aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Barton <dougb@FreeBSD.org>2011-07-16 10:49:33 +0000
committerDoug Barton <dougb@FreeBSD.org>2011-07-16 10:49:33 +0000
commit473038528ab5bd55332138ebf791ab91a25f747b (patch)
treecb160fa2acd93f24b5f5b9082cd3afc68396d51a
parent46da9ebeb3b1241e2e7f0182d76c336966e91d20 (diff)
downloadsrc-473038528ab5bd55332138ebf791ab91a25f747b.tar.gz
src-473038528ab5bd55332138ebf791ab91a25f747b.zip
Vendor import of BIND 9.8.0-P4vendor/bind9/9.8.0-P4
Notes
Notes: svn path=/vendor/bind9/dist/; revision=224090 svn path=/vendor/bind9/9.8.0-P4/; revision=224091; tag=vendor/bind9/9.8.0-P4
-rw-r--r--CHANGES1288
-rw-r--r--COPYRIGHT2
-rw-r--r--FAQ.xml2
-rw-r--r--HISTORY313
-rw-r--r--KNOWN-DEFECTS15
-rw-r--r--Makefile.in11
-rw-r--r--NSEC3-NOTES128
-rw-r--r--README448
-rw-r--r--README.idnkit112
-rw-r--r--README.pkcs1161
-rw-r--r--acconfig.h4
-rw-r--r--bin/Makefile.in7
-rw-r--r--bin/check/Makefile.in20
-rw-r--r--bin/check/check-tool.c5
-rw-r--r--bin/check/check-tool.h2
-rw-r--r--bin/check/named-checkconf.835
-rw-r--r--bin/check/named-checkconf.c43
-rw-r--r--bin/check/named-checkconf.docbook36
-rw-r--r--bin/check/named-checkconf.html41
-rw-r--r--bin/check/named-checkzone.819
-rw-r--r--bin/check/named-checkzone.c47
-rw-r--r--bin/check/named-checkzone.docbook22
-rw-r--r--bin/check/named-checkzone.html26
-rw-r--r--bin/confgen/Makefile.in101
-rw-r--r--bin/confgen/ddns-confgen.8143
-rw-r--r--bin/confgen/ddns-confgen.c257
-rw-r--r--bin/confgen/ddns-confgen.docbook218
-rw-r--r--bin/confgen/ddns-confgen.html141
-rw-r--r--bin/confgen/include/confgen/os.h39
-rw-r--r--bin/confgen/keygen.c218
-rw-r--r--bin/confgen/keygen.h41
-rw-r--r--bin/confgen/rndc-confgen.8 (renamed from bin/rndc/rndc-confgen.8)6
-rw-r--r--bin/confgen/rndc-confgen.c (renamed from bin/rndc/rndc-confgen.c)126
-rw-r--r--bin/confgen/rndc-confgen.docbook (renamed from bin/rndc/rndc-confgen.docbook)5
-rw-r--r--bin/confgen/rndc-confgen.html (renamed from bin/rndc/rndc-confgen.html)14
-rw-r--r--bin/confgen/unix/Makefile.in (renamed from bin/rndc/unix/Makefile.in)5
-rw-r--r--bin/confgen/unix/os.c (renamed from bin/rndc/unix/os.c)33
-rw-r--r--bin/confgen/util.c56
-rw-r--r--bin/confgen/util.h52
-rw-r--r--bin/dig/Makefile.in26
-rw-r--r--bin/dig/dig.111
-rw-r--r--bin/dig/dig.c176
-rw-r--r--bin/dig/dig.docbook16
-rw-r--r--bin/dig/dig.html28
-rw-r--r--bin/dig/dighost.c223
-rw-r--r--bin/dig/host.12
-rw-r--r--bin/dig/host.c5
-rw-r--r--bin/dig/host.docbook2
-rw-r--r--bin/dig/host.html2
-rw-r--r--bin/dig/include/dig/dig.h14
-rw-r--r--bin/dig/nslookup.12
-rw-r--r--bin/dig/nslookup.c20
-rw-r--r--bin/dig/nslookup.docbook2
-rw-r--r--bin/dig/nslookup.html2
-rw-r--r--bin/dnssec/Makefile.in41
-rw-r--r--bin/dnssec/dnssec-dsfromkey.855
-rw-r--r--bin/dnssec/dnssec-dsfromkey.c314
-rw-r--r--bin/dnssec/dnssec-dsfromkey.docbook78
-rw-r--r--bin/dnssec/dnssec-dsfromkey.html67
-rw-r--r--bin/dnssec/dnssec-keyfromlabel.886
-rw-r--r--bin/dnssec/dnssec-keyfromlabel.c336
-rw-r--r--bin/dnssec/dnssec-keyfromlabel.docbook195
-rw-r--r--bin/dnssec/dnssec-keyfromlabel.html136
-rw-r--r--bin/dnssec/dnssec-keygen.8114
-rw-r--r--bin/dnssec/dnssec-keygen.c768
-rw-r--r--bin/dnssec/dnssec-keygen.docbook264
-rw-r--r--bin/dnssec/dnssec-keygen.html196
-rw-r--r--bin/dnssec/dnssec-revoke.883
-rw-r--r--bin/dnssec/dnssec-revoke.c269
-rw-r--r--bin/dnssec/dnssec-revoke.docbook149
-rw-r--r--bin/dnssec/dnssec-revoke.html87
-rw-r--r--bin/dnssec/dnssec-settime.8166
-rw-r--r--bin/dnssec/dnssec-settime.c576
-rw-r--r--bin/dnssec/dnssec-settime.docbook319
-rw-r--r--bin/dnssec/dnssec-settime.html208
-rw-r--r--bin/dnssec/dnssec-signzone.8154
-rw-r--r--bin/dnssec/dnssec-signzone.c1157
-rw-r--r--bin/dnssec/dnssec-signzone.docbook246
-rw-r--r--bin/dnssec/dnssec-signzone.html200
-rw-r--r--bin/dnssec/dnssectool.c223
-rw-r--r--bin/dnssec/dnssectool.h33
-rw-r--r--bin/named/Makefile.in33
-rw-r--r--bin/named/bind.keys.h99
-rw-r--r--bin/named/bind9.xsl2
-rw-r--r--bin/named/bind9.xsl.h4
-rw-r--r--bin/named/builtin.c205
-rw-r--r--bin/named/client.c130
-rw-r--r--bin/named/config.c74
-rw-r--r--bin/named/control.c11
-rw-r--r--bin/named/include/named/client.h17
-rw-r--r--bin/named/include/named/config.h7
-rw-r--r--bin/named/include/named/control.h9
-rw-r--r--bin/named/include/named/globals.h21
-rw-r--r--bin/named/include/named/log.h2
-rw-r--r--bin/named/include/named/lwdclient.h2
-rw-r--r--bin/named/include/named/main.h9
-rw-r--r--bin/named/include/named/notify.h2
-rw-r--r--bin/named/include/named/query.h17
-rw-r--r--bin/named/include/named/server.h53
-rw-r--r--bin/named/include/named/tsigconf.h7
-rw-r--r--bin/named/include/named/types.h6
-rw-r--r--bin/named/include/named/zoneconf.h19
-rw-r--r--bin/named/interfacemgr.c2
-rw-r--r--bin/named/log.c2
-rw-r--r--bin/named/lwdgabn.c6
-rw-r--r--bin/named/lwdgrbn.c6
-rw-r--r--bin/named/lwresd.82
-rw-r--r--bin/named/lwresd.c7
-rw-r--r--bin/named/lwresd.docbook2
-rw-r--r--bin/named/lwresd.html2
-rw-r--r--bin/named/main.c132
-rw-r--r--bin/named/named.811
-rw-r--r--bin/named/named.conf.567
-rw-r--r--bin/named/named.conf.docbook68
-rw-r--r--bin/named/named.conf.html92
-rw-r--r--bin/named/named.docbook17
-rw-r--r--bin/named/named.html26
-rw-r--r--bin/named/query.c2245
-rw-r--r--bin/named/server.c2454
-rw-r--r--bin/named/statschannel.c19
-rw-r--r--bin/named/tkeyconf.c28
-rw-r--r--bin/named/tsigconf.c10
-rw-r--r--bin/named/unix/Makefile.in4
-rw-r--r--bin/named/unix/include/named/os.h8
-rw-r--r--bin/named/unix/os.c186
-rw-r--r--bin/named/update.c1060
-rw-r--r--bin/named/xfrout.c204
-rw-r--r--bin/named/zoneconf.c531
-rw-r--r--bin/nsupdate/Makefile.in19
-rw-r--r--bin/nsupdate/nsupdate.198
-rw-r--r--bin/nsupdate/nsupdate.c279
-rw-r--r--bin/nsupdate/nsupdate.docbook125
-rw-r--r--bin/nsupdate/nsupdate.html113
-rw-r--r--bin/rndc/Makefile.in40
-rw-r--r--bin/rndc/include/rndc/os.h8
-rw-r--r--bin/rndc/rndc.82
-rw-r--r--bin/rndc/rndc.c25
-rw-r--r--bin/rndc/rndc.conf.52
-rw-r--r--bin/rndc/rndc.conf.html2
-rw-r--r--bin/rndc/rndc.html2
-rw-r--r--bin/rndc/util.h10
-rw-r--r--bin/tools/Makefile.in103
-rw-r--r--bin/tools/arpaname.148
-rw-r--r--bin/tools/arpaname.c53
-rw-r--r--bin/tools/arpaname.docbook76
-rw-r--r--bin/tools/arpaname.html52
-rw-r--r--bin/tools/genrandom.869
-rw-r--r--bin/tools/genrandom.c136
-rw-r--r--bin/tools/genrandom.docbook119
-rw-r--r--bin/tools/genrandom.html73
-rw-r--r--bin/tools/isc-hmac-fixup.861
-rw-r--r--bin/tools/isc-hmac-fixup.c136
-rw-r--r--bin/tools/isc-hmac-fixup.docbook109
-rw-r--r--bin/tools/isc-hmac-fixup.html83
-rw-r--r--bin/tools/named-journalprint.860
-rw-r--r--bin/tools/named-journalprint.c86
-rw-r--r--bin/tools/named-journalprint.docbook101
-rw-r--r--bin/tools/named-journalprint.html73
-rw-r--r--bin/tools/nsec3hash.870
-rw-r--r--bin/tools/nsec3hash.c121
-rw-r--r--bin/tools/nsec3hash.docbook125
-rw-r--r--bin/tools/nsec3hash.html78
-rw-r--r--config.guess2
-rw-r--r--config.h.in66
-rw-r--r--configure.in501
-rw-r--r--doc/arm/Bv9ARM-book.xml2041
-rw-r--r--doc/arm/Bv9ARM.ch01.html54
-rw-r--r--doc/arm/Bv9ARM.ch02.html30
-rw-r--r--doc/arm/Bv9ARM.ch03.html174
-rw-r--r--doc/arm/Bv9ARM.ch04.html969
-rw-r--r--doc/arm/Bv9ARM.ch05.html8
-rw-r--r--doc/arm/Bv9ARM.ch06.html1669
-rw-r--r--doc/arm/Bv9ARM.ch07.html29
-rw-r--r--doc/arm/Bv9ARM.ch08.html20
-rw-r--r--doc/arm/Bv9ARM.ch09.html657
-rw-r--r--doc/arm/Bv9ARM.ch10.html28
-rw-r--r--doc/arm/Bv9ARM.html217
-rw-r--r--doc/arm/Bv9ARM.pdf19903
-rw-r--r--doc/arm/Makefile.in2
-rw-r--r--doc/arm/dnssec.xml268
-rw-r--r--doc/arm/libdns.xml530
-rw-r--r--doc/arm/man.arpaname.html91
-rw-r--r--doc/arm/man.ddns-confgen.html180
-rw-r--r--doc/arm/man.dig.html28
-rw-r--r--doc/arm/man.dnssec-dsfromkey.html67
-rw-r--r--doc/arm/man.dnssec-keyfromlabel.html136
-rw-r--r--doc/arm/man.dnssec-keygen.html206
-rw-r--r--doc/arm/man.dnssec-revoke.html126
-rw-r--r--doc/arm/man.dnssec-settime.html247
-rw-r--r--doc/arm/man.dnssec-signzone.html210
-rw-r--r--doc/arm/man.genrandom.html112
-rw-r--r--doc/arm/man.host.html12
-rw-r--r--doc/arm/man.isc-hmac-fixup.html122
-rw-r--r--doc/arm/man.named-checkconf.html41
-rw-r--r--doc/arm/man.named-checkzone.html26
-rw-r--r--doc/arm/man.named-journalprint.html112
-rw-r--r--doc/arm/man.named.html36
-rw-r--r--doc/arm/man.nsec3hash.html113
-rw-r--r--doc/arm/man.nsupdate.html123
-rw-r--r--doc/arm/man.rndc-confgen.html24
-rw-r--r--doc/arm/man.rndc.conf.html14
-rw-r--r--doc/arm/man.rndc.html14
-rw-r--r--doc/arm/managed-keys.xml100
-rw-r--r--doc/arm/pkcs11.xml390
-rw-r--r--doc/misc/Makefile.in2
-rw-r--r--doc/misc/options104
-rw-r--r--lib/bind9/Makefile.in4
-rw-r--r--lib/bind9/api4
-rw-r--r--lib/bind9/check.c549
-rw-r--r--lib/bind9/include/bind9/getaddresses.h2
-rw-r--r--lib/dns/Makefile.in44
-rw-r--r--lib/dns/acl.c2
-rw-r--r--lib/dns/adb.c581
-rw-r--r--lib/dns/api4
-rw-r--r--lib/dns/byaddr.c47
-rw-r--r--lib/dns/cache.c78
-rw-r--r--lib/dns/client.c3019
-rw-r--r--lib/dns/db.c46
-rw-r--r--lib/dns/diff.c19
-rw-r--r--lib/dns/dispatch.c93
-rw-r--r--lib/dns/dlz.c154
-rw-r--r--lib/dns/dns64.c299
-rw-r--r--lib/dns/dnssec.c804
-rw-r--r--lib/dns/ds.c72
-rw-r--r--lib/dns/dst_api.c489
-rw-r--r--lib/dns/dst_internal.h40
-rw-r--r--lib/dns/dst_openssl.h9
-rw-r--r--lib/dns/dst_parse.c193
-rw-r--r--lib/dns/dst_parse.h21
-rw-r--r--lib/dns/ecdb.c810
-rw-r--r--lib/dns/forward.c22
-rw-r--r--lib/dns/gen-unix.h2
-rw-r--r--lib/dns/gen.c6
-rw-r--r--lib/dns/gssapi_link.c91
-rw-r--r--lib/dns/gssapictx.c96
-rw-r--r--lib/dns/hmac_link.c211
-rw-r--r--lib/dns/include/dns/Makefile.in20
-rw-r--r--lib/dns/include/dns/acl.h2
-rw-r--r--lib/dns/include/dns/cache.h39
-rw-r--r--lib/dns/include/dns/client.h621
-rw-r--r--lib/dns/include/dns/compress.h2
-rw-r--r--lib/dns/include/dns/db.h49
-rw-r--r--lib/dns/include/dns/diff.h2
-rw-r--r--lib/dns/include/dns/dispatch.h2
-rw-r--r--lib/dns/include/dns/dlz.h62
-rw-r--r--lib/dns/include/dns/dns64.h175
-rw-r--r--lib/dns/include/dns/dnssec.h137
-rw-r--r--lib/dns/include/dns/ds.h9
-rw-r--r--lib/dns/include/dns/ecdb.h52
-rw-r--r--lib/dns/include/dns/events.h7
-rw-r--r--lib/dns/include/dns/forward.h19
-rw-r--r--lib/dns/include/dns/journal.h2
-rw-r--r--lib/dns/include/dns/keydata.h55
-rw-r--r--lib/dns/include/dns/keytable.h212
-rw-r--r--lib/dns/include/dns/keyvalues.h8
-rw-r--r--lib/dns/include/dns/lib.h18
-rw-r--r--lib/dns/include/dns/log.h3
-rw-r--r--lib/dns/include/dns/lookup.h2
-rw-r--r--lib/dns/include/dns/master.h5
-rw-r--r--lib/dns/include/dns/masterdump.h2
-rw-r--r--lib/dns/include/dns/message.h20
-rw-r--r--lib/dns/include/dns/name.h84
-rw-r--r--lib/dns/include/dns/ncache.h2
-rw-r--r--lib/dns/include/dns/nsec3.h61
-rw-r--r--lib/dns/include/dns/peer.h2
-rw-r--r--lib/dns/include/dns/private.h55
-rw-r--r--lib/dns/include/dns/rbt.h19
-rw-r--r--lib/dns/include/dns/rdata.h55
-rw-r--r--lib/dns/include/dns/rdataset.h2
-rw-r--r--lib/dns/include/dns/request.h11
-rw-r--r--lib/dns/include/dns/resolver.h28
-rw-r--r--lib/dns/include/dns/result.h9
-rw-r--r--lib/dns/include/dns/rpz.h189
-rw-r--r--lib/dns/include/dns/rriterator.h103
-rw-r--r--lib/dns/include/dns/sdb.h2
-rw-r--r--lib/dns/include/dns/sdlz.h130
-rw-r--r--lib/dns/include/dns/secalg.h11
-rw-r--r--lib/dns/include/dns/soa.h26
-rw-r--r--lib/dns/include/dns/ssu.h31
-rw-r--r--lib/dns/include/dns/stats.h2
-rw-r--r--lib/dns/include/dns/tkey.h14
-rw-r--r--lib/dns/include/dns/tsec.h135
-rw-r--r--lib/dns/include/dns/tsig.h32
-rw-r--r--lib/dns/include/dns/types.h18
-rw-r--r--lib/dns/include/dns/validator.h2
-rw-r--r--lib/dns/include/dns/view.h211
-rw-r--r--lib/dns/include/dns/xfrin.h2
-rw-r--r--lib/dns/include/dns/zone.h109
-rw-r--r--lib/dns/include/dst/dst.h241
-rw-r--r--lib/dns/include/dst/gssapi.h13
-rw-r--r--lib/dns/iptable.c2
-rw-r--r--lib/dns/journal.c8
-rw-r--r--lib/dns/keydata.c89
-rw-r--r--lib/dns/keytable.c389
-rw-r--r--lib/dns/lib.c109
-rw-r--r--lib/dns/log.c5
-rw-r--r--lib/dns/master.c113
-rw-r--r--lib/dns/masterdump.c65
-rw-r--r--lib/dns/message.c59
-rw-r--r--lib/dns/name.c77
-rw-r--r--lib/dns/ncache.c57
-rw-r--r--lib/dns/nsec.c2
-rw-r--r--lib/dns/nsec3.c490
-rw-r--r--lib/dns/openssl_link.c231
-rw-r--r--lib/dns/openssldh_link.c45
-rw-r--r--lib/dns/openssldsa_link.c47
-rw-r--r--lib/dns/opensslgost_link.c418
-rw-r--r--lib/dns/opensslrsa_link.c166
-rw-r--r--lib/dns/peer.c6
-rw-r--r--lib/dns/private.c295
-rw-r--r--lib/dns/rbt.c9
-rw-r--r--lib/dns/rbtdb.c826
-rw-r--r--lib/dns/rcode.c27
-rw-r--r--lib/dns/rdata.c143
-rw-r--r--lib/dns/rdata/any_255/tsig_250.c9
-rw-r--r--lib/dns/rdata/ch_3/a_1.c12
-rw-r--r--lib/dns/rdata/generic/afsdb_18.c8
-rw-r--r--lib/dns/rdata/generic/cert_37.c10
-rw-r--r--lib/dns/rdata/generic/cname_5.c9
-rw-r--r--lib/dns/rdata/generic/dlv_32769.c36
-rw-r--r--lib/dns/rdata/generic/dname_39.c8
-rw-r--r--lib/dns/rdata/generic/dnskey_48.c41
-rw-r--r--lib/dns/rdata/generic/ds_43.c32
-rw-r--r--lib/dns/rdata/generic/gpos_27.c9
-rw-r--r--lib/dns/rdata/generic/hinfo_13.c8
-rw-r--r--lib/dns/rdata/generic/hip_55.c506
-rw-r--r--lib/dns/rdata/generic/hip_55.h47
-rw-r--r--lib/dns/rdata/generic/ipseckey_45.c41
-rw-r--r--lib/dns/rdata/generic/isdn_20.c9
-rw-r--r--lib/dns/rdata/generic/key_25.c37
-rw-r--r--lib/dns/rdata/generic/keydata_65533.c377
-rw-r--r--lib/dns/rdata/generic/keydata_65533.h35
-rw-r--r--lib/dns/rdata/generic/loc_29.c7
-rw-r--r--lib/dns/rdata/generic/mb_7.c15
-rw-r--r--lib/dns/rdata/generic/md_3.c15
-rw-r--r--lib/dns/rdata/generic/mf_4.c15
-rw-r--r--lib/dns/rdata/generic/mg_8.c15
-rw-r--r--lib/dns/rdata/generic/minfo_14.c21
-rw-r--r--lib/dns/rdata/generic/mr_9.c15
-rw-r--r--lib/dns/rdata/generic/mx_15.c13
-rw-r--r--lib/dns/rdata/generic/ns_2.c15
-rw-r--r--lib/dns/rdata/generic/nsec3_50.c7
-rw-r--r--lib/dns/rdata/generic/nsec3param_51.c7
-rw-r--r--lib/dns/rdata/generic/nsec_47.c36
-rw-r--r--lib/dns/rdata/generic/null_10.c9
-rw-r--r--lib/dns/rdata/generic/nxt_30.c8
-rw-r--r--lib/dns/rdata/generic/opt_41.c9
-rw-r--r--lib/dns/rdata/generic/proforma.c21
-rw-r--r--lib/dns/rdata/generic/ptr_12.c14
-rw-r--r--lib/dns/rdata/generic/rp_17.c20
-rw-r--r--lib/dns/rdata/generic/rrsig_46.c47
-rw-r--r--lib/dns/rdata/generic/rt_21.c13
-rw-r--r--lib/dns/rdata/generic/sig_24.c8
-rw-r--r--lib/dns/rdata/generic/soa_6.c7
-rw-r--r--lib/dns/rdata/generic/spf_99.c8
-rw-r--r--lib/dns/rdata/generic/sshfp_44.c9
-rw-r--r--lib/dns/rdata/generic/tkey_249.c8
-rw-r--r--lib/dns/rdata/generic/txt_16.c9
-rw-r--r--lib/dns/rdata/generic/unspec_103.c9
-rw-r--r--lib/dns/rdata/generic/x25_19.c9
-rw-r--r--lib/dns/rdata/hs_4/a_1.c9
-rw-r--r--lib/dns/rdata/in_1/a6_38.c9
-rw-r--r--lib/dns/rdata/in_1/a_1.c9
-rw-r--r--lib/dns/rdata/in_1/aaaa_28.c8
-rw-r--r--lib/dns/rdata/in_1/apl_42.c9
-rw-r--r--lib/dns/rdata/in_1/dhcid_49.c11
-rw-r--r--lib/dns/rdata/in_1/kx_36.c13
-rw-r--r--lib/dns/rdata/in_1/naptr_35.c136
-rw-r--r--lib/dns/rdata/in_1/nsap-ptr_23.c15
-rw-r--r--lib/dns/rdata/in_1/nsap_22.c9
-rw-r--r--lib/dns/rdata/in_1/px_26.c13
-rw-r--r--lib/dns/rdata/in_1/srv_33.c13
-rw-r--r--lib/dns/rdata/in_1/wks_11.c7
-rw-r--r--lib/dns/rdatalist.c2
-rw-r--r--lib/dns/rdataset.c2
-rw-r--r--lib/dns/rdataslab.c28
-rw-r--r--lib/dns/request.c10
-rw-r--r--lib/dns/resolver.c630
-rw-r--r--lib/dns/result.c7
-rw-r--r--lib/dns/rootns.c2
-rw-r--r--lib/dns/rpz.c1168
-rw-r--r--lib/dns/rriterator.c202
-rw-r--r--lib/dns/sdb.c8
-rw-r--r--lib/dns/sdlz.c413
-rw-r--r--lib/dns/soa.c40
-rw-r--r--lib/dns/spnego.c9
-rw-r--r--lib/dns/ssu.c68
-rw-r--r--lib/dns/ssu_external.c265
-rw-r--r--lib/dns/stats.c2
-rw-r--r--lib/dns/time.c2
-rw-r--r--lib/dns/tkey.c53
-rw-r--r--lib/dns/tsec.c160
-rw-r--r--lib/dns/tsig.c367
-rw-r--r--lib/dns/validator.c428
-rw-r--r--lib/dns/view.c421
-rw-r--r--lib/dns/xfrin.c43
-rw-r--r--lib/dns/zone.c3909
-rw-r--r--lib/export/Makefile.in27
-rw-r--r--lib/export/dns/Makefile.in179
-rw-r--r--lib/export/dns/include/Makefile.in23
-rw-r--r--lib/export/dns/include/dns/Makefile.in56
-rw-r--r--lib/export/dns/include/dst/Makefile.in36
-rw-r--r--lib/export/irs/Makefile.in86
-rw-r--r--lib/export/irs/include/Makefile.in24
-rw-r--r--lib/export/irs/include/irs/Makefile.in46
-rw-r--r--lib/export/isc/Makefile.in139
-rw-r--r--lib/export/isc/include/Makefile.in24
-rw-r--r--lib/export/isc/include/isc/Makefile.in66
-rw-r--r--lib/export/isc/include/isc/bind9.h30
-rw-r--r--lib/export/isc/nls/Makefile.in35
-rw-r--r--lib/export/isc/nothreads/Makefile.in40
-rw-r--r--lib/export/isc/nothreads/include/Makefile.in24
-rw-r--r--lib/export/isc/nothreads/include/isc/Makefile.in36
-rw-r--r--lib/export/isc/pthreads/Makefile.in38
-rw-r--r--lib/export/isc/pthreads/include/Makefile.in24
-rw-r--r--lib/export/isc/pthreads/include/isc/Makefile.in36
-rw-r--r--lib/export/isc/unix/Makefile.in57
-rw-r--r--lib/export/isc/unix/include/Makefile.in24
-rw-r--r--lib/export/isc/unix/include/isc/Makefile.in37
-rw-r--r--lib/export/isccfg/Makefile.in83
-rw-r--r--lib/export/isccfg/include/Makefile.in24
-rw-r--r--lib/export/isccfg/include/isccfg/Makefile.in42
-rw-r--r--lib/export/samples/Makefile-postinstall.in78
-rw-r--r--lib/export/samples/Makefile.in98
-rw-r--r--lib/export/samples/nsprobe.c1220
-rw-r--r--lib/export/samples/sample-async.c402
-rw-r--r--lib/export/samples/sample-gai.c77
-rw-r--r--lib/export/samples/sample-request.c263
-rw-r--r--lib/export/samples/sample-update.c755
-rw-r--r--lib/export/samples/sample.c378
-rw-r--r--lib/irs/Makefile.in80
-rw-r--r--lib/irs/api3
-rw-r--r--lib/irs/context.c396
-rw-r--r--lib/irs/dnsconf.c269
-rw-r--r--lib/irs/gai_strerror.c93
-rw-r--r--lib/irs/getaddrinfo.c1295
-rw-r--r--lib/irs/getnameinfo.c410
-rw-r--r--lib/irs/include/Makefile.in24
-rw-r--r--lib/irs/include/irs/Makefile.in44
-rw-r--r--lib/irs/include/irs/context.h159
-rw-r--r--lib/irs/include/irs/dnsconf.h94
-rw-r--r--lib/irs/include/irs/netdb.h.in167
-rw-r--r--lib/irs/include/irs/platform.h.in45
-rw-r--r--lib/irs/include/irs/resconf.h113
-rw-r--r--lib/irs/include/irs/types.h31
-rw-r--r--lib/irs/include/irs/version.h27
-rw-r--r--lib/irs/resconf.c636
-rw-r--r--lib/irs/version.c27
-rw-r--r--lib/isc/Makefile.in38
-rw-r--r--lib/isc/alpha/include/isc/atomic.h2
-rw-r--r--lib/isc/api6
-rw-r--r--lib/isc/app_api.c136
-rw-r--r--lib/isc/assertions.c64
-rw-r--r--lib/isc/backtrace-emptytbl.c34
-rw-r--r--lib/isc/backtrace.c285
-rw-r--r--lib/isc/base32.c2
-rw-r--r--lib/isc/base64.c2
-rw-r--r--lib/isc/entropy.c2
-rw-r--r--lib/isc/hash.c20
-rw-r--r--lib/isc/heap.c2
-rw-r--r--lib/isc/hmacmd5.c35
-rw-r--r--lib/isc/hmacsha.c269
-rw-r--r--lib/isc/httpd.c2
-rw-r--r--lib/isc/ia64/include/isc/atomic.h2
-rw-r--r--lib/isc/include/isc/Makefile.in10
-rw-r--r--lib/isc/include/isc/app.h173
-rw-r--r--lib/isc/include/isc/assertions.h8
-rw-r--r--lib/isc/include/isc/backtrace.h131
-rw-r--r--lib/isc/include/isc/bind9.h30
-rw-r--r--lib/isc/include/isc/buffer.h4
-rw-r--r--lib/isc/include/isc/entropy.h2
-rw-r--r--lib/isc/include/isc/error.h9
-rw-r--r--lib/isc/include/isc/file.h31
-rw-r--r--lib/isc/include/isc/fsaccess.h2
-rw-r--r--lib/isc/include/isc/hash.h2
-rw-r--r--lib/isc/include/isc/heap.h2
-rw-r--r--lib/isc/include/isc/hmacmd5.h13
-rw-r--r--lib/isc/include/isc/hmacsha.h17
-rw-r--r--lib/isc/include/isc/lib.h13
-rw-r--r--lib/isc/include/isc/log.h2
-rw-r--r--lib/isc/include/isc/md5.h14
-rw-r--r--lib/isc/include/isc/mem.h161
-rw-r--r--lib/isc/include/isc/msgs.h6
-rw-r--r--lib/isc/include/isc/namespace.h164
-rw-r--r--lib/isc/include/isc/netaddr.h2
-rw-r--r--lib/isc/include/isc/netscope.h2
-rw-r--r--lib/isc/include/isc/platform.h.in24
-rw-r--r--lib/isc/include/isc/portset.h2
-rw-r--r--lib/isc/include/isc/radix.h2
-rw-r--r--lib/isc/include/isc/random.h2
-rw-r--r--lib/isc/include/isc/ratelimiter.h2
-rw-r--r--lib/isc/include/isc/refcount.h12
-rw-r--r--lib/isc/include/isc/result.h5
-rw-r--r--lib/isc/include/isc/resultclass.h5
-rw-r--r--lib/isc/include/isc/serial.h2
-rw-r--r--lib/isc/include/isc/sha1.h13
-rw-r--r--lib/isc/include/isc/sha2.h17
-rw-r--r--lib/isc/include/isc/sockaddr.h2
-rw-r--r--lib/isc/include/isc/socket.h149
-rw-r--r--lib/isc/include/isc/stats.h2
-rw-r--r--lib/isc/include/isc/symtab.h2
-rw-r--r--lib/isc/include/isc/task.h108
-rw-r--r--lib/isc/include/isc/timer.h93
-rw-r--r--lib/isc/include/isc/types.h9
-rw-r--r--lib/isc/include/isc/util.h2
-rw-r--r--lib/isc/inet_aton.c4
-rw-r--r--lib/isc/inet_ntop.c2
-rw-r--r--lib/isc/iterated_hash.c2
-rw-r--r--lib/isc/lib.c34
-rw-r--r--lib/isc/log.c2
-rw-r--r--lib/isc/md5.c30
-rw-r--r--lib/isc/mem.c573
-rw-r--r--lib/isc/mem_api.c303
-rw-r--r--lib/isc/netaddr.c24
-rw-r--r--lib/isc/nls/Makefile.in4
-rw-r--r--lib/isc/nothreads/Makefile.in8
-rw-r--r--lib/isc/powerpc/include/isc/atomic.h2
-rw-r--r--lib/isc/print.c2
-rw-r--r--lib/isc/pthreads/Makefile.in4
-rw-r--r--lib/isc/pthreads/mutex.c2
-rw-r--r--lib/isc/radix.c2
-rw-r--r--lib/isc/random.c4
-rw-r--r--lib/isc/rwlock.c2
-rw-r--r--lib/isc/sha1.c41
-rw-r--r--lib/isc/sha2.c429
-rw-r--r--lib/isc/sockaddr.c8
-rw-r--r--lib/isc/socket_api.c216
-rw-r--r--lib/isc/stats.c2
-rw-r--r--lib/isc/task.c517
-rw-r--r--lib/isc/task_api.c216
-rw-r--r--lib/isc/task_p.h8
-rw-r--r--lib/isc/timer.c346
-rw-r--r--lib/isc/timer_api.c144
-rw-r--r--lib/isc/timer_p.h8
-rw-r--r--lib/isc/unix/Makefile.in4
-rw-r--r--lib/isc/unix/app.c540
-rw-r--r--lib/isc/unix/dir.c4
-rw-r--r--lib/isc/unix/entropy.c4
-rw-r--r--lib/isc/unix/file.c90
-rw-r--r--lib/isc/unix/ifiter_getifaddrs.c2
-rw-r--r--lib/isc/unix/ifiter_ioctl.c2
-rw-r--r--lib/isc/unix/include/isc/net.h4
-rw-r--r--lib/isc/unix/include/isc/offset.h4
-rw-r--r--lib/isc/unix/include/isc/strerror.h4
-rw-r--r--lib/isc/unix/include/isc/time.h2
-rw-r--r--lib/isc/unix/interfaceiter.c4
-rw-r--r--lib/isc/unix/resource.c2
-rw-r--r--lib/isc/unix/socket.c952
-rw-r--r--lib/isc/unix/socket_p.h9
-rw-r--r--lib/isc/unix/strerror.c2
-rw-r--r--lib/isccc/Makefile.in6
-rw-r--r--lib/isccc/api4
-rw-r--r--lib/isccfg/Makefile.in8
-rw-r--r--lib/isccfg/aclconf.c25
-rw-r--r--lib/isccfg/api6
-rw-r--r--lib/isccfg/dnsconf.c69
-rw-r--r--lib/isccfg/include/isccfg/aclconf.h14
-rw-r--r--lib/isccfg/include/isccfg/cfg.h38
-rw-r--r--lib/isccfg/include/isccfg/dnsconf.h35
-rw-r--r--lib/isccfg/include/isccfg/grammar.h24
-rw-r--r--lib/isccfg/include/isccfg/log.h2
-rw-r--r--lib/isccfg/include/isccfg/namedconf.h16
-rw-r--r--lib/isccfg/namedconf.c588
-rw-r--r--lib/isccfg/parser.c92
-rw-r--r--lib/lwres/api4
-rw-r--r--lib/lwres/context.c2
-rw-r--r--lib/lwres/context_p.h2
-rw-r--r--lib/lwres/getaddrinfo.c4
-rw-r--r--lib/lwres/getipnode.c2
-rw-r--r--lib/lwres/include/lwres/context.h2
-rw-r--r--lib/lwres/include/lwres/netdb.h.in2
-rw-r--r--lib/lwres/lwconfig.c2
-rw-r--r--lib/lwres/man/lwres.32
-rw-r--r--lib/lwres/man/lwres.html14
-rw-r--r--lib/lwres/man/lwres_buffer.32
-rw-r--r--lib/lwres/man/lwres_buffer.html6
-rw-r--r--lib/lwres/man/lwres_config.32
-rw-r--r--lib/lwres/man/lwres_config.html12
-rw-r--r--lib/lwres/man/lwres_context.32
-rw-r--r--lib/lwres/man/lwres_context.html10
-rw-r--r--lib/lwres/man/lwres_gabn.32
-rw-r--r--lib/lwres/man/lwres_gabn.html10
-rw-r--r--lib/lwres/man/lwres_gai_strerror.32
-rw-r--r--lib/lwres/man/lwres_gai_strerror.html8
-rw-r--r--lib/lwres/man/lwres_getaddrinfo.32
-rw-r--r--lib/lwres/man/lwres_getaddrinfo.html10
-rw-r--r--lib/lwres/man/lwres_gethostent.32
-rw-r--r--lib/lwres/man/lwres_gethostent.html12
-rw-r--r--lib/lwres/man/lwres_getipnode.32
-rw-r--r--lib/lwres/man/lwres_getipnode.html10
-rw-r--r--lib/lwres/man/lwres_getnameinfo.32
-rw-r--r--lib/lwres/man/lwres_getnameinfo.html12
-rw-r--r--lib/lwres/man/lwres_getrrsetbyname.32
-rw-r--r--lib/lwres/man/lwres_getrrsetbyname.html10
-rw-r--r--lib/lwres/man/lwres_gnba.32
-rw-r--r--lib/lwres/man/lwres_gnba.html10
-rw-r--r--lib/lwres/man/lwres_hstrerror.32
-rw-r--r--lib/lwres/man/lwres_hstrerror.html10
-rw-r--r--lib/lwres/man/lwres_inetntop.32
-rw-r--r--lib/lwres/man/lwres_inetntop.html10
-rw-r--r--lib/lwres/man/lwres_noop.32
-rw-r--r--lib/lwres/man/lwres_noop.html10
-rw-r--r--lib/lwres/man/lwres_packet.32
-rw-r--r--lib/lwres/man/lwres_packet.html8
-rw-r--r--lib/lwres/man/lwres_resutil.32
-rw-r--r--lib/lwres/man/lwres_resutil.html10
-rw-r--r--lib/lwres/print_p.h2
-rw-r--r--make/rules.in91
-rw-r--r--version10
609 files changed, 75304 insertions, 17302 deletions
diff --git a/CHANGES b/CHANGES
index 4a7cadadbf37..80ac38a8b27e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,17 +1,28 @@
- --- 9.6-ESV-R4-P3 released ---
+ --- 9.8.0-P4 released ---
3124. [bug] Use an rdataset attribute flag to indicate
negative-cache records rather than using rrtype 0;
this will prevent problems when that rrtype is
used in actual DNS packets. [RT #24777]
- --- 9.6-ESV-R4-P2 released (withdrawn) ---
+ --- 9.8.0-P3 released (withdrawn) ---
+
+3126. [security] Using DNAME record to generate replacements caused
+ RPZ to exit with a assertion failure. [RT #23766]
+
+3125. [security] Using wildcard CNAME records as a replacement with
+ RPZ caused named to exit with a assertion failure.
+ [RT #24715]
3123. [security] Change #2912 exposed a latent flaw in
dns_rdataset_totext() that could cause named to
crash with an assertion failure. [RT #24777]
- --- 9.6-ESV-R4-P1 released ---
+3115. [bug] Named could fail to return requested data when
+ following a CNAME that points into the same zone.
+ [RT #2445]
+
+ --- 9.8.0-P2 released ---
3121. [security] An authoritative name server sending a negative
response containing a very large RRset could
@@ -22,22 +33,114 @@
that validated insecure without using DLV and had
DS records in the parent zone. [RT #24631]
- --- 9.6-ESV-R4 released ---
+ --- 9.8.0-P1 released ---
+
+3100. [security] Certain response policy zone configurations could
+ trigger an INSIST when receiving a query of type
+ RRSIG. [RT #24280]
+
+ --- 9.8.0 released ---
+
+3025. [bug] Fixed a possible deadlock due to zone resigning.
+ [RT #22964]
+
+3024. [func] RTT Banding removed due to minor security increase
+ but major impact on resolver latency. [RT #23310]
+
+3023. [bug] Named could be left in an inconsistent state when
+ receiving multiple AXFR response messages that were
+ not all TSIG-signed. [RT #23254]
+
+3022. [bug] Fixed rpz SERVFAILs after failed zone transfers
+ [RT #23246]
+
+3021. [bug] Change #3010 was incomplete. [RT #22296]
+
+3020. [bug] auto-dnssec failed to correctly update the zone when
+ changing the DNSKEY RRset. [RT #23232]
+
+3019. [test] Test: check apex NSEC3 records after adding DNSKEY
+ record via UPDATE. [RT #23229]
+
+ --- 9.8.0rc1 released ---
+
+3018. [bug] Named failed to check for the "none;" acl when deciding
+ if a zone may need to be re-signed. [RT #23120]
+
+3017. [doc] dnssec-keyfromlabel -I was not properly documented.
+ [RT #22887]
+
+3016. [bug] rndc usage missing '-b'. [RT #22937]
+
+3015. [port] win32: fix IN6_IS_ADDR_LINKLOCAL and
+ IN6_IS_ADDR_SITELOCAL macros. [RT #22724]
- --- 9.6.3 released ---
+3013. [bug] The DNS64 ttl was not always being set as expected.
+ [RT #23034]
+
+3012. [bug] Remove DNSKEY TTL change pairs before generating
+ signing records for any remaining DNSKEY changes.
+ [RT #22590]
+
+3011. [func] Allow setting this in named.conf using the new
+ 'resolver-query-timeout' option, which specifies a max
+ time in seconds. 0 means 'default' and anything longer
+ than 30 will be silently set to 30. [RT #22852]
+
+3010. [bug] Fixed a bug where "rndc reconfig" stopped the timer
+ for refreshing managed-keys. [RT #22296]
3009. [bug] clients-per-query code didn't work as expected with
particular query patterns. [RT #22972]
- --- 9.6.3rc1 released ---
+ --- 9.8.0b1 released ---
+
+3008. [func] Response policy zones (RPZ) support. [RT #21726]
3007. [bug] Named failed to preserve the case of domain names in
rdata which is not compressible when writing master
files. [RT #22863]
+3006. [func] Allow dynamically generated TSIG keys to be preserved
+ across restarts of named. Initially this is for
+ TSIG keys generated using GSSAPI. [RT #22639]
+
+3005. [port] Solaris: Work around the lack of
+ gsskrb5_register_acceptor_identity() by setting
+ the KRB5_KTNAME environment variable to the
+ contents of tkey-gssapi-keytab. Also fixed
+ test errors on MacOSX. [RT #22853]
+
+3004. [func] DNS64 reverse support. [RT #22769]
+
+3003. [experimental] Added update-policy match type "external",
+ enabling named to defer the decision of whether to
+ allow a dynamic update to an external daemon.
+ (Contributed by Andrew Tridgell.) [RT #22758]
+
3002. [bug] isc_mutex_init_errcheck() failed to destroy attr.
[RT #22766]
+3001. [func] Added a default trust anchor for the root zone, which
+ can be switched on by setting "dnssec-validation auto;"
+ in the named.conf options. [RT #21727]
+
+3000. [bug] More TKEY/GSS fixes:
+ - nsupdate can now get the default realm from
+ the user's Kerberos principal
+ - corrected gsstest compilation flags
+ - improved documentation
+ - fixed some NULL dereferences
+ [RT #22795]
+
+2999. [func] Add GOST support (RFC 5933). [RT #20639]
+
+2998. [func] Add isc_task_beginexclusive and isc_task_endexclusive
+ to the task api. [RT #22776]
+
+2997. [func] named -V now reports the OpenSSL and libxml2 verions
+ it was compiled against. [RT #22687]
+
2996. [security] Temporarily disable SO_ACCEPTFILTER support.
[RT #22589]
@@ -48,13 +151,52 @@
do not use threads on earlier versions. Also kill
the unproven-pthreads, mit-pthreads, and ptl2 support.
+2993. [func] Dynamically grow adb hash tables. [RT #21186]
+
+2992. [contrib] contrib/check-secure-delegation.pl: A simple tool
+ for looking at a secure delegation. [RT #22059]
+
+2991. [contrib] contrib/zone-edit.sh: A simple zone editing tool for
+ dynamic zones. [RT #22365]
+
+2990. [bug] 'dnssec-settime -S' no longer tests prepublication
+ interval validity when the interval is set to 0.
+ [RT #22761]
+
+2989. [func] Added support for writable DLZ zones. (Contributed
+ by Andrew Tridgell of the Samba project.) [RT #22629]
+
+2988. [experimental] Added a "dlopen" DLZ driver, allowing the creation
+ of external DLZ drivers that can be loaded as
+ shared objects at runtime rather than linked with
+ named. Currently this is switched on via a
+ compile-time option, "configure --with-dlz-dlopen".
+ Note: the syntax for configuring DLZ zones
+ is likely to be refined in future releases.
+ (Contributed by Andrew Tridgell of the Samba
+ project.) [RT #22629]
+
+2987. [func] Improve ease of configuring TKEY/GSS updates by
+ adding a "tkey-gssapi-keytab" option. If set,
+ updates will be allowed with any key matching
+ a principal in the specified keytab file.
+ "tkey-gssapi-credential" is no longer required
+ and is expected to be deprecated. (Contributed
+ by Andrew Tridgell of the Samba project.)
+ [RT #22629]
+
+2986. [func] Add new zone type "static-stub". It's like a stub
+ zone, but the nameserver names and/or their IP
+ addresses are statically configured. [RT #21474]
+
+2985. [bug] Add a regression test for change #2896. [RT #21324]
+
2984. [bug] Don't run MX checks when the target of the MX record
is ".". [RT #22645]
-2817. [cleanup] Removed unnecessary isc_task_endexclusive() calls.
- [RT #20768]
+2983. [bug] Include "loadkeys" in rndc help output. [RT #22493]
- --- 9.6.3b1 released ---
+ --- 9.8.0a1 released ---
2982. [bug] Reference count dst keys. dst_key_attach() can be used
increment the reference count.
@@ -63,34 +205,103 @@
always call dst_key_free() rather than setting it
to NULL on success. [RT #22672]
+2981. [func] Partial DNS64 support (AAAA synthesis). [RT #21991]
+
+2980. [bug] named didn't properly handle UPDATES that changed the
+ TTL of the NSEC3PARAM RRset. [RT #22363]
+
2979. [bug] named could deadlock during shutdown if two
"rndc stop" commands were issued at the same
time. [RT #22108]
2978. [port] hpux: look for <devpoll.h> [RT #21919]
+2977. [bug] 'nsupdate -l' report if the session key is missing.
+ [RT #21670]
+
2976. [bug] named could die on exit after negotiating a GSS-TSIG
key. [RT #22573]
-2975. [bug] rbtdb.c:cleanup_dead_nodes_callback() aquired the
+2975. [bug] rbtdb.c:cleanup_dead_nodes_callback() acquired the
wrong lock which could lead to server deadlock.
[RT #22614]
+2974. [bug] Some valid UPDATE requests could fail due to a
+ consistency check examining the existing version
+ of the zone rather than the new version resulting
+ from the UPDATE. [RT #22413]
+
+2973. [bug] bind.keys.h was being removed by the "make clean"
+ at the end of configure resulting in build failures
+ where there is very old version of perl installed.
+ Move it to "make maintainer-clean". [RT #22230]
+
+2972. [bug] win32: address windows socket errors. [RT #21906]
+
+2971. [bug] Fixed a bug that caused journal files not to be
+ compacted on Windows systems as a result of
+ non-POSIX-compliant rename() semantics. [RT #22434]
+
+2970. [security] Adding a NO DATA negative cache entry failed to clear
+ any matching RRSIG records. A subsequent lookup of
+ of NO DATA cache entry could trigger a INSIST when the
+ unexpected RRSIG was also returned with the NO DATA
+ cache entry.
+
+ CVE-2010-3613, VU#706148. [RT #22288]
+
+2969. [security] Fix acl type processing so that allow-query works
+ in options and view statements. Also add a new
+ set of tests to verify proper functioning.
+
+ CVE-2010-3615, VU#510208. [RT #22418]
+
+2968. [security] Named could fail to prove a data set was insecure
+ before marking it as insecure. One set of conditions
+ that can trigger this occurs naturally when rolling
+ DNSKEY algorithms.
+
+ CVE-2010-3614, VU#837744. [RT #22309]
+
+2967. [bug] 'host -D' now turns on debugging messages earlier.
+ [RT #22361]
+
+2966. [bug] isc_print_vsnprintf() failed to check if there was
+ space available in the buffer when adding a left
+ justified character with a non zero width,
+ (e.g. "%-1c"). [RT #22270]
+
2965. [func] Test HMAC functions using test data from RFC 2104 and
RFC 4634. [RT #21702]
+2964. [placeholder]
+
+2963. [security] The allow-query acl was being applied instead of the
+ allow-query-cache acl to cache lookups. [RT #22114]
+
+2962. [port] win32: add more dependencies to BINDBuild.dsw.
+ [RT #22062]
+
+2961. [bug] Be still more selective about the non-authoritative
+ answers we apply change 2748 to. [RT #22074]
+
2960. [func] Check that named accepts non-authoritative answers.
[RT #21594]
2959. [func] Check that named starts with a missing masterfile.
[RT #22076]
+2958. [bug] named failed to start with a missing master file.
+ [RT #22076]
+
2957. [bug] entropy_get() and entropy_getpseudo() failed to match
the API for RAND_bytes() and RAND_pseudo_bytes()
respectively. [RT #21962]
2956. [port] Enable atomic operations on the PowerPC64. [RT #21899]
+2955. [func] Provide more detail in the recursing log. [RT #22043]
+
2954. [bug] contrib: dlz_mysql_driver.c bad error handling on
build_sqldbinstance failure. [RT #21623]
@@ -98,10 +309,26 @@
exact match" message when returning a wildcard
no data response. [RT #21744]
+2952. [port] win32: named-checkzone and named-checkconf failed
+ to initialise winsock. [RT #21932]
+
+2951. [bug] named failed to generate a correct signed response
+ in a optout, delegation only zone with no secure
+ delegations. [RT #22007]
+
2950. [bug] named failed to perform a SOA up to date check when
falling back to TCP on UDP timeouts when
ixfr-from-differences was set. [RT #21595]
+2949. [bug] dns_view_setnewzones() contained a memory leak if
+ it was called multiple times. [RT #21942]
+
+2948. [port] MacOS: provide a mechanism to configure the test
+ interfaces at reboot. See bin/tests/system/README
+ for details.
+
+2947. [placeholder]
+
2946. [doc] Document the default values for the minimum and maximum
zone refresh and retry values in the ARM. [RT #21886]
@@ -110,12 +337,59 @@
2944. [maint] Remove ORCHID prefix from built in empty zones.
[RT #21772]
+2943. [func] Add support to load new keys into managed zones
+ without signing immediately with "rndc loadkeys".
+ Add support to link keys with "dnssec-keygen -S"
+ and "dnssec-settime -S". [RT #21351]
+
2942. [contrib] zone2sqlite failed to setup the entropy sources.
[RT #21610]
2941. [bug] sdb and sdlz (dlz's zone database) failed to support
DNAME at the zone apex. [RT #21610]
+2940. [port] Remove connection aborted error message on
+ Windows. [RT #21549]
+
+2939. [func] Check that named successfully skips NSEC3 records
+ that fail to match the NSEC3PARAM record currently
+ in use. [RT# 21868]
+
+2938. [bug] When generating signed responses, from a signed zone
+ that uses NSEC3, named would use a uninitialised
+ pointer if it needed to skip a NSEC3 record because
+ it didn't match the selected NSEC3PARAM record for
+ zone. [RT# 21868]
+
+2937. [bug] Worked around an apparent race condition in over
+ memory conditions. Without this fix a DNS cache DB or
+ ADB could incorrectly stay in an over memory state,
+ effectively refusing further caching, which
+ subsequently made a BIND 9 caching server unworkable.
+ This fix prevents this problem from happening by
+ polling the state of the memory context, rather than
+ making a copy of the state, which appeared to cause
+ a race. This is a "workaround" in that it doesn't
+ solve the possible race per se, but several experiments
+ proved this change solves the symptom. Also, the
+ polling overhead hasn't been reported to be an issue.
+ This bug should only affect a caching server that
+ specifies a finite max-cache-size. It's also quite
+ likely that the bug happens only when enabling threads,
+ but it's not confirmed yet. [RT #21818]
+
+2936. [func] Improved configuration syntax and multiple-view
+ support for addzone/delzone feature (see change
+ #2930). Removed "new-zone-file" option, replaced
+ with "allow-new-zones (yes|no)". The new-zone-file
+ for each view is now created automatically, with
+ a filename generated from a hash of the view name.
+ It is no longer necessary to "include" the
+ new-zone-file in named.conf; this happens
+ automatically. Zones that were not added via
+ "rndc addzone" can no longer be removed with
+ "rndc delzone". [RT #19447]
+
2935. [bug] nsupdate: improve 'file not found' error message.
[RT #21871]
@@ -136,6 +410,17 @@
revisit the issue and complete the fix later.
[RT #21710]
+2930. [experimental] New "rndc addzone" and "rndc delzone" commads
+ allow dynamic addition and deletion of zones.
+ To enable this feature, specify a "new-zone-file"
+ option at the view or options level in named.conf.
+ Zone configuration information for the new zones
+ will be written into that file. To make the new
+ zones persist after a restart, "include" the file
+ into named.conf in the appropriate view. (Note:
+ This feature is not yet documented, and its syntax
+ is expected to change.) [RT #19447]
+
2929. [bug] Improved handling of GSS security contexts:
- added LRU expiration for generated TSIGs
- added the ability to use a non-default realm
@@ -145,19 +430,49 @@
smaller)
[RT #19737]
+2928. [bug] Be more selective about the non-authoritative
+ answer we apply change 2748 to. [RT #21594]
+
+2927. [placeholder]
+
+2926. [placeholder]
+h
+2925. [bug] Named failed to accept uncachable negative responses
+ from insecure zones. [RT# 21555]
+
+2924. [func] 'rndc secroots' dump a combined summary of the
+ current managed keys combined with trusted keys.
+ [RT #20904]
+
2923. [bug] 'dig +trace' could drop core after "connection
timeout". [RT #21514]
2922. [contrib] Update zkt to version 1.0.
+2921. [bug] The resolver could attempt to destroy a fetch context
+ too soon. [RT #19878]
+
+2920. [func] Allow 'filter-aaaa-on-v4' to be applied selectively
+ to IPv4 clients. New acl 'filter-aaaa' (default any).
+
+2919. [func] Add autosign-ksk and autosign-zsk virtual time tests.
+ [RT #20840]
+
2918. [maint] Add AAAA address for I.ROOT-SERVERS.NET.
+2917. [func] Virtual time test framework. [RT #20801]
+
2916. [func] Add framework to use IPv6 in tests.
fd92:7065:b8e:ffff::1 ... fd92:7065:b8e:ffff::7
2915. [cleanup] Be smarter about which objects we attempt to compile
based on configure options. [RT #21444]
+2914. [bug] Make the "autosign" system test more portable.
+ [RT #20997]
+
+2913. [func] Add pkcs#11 system tests. [RT #20784]
+
2912. [func] Windows clients don't like UPDATE responses that clear
the zone section. [RT #20986]
@@ -166,9 +481,17 @@
2910. [func] Sanity check Kerberos credentials. [RT #20986]
+2909. [bug] named-checkconf -p could die if "update-policy local;"
+ was specified in named.conf. [RT #21416]
+
2908. [bug] It was possible for re-signing to stop after removing
a DNSKEY. [RT #21384]
+2907. [bug] The export version of libdns had undefined references.
+ [RT #21444]
+
+2906. [bug] Address RFC 5011 implementation issues. [RT #20903]
+
2905. [port] aix: set use_atomic=yes with native compiler.
[RT #21402]
@@ -177,23 +500,55 @@
secure leading to negative proofs failing. This was
a unintended outcome from change 2890. [RT# 21392]
+2903. [bug] managed-keys-directory missing from namedconf.c.
+ [RT #21370]
+
+2902. [func] Add regression test for change 2897. [RT #21040]
+
2901. [port] Use AC_C_FLEXIBLE_ARRAY_MEMBER. [RT #21316]
+2900. [bug] The placeholder negative caching element was not
+ properly constructed triggering a INSIST in
+ dns_ncache_towire(). [RT #21346]
+
2899. [port] win32: Support linking against OpenSSL 1.0.0.
2898. [bug] nslookup leaked memory when -domain=value was
specified. [RT #21301]
+2897. [bug] NSEC3 chains could be left behind when transitioning
+ to insecure. [RT #21040]
+
+2896. [bug] "rndc sign" failed to properly update the zone
+ when adding a DNSKEY for publication only. [RT #21045]
+
+2895. [func] genrandom: add support for the generation of multiple
+ files. [RT #20917]
+
2894. [contrib] DLZ LDAP support now use '$' not '%'. [RT #21294]
+2893. [bug] Improve managed keys support. New named.conf option
+ managed-keys-directory. [RT #20924]
+
+2892. [bug] Handle REVOKED keys better. [RT #20961]
+
2891. [maint] Update empty-zones list to match
draft-ietf-dnsop-default-local-zones-13. [RT# 21099]
+2890. [bug] Handle the introduction of new trusted-keys and
+ DS, DLV RRsets better. [RT #21097]
+
2889. [bug] Elements of the grammar where not properly reported.
[RT #21046]
2888. [bug] Only the first EDNS option was displayed. [RT #21273]
+2887. [bug] Report the keytag times in UTC in the .key file,
+ local time is presented as a comment within the
+ comment. [RT #21223]
+
+2886. [bug] ctime() is not thread safe. [RT #21223]
+
2885. [bug] Improve -fno-strict-aliasing support probing in
configure. [RT #21080]
@@ -209,12 +564,21 @@
2881. [bug] Reduce the amount of time the rbtdb write lock
is held when closing a version. [RT #21198]
+2880. [cleanup] Make the output of dnssec-keygen and dnssec-revoke
+ consistent. [RT #21078]
+
2879. [contrib] DLZ bdbhpt driver fails to close correct cursor.
[RT #21106]
+2878. [func] Incrementally write the master file after performing
+ a AXFR. [RT #21010]
+
2877. [bug] The validator failed to skip obviously mismatching
RRSIGs. [RT #21138]
+2876. [bug] Named could return SERVFAIL for negative responses
+ from unsigned zones. [RT #21131]
+
2875. [bug] dns_time64_fromtext() could accept non digits.
[RT #21033]
@@ -222,8 +586,22 @@
successfully responds to the query using plain DNS.
[RT #20930]
+2873. [bug] Cancelling a dynamic update via the dns/client module
+ could trigger an assertion failure. [RT #21133]
+
+2872. [bug] Modify dns/client.c:dns_client_createx() to only
+ require one of IPv4 or IPv6 rather than both.
+ [RT #21122]
+
+2871. [bug] Type mismatch in mem_api.c between the definition and
+ the header file, causing build failure with
+ --enable-exportlib. [RT #21138]
+
2870. [maint] Add AAAA address for L.ROOT-SERVERS.NET.
+2869. [bug] Fix arguments to dns_keytable_findnextkeynode() call.
+ [RT #20877]
+
2868. [cleanup] Run "make clean" at the end of configure to ensure
any changes made by configure are integrated.
Use --with-make-clean=no to disable. [RT #20994]
@@ -245,6 +623,11 @@
2862. [bug] nsupdate didn't default to the parent zone when
updating DS records. [RT #20896]
+2861. [doc] dnssec-settime man pages didn't correctly document the
+ inactivation time. [RT #21039]
+
+2860. [bug] named-checkconf's usage was out of date. [RT #21039]
+
2859. [bug] When cancelling validation it was possible to leak
memory. [RT #20800]
@@ -257,173 +640,244 @@
2856. [bug] The size of a memory allocation was not always properly
recorded. [RT #20927]
-2853. [bug] add_sigs() could run out of scratch space. [RT #21015]
-
-2851. [doc] nslookup.1, removed <informalexample> from the docbook
- source as it produced bad nroff. [RT #21007]
-
- --- 9.6-ESV-R3 released ---
-
-2972. [bug] win32: address windows socket errors. [RT #21906]
-
-2971. [bug] Fixed a bug that caused journal files not to be
- compacted on Windows systems as a result of
- non-POSIX-compliant rename() semantics. [RT #22434]
-
-2970. [security] Adding a NO DATA negative cache entry failed to clear
- any matching RRSIG records. A subsequent lookup of
- of NO DATA cache entry could trigger a INSIST when the
- unexpected RRSIG was also returned with the NO DATA
- cache entry.
-
- CVE-2010-3613, VU#706148. [RT #22288]
-
-2969. [security] Fix acl type processing so that allow-query works
- in options and view statements. Also add a new
- set of tests to verify proper functioning.
+2855. [func] nsupdate will now preserve the entered case of domain
+ names in update requests it sends. [RT #20928]
- CVE-2010-3615, VU#510208. [RT #22418]
+2854. [func] dig: allow the final soa record in a axfr response to
+ be suppressed, dig +onesoa. [RT #20929]
-2968. [security] Named could fail to prove a data set was insecure
- before marking it as insecure. One set of conditions
- that can trigger this occurs naturally when rolling
- DNSKEY algorithms.
-
- CVE-2010-3614, VU#837744. [RT #22309]
-
-2967. [bug] 'host -D' now turns on debugging messages earlier.
- [RT #22361]
-
-2966. [bug] isc_print_vsnprintf() failed to check if there was
- space available in the buffer when adding a left
- justified character with a non zero width,
- (e.g. "%-1c"). [RT #22270]
-
-2964. [bug] view->queryacl was being overloaded. Seperate the
- usage into view->queryacl, view->cacheacl and
- view->queryonacl. [RT #22114]
-
-2962. [port] win32: add more dependencies to BINDBuild.dsw.
- [RT #22062]
-
-2952. [port] win32: named-checkzone and named-checkconf failed
- to initialise winsock. [RT #21932]
+2853. [bug] add_sigs() could run out of scratch space. [RT #21015]
-2951. [bug] named failed to generate a correct signed response
- in a optout, delegation only zone with no secure
- delegations. [RT #22007]
+2852. [bug] Handle broken DNSSEC trust chains better. [RT #15619]
- --- 9.6-ESV-R2 released ---
+2851. [doc] nslookup.1, removed <informalexample> from the docbook
+ source as it produced bad nroff. [RT #21007]
-2939. [func] Check that named successfully skips NSEC3 records
- that fail to match the NSEC3PARAM record currently
- in use. [RT# 21868]
+2850. [bug] If isc_heap_insert() failed due to memory shortage
+ the heap would have corrupted entries. [RT #20951]
-2937. [bug] Worked around an apparent race condition in over
- memory conditions. Without this fix a DNS cache DB or
- ADB could incorrectly stay in an over memory state,
- effectively refusing further caching, which
- subsequently made a BIND 9 caching server unworkable.
- This fix prevents this problem from happening by
- polling the state of the memory context, rather than
- making a copy of the state, which appeared to cause
- a race. This is a "workaround" in that it doesn't
- solve the possible race per se, but several experiments
- proved this change solves the symptom. Also, the
- polling overhead hasn't been reported to be an issue.
- This bug should only affect a caching server that
- specifies a finite max-cache-size. It's also quite
- likely that the bug happens only when enabling threads,
- but it's not confirmed yet. [RT #21818]
+2849. [bug] Don't treat errors from the xml2 library as fatal.
+ [RT #20945]
-2925. [bug] Named failed to accept uncachable negative responses
- from insecure zones. [RT# 21555]
+2848. [doc] Moved README.dnssec, README.libdns, README.pkcs11 and
+ README.rfc5011 into the ARM. [RT #20899]
-2921. [bug] The resolver could attempt to destroy a fetch context
- too soon. [RT #19878]
+2847. [cleanup] Corrected usage message in dnssec-settime. [RT #20921]
-2900. [bug] The placeholder negative caching element was not
- properly constructed triggering a INSIST in
- dns_ncache_towire(). [RT #21346]
+2846. [bug] EOF on unix domain sockets was not being handled
+ correctly. [RT #20731]
-2890. [bug] Handle the introduction of new trusted-keys and
- DS, DLV RRsets better. [RT #21097]
+2845. [bug] RFC 5011 client could crash on shutdown. [RT #20903]
-2869. [bug] Fix arguments to dns_keytable_findnextkeynode() call.
- [RT #20877]
+2844. [doc] notify-delay default in ARM was wrong. It should have
+ been five (5) seconds.
- --- 9.6-ESV-R1 released ---
+2843. [func] Prevent dnssec-keygen and dnssec-keyfromlabel from
+ creating key files if there is a chance that the new
+ key ID will collide with an existing one after
+ either of the keys has been revoked. (To override
+ this in the case of dnssec-keyfromlabel, use the -y
+ option. dnssec-keygen will simply create a
+ different, non-colliding key, so an override is
+ not necessary.) [RT #20838]
-2876. [bug] Named could return SERVFAIL for negative responses
- from unsigned zones. [RT #21131]
+2842. [func] Added "smartsign" and improved "autosign" and
+ "dnssec" regression tests. [RT #20865]
- --- 9.6-ESV released ---
+2841. [bug] Change 2836 was not complete. [RT #20883]
-2852. [bug] Handle broken DNSSEC trust chains better. [RT #15619]
+2840. [bug] Temporary fixed pkcs11-destroy usage check.
+ [RT #20760]
- --- 9.6.2 released ---
+2839. [bug] A KSK revoked by named could not be deleted.
+ [RT #20881]
-2850. [bug] If isc_heap_insert() failed due to memory shortage
- the heap would have corrupted entries. [RT #20951]
+2838. [placeholder]
-2849. [bug] Don't treat errors from the xml2 library as fatal.
- [RT #20945]
+2837. [port] Prevent Linux spurious warnings about fwrite().
+ [RT #20812]
-2846. [bug] EOF on unix domain sockets was not being handled
- correctly. [RT #20731]
+2836. [bug] Keys that were scheduled to become active could
+ be delayed. [RT #20874]
-2844. [doc] notify-delay default in ARM was wrong. It should have
- been five (5) seconds.
+2835. [bug] Key inactivity dates were inadvertently stored in
+ the private key file with the outdated tag
+ "Unpublish" rather than "Inactive". This has been
+ fixed; however, any existing keys that had Inactive
+ dates set will now need to have them reset, using
+ 'dnssec-settime -I'. [RT #20868]
- --- 9.6.2rc1 released ---
+2834. [bug] HMAC-SHA* keys that were longer than the algorithm
+ digest length were used incorrectly, leading to
+ interoperability problems with other DNS
+ implementations. This has been corrected.
+ (Note: If an oversize key is in use, and
+ compatibility is needed with an older release of
+ BIND, the new tool "isc-hmac-fixup" can convert
+ the key secret to a form that will work with all
+ versions.) [RT #20751]
-2838. [func] Backport support for SHA-2 DNSSEC algorithms,
- RSASHA256 and RSASHA512, from BIND 9.7. (This
- incorporates changes 2726 and 2738 from that
- release branch.) [RT #20871]
+2833. [cleanup] Fix usage messages in dnssec-keygen and dnssec-settime.
+ [RT #20851]
-2837. [port] Prevent Linux spurious warnings about fwrite().
- [RT #20812]
+2832. [bug] Modify "struct stat" in lib/export/samples/nsprobe.c
+ to avoid redefinition in some OSs [RT 20831]
2831. [security] Do not attempt to validate or cache
out-of-bailiwick data returned with a secure
answer; it must be re-fetched from its original
source and validated in that context. [RT #20819]
+2830. [bug] Changing the OPTOUT setting could take multiple
+ passes. [RT #20813]
+
+2829. [bug] Fixed potential node inconsistency in rbtdb.c.
+ [RT #20808]
+
2828. [security] Cached CNAME or DNAME RR could be returned to clients
without DNSSEC validation. [RT #20737]
2827. [security] Bogus NXDOMAIN could be cached as if valid. [RT #20712]
+2826. [bug] NSEC3->NSEC transitions could fail due to a lock not
+ being released. [RT #20740]
+
2825. [bug] Changing the setting of OPTOUT in a NSEC3 chain that
was in the process of being created was not properly
recorded in the zone. [RT #20786]
+2824. [bug] "rndc sign" was not being run by the correct task.
+ [RT #20759]
+
2823. [bug] rbtdb.c:getsigningtime() was missing locks. [RT #20781]
+2822. [bug] rbtdb.c:loadnode() could return the wrong result.
+ [RT #20802]
+
+2821. [doc] Add note that named-checkconf doesn't automatically
+ read rndc.key and bind.keys [RT #20758]
+
+2820. [func] Handle read access failure of OpenSSL configuration
+ file more user friendly (PKCS#11 engine patch).
+ [RT #20668]
+
2819. [cleanup] Removed unnecessary DNS_POINTER_MAXHOPS define.
[RT #20771]
2818. [cleanup] rndc could return an incorrect error code
when a zone was not found. [RT #20767]
+2817. [cleanup] Removed unnecessary isc_task_endexclusive() calls.
+ [RT #20768]
+
+2816. [bug] previous_closest_nsec() could fail to return
+ data for NSEC3 nodes [RT #29730]
+
2815. [bug] Exclusively lock the task when freezing a zone.
[RT #19838]
2814. [func] Provide a definitive error message when a master
zone is not loaded. [RT #20757]
- --- 9.6.2b1 released ---
+2813. [bug] Better handling of unreadable DNSSEC key files.
+ [RT #20710]
+
+2812. [bug] Make sure updates can't result in a zone with
+ NSEC-only keys and NSEC3 records. [RT 20748]
+
+2811. [cleanup] Add "rndc sign" to list of commands in rndc usage
+ output. [RT #20733]
+
+2810. [doc] Clarified the process of transitioning an NSEC3 zone
+ to insecure. [RT #20746]
+
+2809. [cleanup] Restored accidentally-deleted text in usage output
+ in dnssec-settime and dnssec-revoke [RT #20739]
+
+2808. [bug] Remove the attempt to install atomic.h from lib/isc.
+ atomic.h is correctly installed by the architecture
+ specific subdirectories. [RT #20722]
+
+2807. [bug] Fixed a possible ASSERT when reconfiguring zone
+ keys. [RT #20720]
+
+ --- 9.7.0rc1 released ---
+
+2806. [bug] "rdnc sign" could delay re-signing the DNSKEY
+ when it had changed. [RT #20703]
+
+2805. [bug] Fixed namespace problems encountered when building
+ external programs using non-exported BIND9 libraries
+ (i.e., built without --enable-exportlib). [RT #20679]
+
+2804. [bug] Send notifies when a zone is signed with "rndc sign"
+ or as a result of a scheduled key change. [RT #20700]
+
+2803. [port] win32: Install named-journalprint, nsec3hash, arpaname
+ and genrandom under windows. [RT #20670]
+
+2802. [cleanup] Rename journalprint to named-journalprint. [RT #20670]
+
+2801. [func] Detect and report records that are different according
+ to DNSSEC but are semantically equal according to plain
+ DNS. Apply plain DNS comparisons rather than DNSSEC
+ comparisons when processing UPDATE requests.
+ dnssec-signzone now removes such semantically duplicate
+ records prior to signing the RRset.
+
+ named-checkzone -r {ignore|warn|fail} (default warn)
+ named-compilezone -r {ignore|warn|fail} (default warn)
+
+ named.conf: check-dup-records {ignore|warn|fail};
+
+2800. [func] Reject zones which have NS records which refer to
+ CNAMEs, DNAMEs or don't have address record (class IN
+ only). Reject UPDATEs which would cause the zone
+ to fail the above checks if committed. [RT #20678]
+
+2799. [cleanup] Changed the "secure-to-insecure" option to
+ "dnssec-secure-to-insecure", and "dnskey-ksk-only"
+ to "dnssec-dnskey-kskonly", for clarity. [RT #20586]
+
+2798. [bug] Addressed bugs in managed-keys initialization
+ and rollover. [RT #20683]
2797. [bug] Don't decrement the dispatch manager's maxbuffers.
[RT #20613]
+2796. [bug] Missing dns_rdataset_disassociate() call in
+ dns_nsec3_delnsec3sx(). [RT #20681]
+
+2795. [cleanup] Add text to differentiate "update with no effect"
+ log messages. [RT #18889]
+
+2794. [bug] Install <isc/namespace.h>. [RT #20677]
+
+2793. [func] Add "autosign" and "metadata" tests to the
+ automatic tests. [RT #19946]
+
+2792. [func] "filter-aaaa-on-v4" can now be set in view
+ options (if compiled in). [RT #20635]
+
+2791. [bug] The installation of isc-config.sh was broken.
+ [RT #20667]
+
2790. [bug] Handle DS queries to stub zones. [RT #20440]
2789. [bug] Fixed an INSIST in dispatch.c [RT #20576]
+2788. [bug] dnssec-signzone could sign with keys that were
+ not requested [RT #20625]
+
+2787. [bug] Spurious log message when zone keys were
+ dynamically reconfigured. [RT #20659]
+
2786. [bug] Additional could be promoted to answer. [RT #20663]
+ --- 9.7.0b3 released ---
+
+2785. [bug] Revoked keys could fail to self-sign [RT #20652]
+
2784. [bug] TC was not always being set when required glue was
dropped. [RT #20655]
@@ -433,15 +887,65 @@
2782. [port] win32: use getaddrinfo() for hostname lookups.
[RT #20650]
+2781. [bug] Inactive keys could be used for signing. [RT #20649]
+
+2780. [bug] dnssec-keygen -A none didn't properly unset the
+ activation date in all cases. [RT #20648]
+
+2779. [bug] Dynamic key revocation could fail. [RT #20644]
+
+2778. [bug] dnssec-signzone could fail when a key was revoked
+ without deleting the unrevoked version. [RT #20638]
+
2777. [contrib] DLZ MYSQL auto reconnect support discovery was wrong.
+2776. [bug] Change #2762 was not correct. [RT #20647]
+
+2775. [bug] Accept RSASHA256 and RSASHA512 as NSEC3 compatible
+ in dnssec-keyfromlabel. [RT #20643]
+
+2774. [bug] Existing cache DB wasn't being reused after
+ reconfiguration. [RT #20629]
+
+2773. [bug] In autosigned zones, the SOA could be signed
+ with the KSK. [RT #20628]
+
2772. [security] When validating, track whether pending data was from
the additional section or not and only return it if
validates as secure. [RT #20438]
+2771. [bug] dnssec-signzone: DNSKEY records could be
+ corrupted when importing from key files [RT #20624]
+
+2770. [cleanup] Add log messages to resolver.c to indicate events
+ causing FORMERR responses. [RT #20526]
+
+2769. [cleanup] Change #2742 was incomplete. [RT #19589]
+
+2768. [bug] dnssec-signzone: -S no longer implies -g [RT #20568]
+
+2767. [bug] named could crash on startup if a zone was
+ configured with auto-dnssec and there was no
+ key-directory. [RT #20615]
+
+2766. [bug] isc_socket_fdwatchpoke() should only update the
+ socketmgr state if the socket is not pending on a
+ read or write. [RT #20603]
+
2765. [bug] Skip masters for which the TSIG key cannot be found.
[RT #20595]
+2764. [bug] "rndc-confgen -a" could trigger a REQUIRE. [RT #20610]
+
+2763. [bug] "rndc sign" didn't create an NSEC chain. [RT #20591]
+
+2762. [bug] DLV validation failed with a local slave DLV zone.
+ [RT #20577]
+
+2761. [cleanup] Enable internal symbol table for backtrace only for
+ systems that are known to work. Currently, BSD
+ variants, Linux and Solaris are supported. [RT# 20202]
+
2760. [cleanup] Corrected named-compilezone usage summary. [RT #20533]
2759. [doc] Add information about .jbk/.jnw files to
@@ -454,27 +958,115 @@
2757. [bug] dig: assertion failure could occur in connect
timeout. [RT #20599]
-2755. [doc] Clarify documentation of keyset- files in
- dnssec-signzone man page. [RT #19810]
+2756. [bug] Fixed corrupt logfile message in update.c. [RT# 20597]
+
+2755. [placeholder]
2754. [bug] Secure-to-insecure transitions failed when zone
was signed with NSEC3. [RT #20587]
+2753. [bug] Removed an unnecessary warning that could appear when
+ building an NSEC chain. [RT #20589]
+
+2752. [bug] Locking violation. [RT #20587]
+
+2751. [bug] Fixed a memory leak in dnssec-keyfromlabel. [RT #20588]
+
2750. [bug] dig: assertion failure could occur when a server
didn't have an address. [RT #20579]
2749. [bug] ixfr-from-differences generated a non-minimal ixfr
for NSEC3 signed zones. [RT #20452]
+2748. [func] Identify bad answers from GTLD servers and treat them
+ as referrals. [RT #18884]
+
2747. [bug] Journal roll forwards failed to set the re-signing
time of RRSIGs correctly. [RT #20541]
+2746. [port] hpux: address signed/unsigned expansion mismatch of
+ dns_rbtnode_t.nsec. [RT #20542]
+
+2745. [bug] configure script didn't probe the return type of
+ gai_strerror(3) correctly. [RT #20573]
+
+2744. [func] Log if a query was over TCP. [RT #19961]
+
2743. [bug] RRSIG could be incorrectly set in the NSEC3 record
for a insecure delegation.
+ --- 9.7.0b2 released ---
+
+2742. [cleanup] Clarify some DNSSEC-related log messages in
+ validator.c. [RT #19589]
+
+2741. [func] Allow the dnssec-keygen progress messages to be
+ suppressed (dnssec-keygen -q). Automatically
+ suppress the progress messages when stdin is not
+ a tty. [RT #20474]
+
+2740. [placeholder]
+
+2739. [cleanup] Clean up API for initializing and clearing trust
+ anchors for a view. [RT #20211]
+
+2738. [func] Add RSASHA256 and RSASHA512 tests to the dnssec system
+ test. [RT #20453]
+
+2737. [func] UPDATE requests can leak existence information.
+ [RT #17261]
+
+2736. [func] Improve the performance of NSEC signed zones with
+ more than a normal amount of glue below a delegation.
+ [RT #20191]
+
+2735. [bug] dnssec-signzone could fail to read keys
+ that were specified on the command line with
+ full paths, but weren't in the current
+ directory. [RT #20421]
+
+2734. [port] cygwin: arpaname did not compile. [RT #20473]
+
+2733. [cleanup] Clean up coding style in pkcs11-* tools. [RT #20355]
+
+2732. [func] Add optional filter-aaaa-on-v4 option, available
+ if built with './configure --enable-filter-aaaa'.
+ Filters out AAAA answers to clients connecting
+ via IPv4. (This is NOT recommended for general
+ use.) [RT #20339]
+
+2731. [func] Additional work on change 2709. The key parser
+ will now ignore unrecognized fields when the
+ minor version number of the private key format
+ has been increased. It will reject any key with
+ the major version number increased. [RT #20310]
+
+2730. [func] Have dnssec-keygen display a progress indication
+ a la 'openssl genrsa' on standard error. Note
+ when the first '.' is followed by a long stop
+ one has the choice between slow generation vs.
+ poor random quality, i.e., '-r /dev/urandom'.
+ [RT #20284]
+
2729. [func] When constructing a CNAME from a DNAME use the DNAME
TTL. [RT #20451]
+2728. [bug] dnssec-keygen, dnssec-keyfromlabel and
+ dnssec-signzone now warn immediately if asked to
+ write into a nonexistent directory. [RT #20278]
+
+2727. [func] The 'key-directory' option can now specify a relative
+ path. [RT #20154]
+
+2726. [func] Added support for SHA-2 DNSSEC algorithms,
+ RSASHA256 and RSASHA512. [RT #20023]
+
+2725. [doc] Added information about the file "managed-keys.bind"
+ to the ARM. [RT #20235]
+
+2724. [bug] Updates to a existing node in secure zone using NSEC
+ were failing. [RT #20448]
+
2723. [bug] isc_base32_totext(), isc_base32hex_totext(), and
isc_base64_totext(), didn't always mark regions of
memory as fully consumed after conversion. [RT #20445]
@@ -486,11 +1078,24 @@
2721. [port] Have dst__entropy_status() prime the random number
generator. [RT #20369]
+2720. [bug] RFC 5011 trust anchor updates could trigger an
+ assert if the DNSKEY record was unsigned. [RT #20406]
+
+2719. [func] Skip trusted/managed keys for unsupported algorithms.
+ [RT #20392]
+
2718. [bug] The space calculations in opensslrsa_todns() were
incorrect. [RT #20394]
+2717. [bug] named failed to update the NSEC/NSEC3 record when
+ the last private type record was removed as a result
+ of completing the signing the zone with a key.
+ [RT #20399]
+
2716. [bug] nslookup debug mode didn't return the ttl. [RT #20414]
+ --- 9.7.0b1 released ---
+
2715. [bug] Require OpenSSL support to be explicitly disabled.
[RT #20288]
@@ -500,19 +1105,63 @@
2713. [bug] powerpc: atomic operations missing asm("ics") /
__isync() calls.
+2712. [func] New 'auto-dnssec' zone option allows zone signing
+ to be fully automated in zones configured for
+ dynamic DNS. 'auto-dnssec allow;' permits a zone
+ to be signed by creating keys for it in the
+ key-directory and using 'rndc sign <zone>'.
+ 'auto-dnssec maintain;' allows that too, plus it
+ also keeps the zone's DNSSEC keys up to date
+ according to their timing metadata. [RT #19943]
+
+2711. [port] win32: Add the bin/pkcs11 tools into the full
+ build. [RT #20372]
+
+2710. [func] New 'dnssec-signzone -x' flag and 'dnskey-ksk-only'
+ zone option cause a zone to be signed with only KSKs
+ signing the DNSKEY RRset, not ZSKs. This reduces
+ the size of a DNSKEY answer. [RT #20340]
+
+2709. [func] Added some data fields, currently unused, to the
+ private key file format, to allow implementation
+ of explicit key rollover in a future release
+ without impairing backward or forward compatibility.
+ [RT #20310]
+
+2708. [func] Insecure to secure and NSEC3 parameter changes via
+ update are now fully supported and no longer require
+ defines to enable. We now no longer overload the
+ NSEC3PARAM flag field, nor the NSEC OPT bit at the
+ apex. Secure to insecure changes are controlled by
+ by the named.conf option 'secure-to-insecure'.
+
+ Warning: If you had previously enabled support by
+ adding defines at compile time to BIND 9.6 you should
+ ensure that all changes that are in progress have
+ completed prior to upgrading to BIND 9.7. BIND 9.7
+ is not backwards compatible.
+
+2707. [func] dnssec-keyfromlabel no longer require engine name
+ to be specified in the label if there is a default
+ engine or the -E option has been used. Also, it
+ now uses default algorithms as dnssec-keygen does
+ (i.e., RSASHA1, or NSEC3RSASHA1 if -3 is used).
+ [RT #20371]
+
2706. [bug] Loading a zone with a very large NSEC3 salt could
trigger an assert. [RT #20368]
-2705. [bug] Reconcile the XML stats version number with a later
- BIND9 release, by adding a "name" attribute to
- "cache" elements and increasing the version number
- to 2.2. (This is a minor version change, but may
- affect XML parsers if they assume the cache element
- doesn't take an attribute.)
+2705. [placeholder]
2704. [bug] Serial of dynamic and stub zones could be inconsistent
with their SOA serial. [RT #19387]
+2703. [func] Introduce an OpenSSL "engine" argument with -E
+ for all binaries which can take benefit of
+ crypto hardware. [RT #20230]
+
+2702. [func] Update PKCS#11 tools (bin/pkcs11) [RT #20225 & all]
+
2701. [doc] Correction to ARM: hmac-md5 is no longer the only
supported TSIG key algorithm. [RT #18046]
@@ -521,6 +1170,8 @@
2699. [bug] Missing lock in rbtdb.c. [RT #20037]
+2698. [placeholder]
+
2697. [port] win32: ensure that S_IFMT, S_IFDIR, S_IFCHR and
S_IFREG are defined after including <isc/stat.h>.
[RT #20309]
@@ -528,8 +1179,25 @@
2696. [bug] named failed to successfully process some valid
acl constructs. [RT #20308]
+2695. [func] DHCP/DDNS - update fdwatch code for use by
+ DHCP. Modify the api to isc_sockfdwatch_t (the
+ callback functon for isc_socket_fdwatchcreate)
+ to include information about the direction (read
+ or write) and add isc_socket_fdwatchpoke.
+ [RT #20253]
+
+2694. [bug] Reduce default NSEC3 iterations from 100 to 10.
+ [RT #19970]
+
+2693. [port] Add some noreturn attributes. [RT #20257]
+
2692. [port] win32: 32/64 bit cleanups. [RT #20335]
+2691. [func] dnssec-signzone: retain the existing NSEC or NSEC3
+ chain when re-signing a previously-signed zone.
+ Use -u to modify NSEC3 parameters or switch
+ between NSEC and NSEC3. [RT #20304]
+
2690. [bug] win32: fix isc_thread_key_getspecific() prototype.
[RT #20315]
@@ -538,25 +1206,102 @@
2688. [bug] Use INTERFACE_F_POINTTOPOINT, not IFF_POINTOPOINT,
to decide to fetch the destination address. [RT #20305]
+2687. [bug] Fixed dnssec-signzone -S handling of revoked keys.
+ Also, added warnings when revoking a ZSK, as this is
+ not defined by protocol (but is legal). [RT #19943]
+
2686. [bug] dnssec-signzone should clean the old NSEC chain when
signing with NSEC3 and vice versa. [RT #20301]
+2685. [contrib] Update contrib/zkt to version 0.99c. [RT #20054]
+
+2684. [cleanup] dig: formalize +ad and +cd as synonyms for
+ +adflag and +cdflag. [RT #19305]
+
2683. [bug] dnssec-signzone should clean out old NSEC3 chains when
the NSEC3 parameters used to sign the zone change.
[RT #20246]
+2682. [bug] "configure --enable-symtable=all" failed to
+ build. [RT #20282]
+
2681. [bug] IPSECKEY RR of gateway type 3 was not correctly
decoded. [RT #20269]
+2680. [func] Move contrib/pkcs11-keygen to bin/pkcs11. [RT #20067]
+
+2679. [func] dig -k can now accept TSIG keys in named.conf
+ format. [RT #20031]
+
2678. [func] Treat DS queries as if "minimal-response yes;"
was set. [RT #20258]
+2677. [func] Changes to key metadata behavior:
+ - Keys without "publish" or "active" dates set will
+ no longer be used for smart signing. However,
+ those dates will be set to "now" by default when
+ a key is created; to generate a key but not use
+ it yet, use dnssec-keygen -G.
+ - New "inactive" date (dnssec-keygen/settime -I)
+ sets the time when a key is no longer used for
+ signing but is still published.
+ - The "unpublished" date (-U) is deprecated in
+ favour of "deleted" (-D).
+ [RT #20247]
+
+2676. [bug] --with-export-installdir should have been
+ --with-export-includedir. [RT #20252]
+
+2675. [bug] dnssec-signzone could crash if the key directory
+ did not exist. [RT #20232]
+
+ --- 9.7.0a3 released ---
+
+2674. [bug] "dnssec-lookaside auto;" crashed if named was built
+ without openssl. [RT #20231]
+
+2673. [bug] The managed-keys.bind zone file could fail to
+ load due to a spurious result from sync_keyzone()
+ [RT #20045]
+
2672. [bug] Don't enable searching in 'host' when doing reverse
lookups. [RT #20218]
+2671. [bug] Add support for PKCS#11 providers not returning
+ the public exponent in RSA private keys
+ (OpenCryptoki for instance) in
+ dnssec-keyfromlabel. [RT #19294]
+
2670. [bug] Unexpected connect failures failed to log enough
information to be useful. [RT #20205]
+2669. [func] Update PKCS#11 support to support Keyper HSM.
+ Update PKCS#11 patch to be against openssl-0.9.8i.
+
+2668. [func] Several improvements to dnssec-* tools, including:
+ - dnssec-keygen and dnssec-settime can now set key
+ metadata fields 0 (to unset a value, use "none")
+ - dnssec-revoke sets the revocation date in
+ addition to the revoke bit
+ - dnssec-settime can now print individual metadata
+ fields instead of always printing all of them,
+ and can print them in unix epoch time format for
+ use by scripts
+ [RT #19942]
+
+2667. [func] Add support for logging stack backtrace on assertion
+ failure (not available for all platforms). [RT #19780]
+
+2666. [func] Added an 'options' argument to dns_name_fromstring()
+ (API change from 9.7.0a2). [RT #20196]
+
+2665. [func] Clarify syntax for managed-keys {} statement, add
+ ARM documentation about RFC 5011 support. [RT #19874]
+
+2664. [bug] create_keydata() and minimal_update() in zone.c
+ didn't properly check return values for some
+ functions. [RT #19956]
+
2663. [func] win32: allow named to run as a service using
"NT AUTHORITY\LocalService" as the account. [RT #19977]
@@ -567,19 +1312,40 @@
2661. [bug] Check whether socket fd exceeds FD_SETSIZE when
creating lwres context. [RT #20029]
+2660. [func] Add a new set of DNS libraries for non-BIND9
+ applications. See README.libdns. [RT #19369]
+
2659. [doc] Clarify dnssec-keygen doc: key name must match zone
name for DNSSEC keys. [RT #19938]
+2658. [bug] dnssec-settime and dnssec-revoke didn't process
+ key file paths correctly. [RT #20078]
+
+2657. [cleanup] Lower "journal file <path> does not exist, creating it"
+ log level to debug 1. [RT #20058]
+
2656. [func] win32: add a "tools only" check box to the installer
which causes it to only install dig, host, nslookup,
nsupdate and relevant DLLs. [RT #19998]
2655. [doc] Document that key-directory does not affect
- rndc.key. [RT #20155]
+ bind.keys, rndc.key or session.key. [RT #20155]
+
+2654. [bug] Improve error reporting on duplicated names for
+ deny-answer-xxx. [RT #20164]
2653. [bug] Treat ENGINE_load_private_key() failures as key
not found rather than out of memory. [RT #18033]
+2652. [func] Provide more detail about what record is being
+ deleted. [RT #20061]
+
+2651. [bug] Dates could print incorrectly in K*.key files on
+ 64-bit systems. [RT #20076]
+
+2650. [bug] Assertion failure in dnssec-signzone when trying
+ to read keyset-* files. [RT #20075]
+
2649. [bug] Set the domain for forward only zones. [RT #19944]
2648. [port] win32: isc_time_seconds() was broken. [RT #19900]
@@ -592,37 +1358,99 @@
2645. [port] "gcc -m32" didn't work on amd64 and x86_64 platforms
which default to 64 bits. [RT #19927]
+ --- 9.7.0a2 released ---
+
+2644. [bug] Change #2628 caused a regression on some systems;
+ named was unable to write the PID file and would
+ fail on startup. [RT #20001]
+
2643. [bug] Stub zones interacted badly with NSEC3 support.
[RT #19777]
2642. [bug] nsupdate could dump core on solaris when reading
improperly formatted key files. [RT #20015]
+2641. [bug] Fixed an error in parsing update-policy syntax,
+ added a regression test to check it. [RT #20007]
+
2640. [security] A specially crafted update packet will cause named
to exit. [RT #20000]
2639. [bug] Silence compiler warnings in gssapi code. [RT #19954]
+2638. [bug] Install arpaname. [RT #19957]
+
2637. [func] Rationalize dnssec-signzone's signwithkey() calling.
[RT #19959]
+2636. [func] Simplify zone signing and key maintenance with the
+ dnssec-* tools. Major changes:
+ - all dnssec-* tools now take a -K option to
+ specify a directory in which key files will be
+ stored
+ - DNSSEC can now store metadata indicating when
+ they are scheduled to be published, activated,
+ revoked or removed; these values can be set by
+ dnssec-keygen or overwritten by the new
+ dnssec-settime command
+ - dnssec-signzone -S (for "smart") option reads key
+ metadata and uses it to determine automatically
+ which keys to publish to the zone, use for
+ signing, revoke, or remove from the zone
+ [RT #19816]
+
2635. [bug] isc_inet_ntop() incorrectly handled 0.0/16 addresses.
[RT #19716]
+2634. [port] win32: Add support for libxml2, enable
+ statschannel. [RT #19773]
+
2633. [bug] Handle 15 bit rand() functions. [RT #19783]
2632. [func] util/kit.sh: warn if documentation appears to be out of
date. [RT #19922]
+2631. [bug] Handle "//", "/./" and "/../" in mkdirpath().
+ [RT #19926 ]
+
+2630. [func] Improved syntax for DDNS autoconfiguration: use
+ "update-policy local;" to switch on local DDNS in a
+ zone. (The "ddns-autoconf" option has been removed.)
+ [RT #19875]
+
+2629. [port] Check for seteuid()/setegid(), use setresuid()/
+ setresgid() if not present. [RT #19932]
+
+2628. [port] linux: Allow /var/run/named/named.pid to be opened
+ at startup with reduced capabilities in operation.
+ [RT #19884]
+
+2627. [bug] Named aborted if the same key was included in
+ trusted-keys more than once. [RT #19918]
+
+2626. [bug] Multiple trusted-keys could trigger an assertion
+ failure. [RT #19914]
+
2625. [bug] Missing UNLOCK in rbtdb.c. [RT #19865]
-2623. [bug] Named started seaches for DS non-optimally. [RT #19915]
+2624. [func] 'named-checkconf -p' will print out the parsed
+ configuration. [RT #18871]
+
+2623. [bug] Named started searches for DS non-optimally. [RT #19915]
-2621. [doc] Made copyright boilterplate consistent. [RT #19833]
+2622. [bug] Printing of named.conf grammar was broken. [RT #19919]
+
+2621. [doc] Made copyright boilerplate consistent. [RT #19833]
2620. [bug] Delay thawing the zone until the reload of it has
completed successfully. [RT #19750]
+2619. [func] Add support for RFC 5011, automatic trust anchor
+ maintenance. The new "managed-keys" statement can
+ be used in place of "trusted-keys" for zones which
+ support this protocol. (Note: this syntax is
+ expected to change prior to 9.7.0 final.) [RT #19248]
+
2618. [bug] The sdb and sdlz db_interator_seek() methods could
loop infinitely. [RT #19847]
@@ -638,11 +1466,33 @@
2614. [port] win32: 'named -v' should automatically be executed
in the foreground. [RT #19844]
-2613. [bug] Option argument validation was missing for
- dnssec-dsfromkey. [RT #19828]
+2613. [placeholder]
+
+ --- 9.7.0a1 released ---
+
+2612. [func] Add default values for the arguments to
+ dnssec-keygen. Without arguments, it will now
+ generate a 1024-bit RSASHA1 zone-signing key,
+ or with the -f KSK option, a 2048-bit RSASHA1
+ key-signing key. [RT #19300]
+
+2611. [func] Add -l option to dnssec-dsfromkey to generate
+ DLV records instead of DS records. [RT #19300]
2610. [port] sunos: Change #2363 was not complete. [RT #19796]
+2609. [func] Simplify the configuration of dynamic zones:
+ - add ddns-confgen command to generate
+ configuration text for named.conf
+ - add zone option "ddns-autoconf yes;", which
+ causes named to generate a TSIG session key
+ and allow updates to the zone using that key
+ - add '-l' (localhost) option to nsupdate, which
+ causes nsupdate to connect to a locally-running
+ named process using the session key generated
+ by named
+ [RT #19284]
+
2608. [func] Perform post signing verification checks in
dnssec-signzone. These can be disabled with -P.
@@ -652,27 +1502,6 @@
self signed. That all records in the zone are signed
by the algorithm. [RT #19653]
-2601. [doc] Mention file creation mode mask in the
- named manual page.
-
-2593. [bug] Improve a corner source of SERVFAILs [RT #19632]
-
-2589. [bug] dns_db_unregister() failed to clear '*dbimp'.
- [RT #19626]
-
-2581. [contrib] dlz/mysql set MYSQL_OPT_RECONNECT option on connection.
- Requires MySQL 5.0.19 or later. [RT #19084]
-
-2580. [bug] UpdateRej statistics counter could be incremented twice
- for one rejection. [RT #19476]
-
-2533. [doc] ARM: document @ (at-sign). [RT #17144]
-
-2500. [contrib] contrib/sdb/pgsql/zonetodb.c called non-existent
- function. [RT #18582]
-
- --- 9.6.1 released ---
-
2607. [bug] named could incorrectly delete NSEC3 records for
empty nodes when processing a update request.
[RT #19749]
@@ -683,6 +1512,11 @@
2605. [bug] Accept DS responses from delegation only zones.
[RT # 19296]
+2604. [func] Add support for DNS rebinding attack prevention through
+ new options, deny-answer-addresses and
+ deny-answer-aliases. Based on contributed code from
+ JD Nurmi, Google. [RT #18192]
+
2603. [port] win32: handle .exe extension of named-checkzone and
named-comilezone argv[0] names under windows.
[RT #19767]
@@ -690,11 +1524,17 @@
2602. [port] win32: fix debugging command line build of libisccfg.
[RT #19767]
- --- 9.6.1rc1 released ---
+2601. [doc] Mention file creation mode mask in the
+ named manual page.
+
+2600. [doc] ARM: miscellaneous reformatting for different
+ page widths. [RT #19574]
2599. [bug] Address rapid memory growth when validation fails.
[RT #19654]
+2598. [func] Reserve the -F flag. [RT #19657]
+
2597. [bug] Handle a validation failure with a insecure delegation
from a NSEC3 signed master/slave zone. [RT #19464]
@@ -704,16 +1544,31 @@
2595. [bug] Fix unknown extended rcodes in dig. [RT #19625]
+2594. [func] Have rndc warn if using its default configuration
+ file when the key file also exists. [RT #19424]
+
+2593. [bug] Improve a corner source of SERVFAILs [RT #19632]
+
2592. [bug] Treat "any" as a type in nsupdate. [RT #19455]
2591. [bug] named could die when processing a update in
removed_orphaned_ds(). [RT #19507]
+2590. [func] Report zone/class of "update with no effect".
+ [RT #19542]
+
+2589. [bug] dns_db_unregister() failed to clear '*dbimp'.
+ [RT #19626]
+
2588. [bug] SO_REUSEADDR could be set unconditionally after failure
of bind(2) call. This should be rare and mostly
harmless, but may cause interference with other
processes that happen to use the same port. [RT #19642]
+2587. [func] Improve logging by reporting serial numbers for
+ when zone serial has gone backwards or unchanged.
+ [RT #19506]
+
2586. [bug] Missing cleanup of SIG rdataset in searching a DLZ DB
or SDB. [RT #19577]
@@ -730,28 +1585,57 @@
2582. [bug] Don't emit warning log message when we attempt to
remove non-existent journal. [RT #19516]
+2581. [contrib] dlz/mysql set MYSQL_OPT_RECONNECT option on connection.
+ Requires MySQL 5.0.19 or later. [RT #19084]
+
+2580. [bug] UpdateRej statistics counter could be incremented twice
+ for one rejection. [RT #19476]
+
2579. [bug] DNSSEC lookaside validation failed to handle unknown
algorithms. [RT #19479]
2578. [bug] Changed default sig-signing-type to 65534, because
65535 turns out to be reserved. [RT #19477]
-2499. [port] solaris: lib/lwres/getaddrinfo.c namespace clash.
- [RT #18837]
-
- --- 9.6.1b1 released ---
-
2577. [doc] Clarified some statistics counters. [RT #19454]
2576. [bug] NSEC record were not being correctly signed when
a zone transitions from insecure to secure.
Handle such incorrectly signed zones. [RT #19114]
+2575. [func] New functions dns_name_fromstring() and
+ dns_name_tostring(), to simplify conversion
+ of a string to a dns_name structure and vice
+ versa. [RT #19451]
+
2574. [doc] Document nsupdate -g and -o. [RT #19351]
2573. [bug] Replacing a non-CNAME record with a CNAME record in a
single transaction in a signed zone failed. [RT #19397]
+2572. [func] Simplify DLV configuration, with a new option
+ "dnssec-lookaside auto;" This is the equivalent
+ of "dnssec-lookaside . trust-anchor dlv.isc.org;"
+ plus setting a trusted-key for dlv.isc.org.
+
+ Note: The trusted key is hard-coded into named,
+ but is also stored in (and can be overridden
+ by) $sysconfdir/bind.keys. As the ISC DLV key
+ rolls over it can be kept up to date by replacing
+ the bind.keys file with a key downloaded from
+ https://www.isc.org/solutions/dlv. [RT #18685]
+
+2571. [func] Add a new tool "arpaname" which translates IP addresses
+ to the corresponding IN-ADDR.ARPA or IP6.ARPA name.
+ [RT #18976]
+
+2570. [func] Log the destination address the query was sent to.
+ [RT #19209]
+
+2569. [func] Move journalprint, nsec3hash, and genrandom
+ commands from bin/tests into bin/tools;
+ "make install" will put them in $sbindir. [RT #19301]
+
2568. [bug] Report when the write to indicate a otherwise
successful start fails. [RT #19360]
@@ -760,6 +1644,15 @@
dnssec-dsfromkey could miss write errors.
[RT #19360]
+2566. [cleanup] Clarify logged message when an insecure DNSSEC
+ response arrives from a zone thought to be secure:
+ "insecurity proof failed" instead of "not
+ insecure". [RT #19400]
+
+2565. [func] Add support for HIP record. Includes new functions
+ dns_rdata_hip_first(), dns_rdata_hip_next()
+ and dns_rdata_hip_current(). [RT #19384]
+
2564. [bug] Only take EDNS fallback steps when processing timeouts.
[RT #19405]
@@ -776,6 +1669,10 @@
2559. [bug] dnssec-dsfromkey could compute bad DS records when
reading from a K* files. [RT #19357]
+2558. [func] Set the ownership of missing directories created
+ for pid-file if -u has been specified on the command
+ line. [RT #19328]
+
2557. [cleanup] PCI compliance:
* new libisc log module file
* isc_dir_chroot() now also changes the working
@@ -787,6 +1684,9 @@
error checks in the correct order resulting in the
wrong error code sometimes being returned. [RT #19249]
+2555. [func] dig: when emitting a hex dump also display the
+ corresponding characters. [RT #19258]
+
2554. [bug] Validation of uppercase queries from NSEC3 zones could
fail. [RT #19297]
@@ -810,6 +1710,10 @@
function isc_mem_reallocate() was introduced to address
this bug. [RT #19313]
+2546. [func] Add --enable-openssl-hash configure flag to use
+ OpenSSL (in place of internal routine) for hash
+ functions (MD5, SHA[12] and HMAC). [RT #18815]
+
2545. [doc] ARM: Legal hostname checking (check-names) is
for SRV RDATA too. [RT #19304]
@@ -822,6 +1726,8 @@
2541. [bug] Conditionally update dispatch manager statistics.
[RT #19247]
+2540. [func] Add a nibble mode to $GENERATE. [RT #18872]
+
2539. [security] Update the interaction between recursion, allow-query,
allow-query-cache and allow-recursion. [RT #19198]
@@ -829,7 +1735,7 @@
especially with threads and smaller max-cache-size
values. [RT #19240]
-2537. [experimental] Added more statistics counters including those on socket
+2537. [func] Added more statistics counters including those on socket
I/O events and query RTT histograms. [RT #18802]
2536. [cleanup] Silence some warnings when -Werror=format-security is
@@ -837,6 +1743,12 @@
2535. [bug] dig +showsearch and +trace interacted badly. [RT #19091]
+2534. [func] Check NAPTR records regular expressions and
+ replacement strings to ensure they are syntactically
+ valid and consistant. [RT #18168]
+
+2533. [doc] ARM: document @ (at-sign). [RT #17144]
+
2532. [bug] dig: check the question section of the response to
see if it matches the asked question. [RT #18495]
@@ -851,10 +1763,14 @@
2528. [cleanup] Silence spurious configure warning about
--datarootdir [RT #19096]
-2527. [bug] named could reuse cache on reload with
- enabling/disabling validation. [RT #19119]
+2527. [placeholder]
-2525. [experimental] New logging category "query-errors" to provide detailed
+2526. [func] New named option "attach-cache" that allows multiple
+ views to share a single cache to save memory and
+ improve lookup efficiency. Based on contributed code
+ from Barclay Osborn, Google. [RT #18905]
+
+2525. [func] New logging category "query-errors" to provide detailed
internal information about query failures, especially
about server failures. [RT #19027]
@@ -867,10 +1783,17 @@
2521. [bug] Improve epoll cross compilation support. [RT #19047]
+2520. [bug] Update xml statistics version number to 2.0 as change
+ #2388 made the schema incompatible to the previous
+ version. [RT #19080]
+
2519. [bug] dig/host with -4 or -6 didn't work if more than two
nameserver addresses of the excluded address family
preceded in resolv.conf. [RT #19081]
+2518. [func] Add support for the new CERT types from RFC 4398.
+ [RT #19077]
+
2517. [bug] dig +trace with -4 or -6 failed when it chose a
nameserver address of the excluded address type.
[RT #18843]
@@ -878,45 +1801,56 @@
2516. [bug] glue sort for responses was performed even when not
needed. [RT #19039]
+2515. [port] win32: build dnssec-dsfromkey and dnssec-keyfromlabel.
+ [RT #19063]
+
2514. [bug] dig/host failed with -4 or -6 when resolv.conf contains
a nameserver of the excluded address family.
[RT #18848]
+2513. [bug] Fix windows cli build. [RT #19062]
+
+2512. [func] Print a summary of the cached records which make up
+ the negative response. [RT #18885]
+
2511. [cleanup] dns_rdata_tofmttext() add const to linebreak.
[RT #18885]
+2510. [bug] "dig +sigchase" could trigger REQUIRE failures.
+ [RT #19033]
+
+2509. [bug] Specifying a fixed query source port was broken.
+ [RT #19051]
+
+2508. [placeholder]
+
+2507. [func] Log the recursion quota values when killing the
+ oldest query or refusing to recurse due to quota.
+ [RT #19022]
+
2506. [port] solaris: Check at configure time if
hack_shutup_pthreadonceinit is needed. [RT #19037]
2505. [port] Treat amd64 similarly to x86_64 when determining
atomic operation support. [RT #19031]
+2504. [bug] Address race condition in the socket code. [RT #18899]
+
2503. [port] linux: improve compatibility with Linux Standard
Base. [RT #18793]
2502. [cleanup] isc_radix: Improve compliance with coding style,
document function in <isc/radix.h>. [RT #18534]
- --- 9.6.0 released ---
-
-2520. [bug] Update xml statistics version number to 2.0 as change
- #2388 made the schema incompatible to the previous
- version. [RT #19080]
-
- --- 9.6.0rc2 released ---
-
-2515. [port] win32: build dnssec-dsfromkey and dnssec-keyfromlabel.
- [RT #19063]
-
-2513. [bug] Fix windows cli build. [RT #19062]
-
-2510. [bug] "dig +sigchase" could trigger REQUIRE failures.
- [RT #19033]
+2501. [func] $GENERATE now supports all rdata types. Multi-field
+ rdata types need to be quoted. See the ARM for
+ details. [RT #18368]
-2509. [bug] Specifying a fixed query source port was broken.
- [RT #19051]
+2500. [contrib] contrib/sdb/pgsql/zonetodb.c called non-existent
+ function. [RT #18582]
-2504. [bug] Address race condition in the socket code. [RT #18899]
+2499. [port] solaris: lib/lwres/getaddrinfo.c namespace clash.
+ [RT #18837]
--- 9.6.0rc1 released ---
diff --git a/COPYRIGHT b/COPYRIGHT
index ee90ece313ec..8721ceca8462 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -13,7 +13,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.14.176.3 2011-01-04 23:45:42 tbox Exp $
+$Id: COPYRIGHT,v 1.17 2011-01-04 23:47:13 tbox Exp $
Portions Copyright (C) 1996-2001 Nominum, Inc.
diff --git a/FAQ.xml b/FAQ.xml
index a9b2b41bbe67..4c83f7647075 100644
--- a/FAQ.xml
+++ b/FAQ.xml
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: FAQ.xml,v 1.46.56.9 2010-01-20 23:47:43 tbox Exp $ -->
+<!-- $Id: FAQ.xml,v 1.54 2010-01-19 23:48:55 tbox Exp $ -->
<article class="faq">
<title>Frequently Asked Questions about BIND 9</title>
diff --git a/HISTORY b/HISTORY
new file mode 100644
index 000000000000..e98f9b41460d
--- /dev/null
+++ b/HISTORY
@@ -0,0 +1,313 @@
+Summary of functional enhancements from prior major releases of BIND 9:
+
+BIND 9.6.0
+
+ Full NSEC3 support
+
+ Automatic zone re-signing
+
+ New update-policy methods tcp-self and 6to4-self
+
+ The BIND 8 resolver library, libbind, has been removed from the
+ BIND 9 distribution and is now available as a separate download.
+
+ Change the default pid file location from /var/run to
+ /var/run/{named,lwresd} for improved chroot/setuid support.
+
+BIND 9.5.0
+
+ GSS-TSIG support (RFC 3645).
+
+ DHCID support.
+
+ Experimental http server and statistics support for named via xml.
+
+ More detailed statistics counters including those supported in BIND 8.
+
+ Faster ACL processing.
+
+ Use Doxygen to generate internal documentation.
+
+ Efficient LRU cache-cleaning mechanism.
+
+ NSID support.
+
+BIND 9.4.0
+
+ Implemented "additional section caching (or acache)", an
+ internal cache framework for additional section content to
+ improve response performance. Several configuration options
+ were provided to control the behavior.
+
+ New notify type 'master-only'. Enable notify for master
+ zones only.
+
+ Accept 'notify-source' style syntax for query-source.
+
+ rndc now allows addresses to be set in the server clauses.
+
+ New option "allow-query-cache". This lets "allow-query"
+ be used to specify the default zone access level rather
+ than having to have every zone override the global value.
+ "allow-query-cache" can be set at both the options and view
+ levels. If "allow-query-cache" is not set then "allow-recursion"
+ is used if set, otherwise "allow-query" is used if set
+ unless "recursion no;" is set in which case "none;" is used,
+ otherwise the default (localhost; localnets;) is used.
+
+ rndc: the source address can now be specified.
+
+ ixfr-from-differences now takes master and slave in addition
+ to yes and no at the options and view levels.
+
+ Allow the journal's name to be changed via named.conf.
+
+ 'rndc notify zone [class [view]]' resend the NOTIFY messages
+ for the specified zone.
+
+ 'dig +trace' now randomly selects the next servers to try.
+ Report if there is a bad delegation.
+
+ Improve check-names error messages.
+
+ Make public the function to read a key file, dst_key_read_public().
+
+ dig now returns the byte count for axfr/ixfr.
+
+ allow-update is now settable at the options / view level.
+
+ named-checkconf now checks the logging configuration.
+
+ host now can turn on memory debugging flags with '-m'.
+
+ Don't send notify messages to self.
+
+ Perform sanity checks on NS records which refer to 'in zone' names.
+
+ New zone option "notify-delay". Specify a minimum delay
+ between sets of NOTIFY messages.
+
+ Extend adjusting TTL warning messages.
+
+ Named and named-checkzone can now both check for non-terminal
+ wildcard records.
+
+ "rndc freeze/thaw" now freezes/thaws all zones.
+
+ named-checkconf now check acls to verify that they only
+ refer to existing acls.
+
+ The server syntax has been extended to support a range of
+ servers.
+
+ Report differences between hints and real NS rrset and
+ associated address records.
+
+ Preserve the case of domain names in rdata during zone
+ transfers.
+
+ Restructured the data locking framework using architecture
+ dependent atomic operations (when available), improving
+ response performance on multi-processor machines significantly.
+ x86, x86_64, alpha, powerpc, and mips are currently supported.
+
+ UNIX domain controls are now supported.
+
+ Add support for additional zone file formats for improving
+ loading performance. The masterfile-format option in
+ named.conf can be used to specify a non-default format. A
+ separate command named-compilezone was provided to generate
+ zone files in the new format. Additionally, the -I and -O
+ options for dnssec-signzone specify the input and output
+ formats.
+
+ dnssec-signzone can now randomize signature end times
+ (dnssec-signzone -j jitter).
+
+ Add support for CH A record.
+
+ Add additional zone data constancy checks. named-checkzone
+ has extended checking of NS, MX and SRV record and the hosts
+ they reference. named has extended post zone load checks.
+ New zone options: check-mx and integrity-check.
+
+
+ edns-udp-size can now be overridden on a per server basis.
+
+ dig can now specify the EDNS version when making a query.
+
+ Added framework for handling multiple EDNS versions.
+
+ Additional memory debugging support to track size and mctx
+ arguments.
+
+ Detect duplicates of UDP queries we are recursing on and
+ drop them. New stats category "duplicates".
+
+ "USE INTERNAL MALLOC" is now runtime selectable.
+
+ The lame cache is now done on a <qname,qclass,qtype> basis
+ as some servers only appear to be lame for certain query
+ types.
+
+ Limit the number of recursive clients that can be waiting
+ for a single query (<qname,qtype,qclass>) to resolve. New
+ options clients-per-query and max-clients-per-query.
+
+ dig: report the number of extra bytes still left in the
+ packet after processing all the records.
+
+ Support for IPSECKEY rdata type.
+
+ Raise the UDP recieve buffer size to 32k if it is less than 32k.
+
+ x86 and x86_64 now have seperate atomic locking implementations.
+
+ named-checkconf now validates update-policy entries.
+
+ Attempt to make the amount of work performed in a iteration
+ self tuning. The covers nodes clean from the cache per
+ iteration, nodes written to disk when rewriting a master
+ file and nodes destroyed per iteration when destroying a
+ zone or a cache.
+
+ ISC string copy API.
+
+ Automatic empty zone creation for D.F.IP6.ARPA and friends.
+ Note: RFC 1918 zones are not yet covered by this but are
+ likely to be in a future release.
+
+ New options: empty-server, empty-contact, empty-zones-enable
+ and disable-empty-zone.
+
+ dig now has a '-q queryname' and '+showsearch' options.
+
+ host/nslookup now continue (default)/fail on SERVFAIL.
+
+ dig now warns if 'RA' is not set in the answer when 'RD'
+ was set in the query. host/nslookup skip servers that fail
+ to set 'RA' when 'RD' is set unless a server is explicitly
+ set.
+
+ Integrate contibuted DLZ code into named.
+
+ Integrate contibuted IDN code from JPNIC.
+
+ libbind: corresponds to that from BIND 8.4.7.
+
+BIND 9.3.0
+
+ DNSSEC is now DS based (RFC 3658).
+ See also RFC 3845, doc/draft/draft-ietf-dnsext-dnssec-*.
+
+ DNSSEC lookaside validation.
+
+ check-names is now implemented.
+ rrset-order in more complete.
+
+ IPv4/IPv6 transition support, dual-stack-servers.
+
+ IXFR deltas can now be generated when loading master files,
+ ixfr-from-differences.
+
+ It is now possible to specify the size of a journal, max-journal-size.
+
+ It is now possible to define a named set of master servers to be
+ used in masters clause, masters.
+
+ The advertised EDNS UDP size can now be set, edns-udp-size.
+
+ allow-v6-synthesis has been obsoleted.
+
+ NOTE:
+ * Zones containing MD and MF will now be rejected.
+ * dig, nslookup name. now report "Not Implemented" as
+ NOTIMP rather than NOTIMPL. This will have impact on scripts
+ that are looking for NOTIMPL.
+
+ libbind: corresponds to that from BIND 8.4.5.
+
+BIND 9.2.0
+
+ 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. See
+ win32utils/readme1.txt and win32utils/win32-build.txt for details.
+
+ This distribution also includes a new lightweight stub
+ resolver library and associated resolver daemon that fully
+ support forward and reverse lookups of both IPv4 and IPv6
+ addresses. This library is considered experimental and
+ is not a complete replacement for the BIND 8 resolver library.
+ Applications that use the BIND 8 res_* functions to perform
+ DNS lookups or dynamic updates still need to be linked against
+ the BIND 8 libraries. For DNS lookups, they can also use the
+ new "getrrsetbyname()" API.
+
+ BIND 9.2 is capable of acting as an authoritative server
+ for DNSSEC secured zones. This functionality is believed to
+ be stable and complete except for lacking support for
+ verifications involving wildcard records in secure zones.
+
+ When acting as a caching server, BIND 9.2 can be configured
+ to perform DNSSEC secure resolution on behalf of its clients.
+ This part of the DNSSEC implementation is still considered
+ experimental. For detailed information about the state of the
+ DNSSEC implementation, see the file doc/misc/dnssec.
+
+ There are a few known bugs:
+
+ On some systems, IPv6 and IPv4 sockets interact in
+ unexpected ways. For details, see doc/misc/ipv6.
+ To reduce the impact of these problems, the server
+ no longer listens for requests on IPv6 addresses
+ by default. If you need to accept DNS queries over
+ IPv6, you must specify "listen-on-v6 { any; };"
+ in the named.conf options statement.
+
+ FreeBSD prior to 4.2 (and 4.2 if running as non-root)
+ and OpenBSD prior to 2.8 log messages like
+ "fcntl(8, F_SETFL, 4): Inappropriate ioctl for device".
+ This is due to a bug in "/dev/random" and impacts the
+ server's DNSSEC support.
+
+ OS X 10.1.4 (Darwin 5.4), OS X 10.1.5 (Darwin 5.5) and
+ OS X 10.2 (Darwin 6.0) reports errors like
+ "fcntl(3, F_SETFL, 4): Operation not supported by device".
+ This is due to a bug in "/dev/random" and impacts the
+ server's DNSSEC support.
+
+ --with-libtool does not work on AIX.
+
+ A bug in some versions of the Microsoft 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.
diff --git a/KNOWN-DEFECTS b/KNOWN-DEFECTS
deleted file mode 100644
index 83d71759740e..000000000000
--- a/KNOWN-DEFECTS
+++ /dev/null
@@ -1,15 +0,0 @@
-dnssec-signzone was designed so that it could sign a zone partially, using
-only a subset of the DNSSEC keys needed to produce a fully-signed zone.
-This permits a zone administrator, for example, to sign a zone with one
-key on one machine, move the resulting partially-signed zone to a second
-machine, and sign it again with a second key.
-
-An unfortunate side-effect of this flexibility is that dnssec-signzone
-does not check to make sure it's signing a zone with any valid keys at
-all. An attempt to sign a zone without any keys will appear to succeed,
-producing a "signed" zone with no signatures. There is no warning issued
-when a zone is not signed.
-
-This will be corrected in a future release. In the meantime, ISC
-recommends examining the output of dnssec-signzone to confirm that
-the zone is properly signed by all keys before using it.
diff --git a/Makefile.in b/Makefile.in
index e4d56396da2b..95944d9fa4ff 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.52.48.2 2009-02-20 23:47:23 tbox Exp $
+# $Id: Makefile.in,v 1.58 2009-11-26 20:52:44 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -21,13 +21,13 @@ top_srcdir = @top_srcdir@
@BIND9_VERSION@
-SUBDIRS = make lib bin doc
+SUBDIRS = make lib bin doc @LIBEXPORT@
TARGETS =
MANPAGES = isc-config.sh.1
-
+
HTMLPAGES = isc-config.sh.html
-
+
MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
@@ -54,7 +54,8 @@ installdirs:
install:: isc-config.sh installdirs
${INSTALL_SCRIPT} isc-config.sh ${DESTDIR}${bindir}
- ${INSTALL_DATA} ${srcdir}/isc-config.sh.1 ${DESTDIR}${mandir}/man1
+ ${INSTALL_DATA} ${top_srcdir}/isc-config.sh.1 ${DESTDIR}${mandir}/man1
+ ${INSTALL_DATA} ${top_srcdir}/bind.keys ${DESTDIR}${sysconfdir}
tags:
rm -f TAGS
diff --git a/NSEC3-NOTES b/NSEC3-NOTES
deleted file mode 100644
index 3f8d8f905c00..000000000000
--- a/NSEC3-NOTES
+++ /dev/null
@@ -1,128 +0,0 @@
-
- DNSSEC and UPDATE
-
- Converting from insecure to secure
-
-As of BIND 9.6.0 it is possible to move a zone between being insecure
-to secure and back again. A secure zone can be using NSEC or NSEC3.
-
-To move a zone from insecure to secure you need to configure named
-so that it can see the K* files which contain the public and private
-parts of the keys that will be used to sign the zone. These files
-will have been generated by dnssec-keygen. You can do this by
-placing them in the key-directory as specified in named.conf.
-
- zone example.net {
- type master;
- allow-update { .... };
- file "dynamic/example.net/example.net";
- key-directory "dynamic/example.net";
- };
-
-Assuming one KSK and one ZSK DNSKEY key have been generated. Then
-this will cause the zone to be signed with the ZSK and the DNSKEY
-RRset to be signed with the KSK DNSKEY. A NSEC chain will also be
-generated as part of the initial signing process.
-
- % nsupdate
- > ttl 3600
- > update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
- > update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
- > send
-
-While the update request will complete almost immediately the zone
-will not be completely signed until named has had time to walk the
-zone and generate the NSEC and RRSIG records. Initially the NSEC
-record at the zone apex will have the OPT bit set. When the NSEC
-chain is complete the OPT bit will be cleared. Additionally when
-the zone is fully signed the private type (default TYPE65534) records
-will have a non zero value for the final octet.
-
-The private type record has 5 octets.
- algorithm (octet 1)
- key id in network order (octet 2 and 3)
- removal flag (octet 4)
- complete flag (octet 5)
-
-If you wish to go straight to a secure zone using NSEC3 you should
-also add a NSEC3PARAM record to the update request with the flags
-field set to indicate whether the NSEC3 chain will have the OPTOUT
-bit set or not.
-
- % nsupdate
- > ttl 3600
- > update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
- > update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
- > update add example.net NSEC3PARAM 1 1 100 1234567890
- > send
-
-Again the update request will complete almost immediately however the
-NSEC3PARAM record will have additional flag bits set indicating that the
-NSEC3 chain is under construction. When the NSEC3 chain is complete the
-flags field will be set to zero.
-
-While the initial signing and NSEC/NSEC3 chain generation is happening
-other updates are possible.
-
- DNSKEY roll overs via UPDATE
-
-It is possible to perform key rollovers via update. You need to
-add the K* files for the new keys so that named can find them. You
-can then add the new DNSKEY RRs via update. Named will then cause
-the zone to be signed with the new keys. When the signing is
-complete the private type records will be updated so that the last
-octet is non zero.
-
-If this is for a KSK you need to inform the parent and any trust
-anchor repositories of the new KSK.
-
-You should then wait for the maximum TLL in the zone before removing the
-old DNSKEY. If it is a KSK that is being updated you also need to wait
-for the DS RRset in the parent to be updated and its TTL to expire.
-This ensures that all clients will be able to verify at least a signature
-when you remove the old DNSKEY.
-
-The old DNSKEY can be removed via UPDATE. Take care to specify
-the correct key. Named will clean out any signatures generated by
-the old key after the update completes.
-
- NSEC3PARAM rollovers via UPDATE.
-
-Add the new NSEC3PARAM record via update. When the new NSEC3 chain
-has been generated the NSEC3PARAM flag field will be zero. At this
-point you can remove the old NSEC3PARAM record. The old chain will
-be removed after the update request completes.
-
- Converting from NSEC to NSEC3
-
-To do this you just need to add a NSEC3PARAM record. When the
-conversion is complete the NSEC chain will have been removed and
-the NSEC3PARAM record will have a zero flag field. The NSEC3 chain
-will be generated before the NSEC chain is destroyed.
-
- Converting from NSEC3 to NSEC
-
-To do this remove all NSEC3PARAM records with a zero flag field. The
-NSEC chain will be generated before the NSEC3 chain is removed.
-
- Converting from secure to insecure
-
-To do this remove all the DNSKEY records. Any NSEC or NSEC3 chains
-will be removed as well as associated NSEC3PARAM records. This will
-take place after the update requests completes.
-
- Periodic re-signing.
-
-Named will periodically re-sign RRsets which have not been re-signed
-as a result of some update action. The signature lifetimes will
-be adjusted so as to spread the re-sign load over time rather than
-all at once.
-
- NSEC3 and OPTOUT
-
-Named only supports creating new NSEC3 chains where all the NSEC3
-records in the zone have the same OPTOUT state. Named supports
-UPDATES to zones where the NSEC3 records in the chain have mixed
-OPTOUT state. Named does not support changing the OPTOUT state of
-an individual NSEC3 record, the entire chain needs to be changed if
-the OPTOUT state of an individual NSEC3 needs to be changed.
diff --git a/README b/README
index 54d90fe1f22c..00010c3983f3 100644
--- a/README
+++ b/README
@@ -42,368 +42,95 @@ BIND 9
Stichting NLnet - NLnet Foundation
Nominum, Inc.
-BIND 9.6.3
-
- BIND 9.6.3 is a maintenance release, fixing bugs in 9.6.2.
-
-BIND 9.6.2
-
- BIND 9.6.2 is a maintenance release, fixing bugs in 9.6.1.
- It also introduces support for the SHA-2 DNSSEC algorithms,
- RSASHA256 and RSASHA512.
-
- Known issues in this release:
-
- - A validating resolver that has been incorrectly configured with
- an invalid trust anchor will be unable to resolve names covered
- by that trust anchor. In all current versions of BIND 9, such a
- resolver will also generate significant unnecessary DNS traffic
- while trying to validate. The latter problem will be addressed
- in future BIND 9 releases. In the meantime, to avoid these
- problems, exercise caution when configuring "trusted-keys":
- make sure all keys are correct and current when you add them,
- and update your configuration in a timely manner when keys
- roll over.
-
-BIND 9.6.1
-
- BIND 9.6.1 is a maintenance release, fixing bugs in 9.6.0.
-
-BIND 9.6.0
-
- BIND 9.6.0 includes a number of changes from BIND 9.5 and earlier
- releases, including:
-
- Full NSEC3 support
-
- Automatic zone re-signing
-
- New update-policy methods tcp-self and 6to4-self
-
- The BIND 8 resolver library, libbind, has been removed from the
- BIND 9 distribution and is now available as a separate download.
-
- Change the default pid file location from /var/run to
- /var/run/{named,lwresd} for improved chroot/setuid support.
-
-BIND 9.5.0
-
- BIND 9.5.0 has a number of new features over 9.4,
- including:
-
- GSS-TSIG support (RFC 3645).
-
- DHCID support.
-
- Experimental http server and statistics support for named via xml.
-
- More detailed statistics counters including those supported in BIND 8.
-
- Faster ACL processing.
-
- Use Doxygen to generate internal documentation.
-
- Efficient LRU cache-cleaning mechanism.
-
- NSID support.
-
-BIND 9.4.0
-
- BIND 9.4.0 has a number of new features over 9.3,
- including:
-
- Implemented "additional section caching (or acache)", an
- internal cache framework for additional section content to
- improve response performance. Several configuration options
- were provided to control the behavior.
-
- New notify type 'master-only'. Enable notify for master
- zones only.
-
- Accept 'notify-source' style syntax for query-source.
-
- rndc now allows addresses to be set in the server clauses.
-
- New option "allow-query-cache". This lets "allow-query"
- be used to specify the default zone access level rather
- than having to have every zone override the global value.
- "allow-query-cache" can be set at both the options and view
- levels. If "allow-query-cache" is not set then "allow-recursion"
- is used if set, otherwise "allow-query" is used if set
- unless "recursion no;" is set in which case "none;" is used,
- otherwise the default (localhost; localnets;) is used.
-
- rndc: the source address can now be specified.
-
- ixfr-from-differences now takes master and slave in addition
- to yes and no at the options and view levels.
-
- Allow the journal's name to be changed via named.conf.
-
- 'rndc notify zone [class [view]]' resend the NOTIFY messages
- for the specified zone.
-
- 'dig +trace' now randomly selects the next servers to try.
- Report if there is a bad delegation.
-
- Improve check-names error messages.
-
- Make public the function to read a key file, dst_key_read_public().
-
- dig now returns the byte count for axfr/ixfr.
-
- allow-update is now settable at the options / view level.
-
- named-checkconf now checks the logging configuration.
-
- host now can turn on memory debugging flags with '-m'.
-
- Don't send notify messages to self.
-
- Perform sanity checks on NS records which refer to 'in zone' names.
-
- New zone option "notify-delay". Specify a minimum delay
- between sets of NOTIFY messages.
-
- Extend adjusting TTL warning messages.
-
- Named and named-checkzone can now both check for non-terminal
- wildcard records.
-
- "rndc freeze/thaw" now freezes/thaws all zones.
-
- named-checkconf now check acls to verify that they only
- refer to existing acls.
-
- The server syntax has been extended to support a range of
- servers.
-
- Report differences between hints and real NS rrset and
- associated address records.
-
- Preserve the case of domain names in rdata during zone
- transfers.
-
- Restructured the data locking framework using architecture
- dependent atomic operations (when available), improving
- response performance on multi-processor machines significantly.
- x86, x86_64, alpha, powerpc, and mips are currently supported.
-
- UNIX domain controls are now supported.
-
- Add support for additional zone file formats for improving
- loading performance. The masterfile-format option in
- named.conf can be used to specify a non-default format. A
- separate command named-compilezone was provided to generate
- zone files in the new format. Additionally, the -I and -O
- options for dnssec-signzone specify the input and output
- formats.
-
- dnssec-signzone can now randomize signature end times
- (dnssec-signzone -j jitter).
-
- Add support for CH A record.
-
- Add additional zone data constancy checks. named-checkzone
- has extended checking of NS, MX and SRV record and the hosts
- they reference. named has extended post zone load checks.
- New zone options: check-mx and integrity-check.
-
-
- edns-udp-size can now be overridden on a per server basis.
-
- dig can now specify the EDNS version when making a query.
-
- Added framework for handling multiple EDNS versions.
-
- Additional memory debugging support to track size and mctx
- arguments.
-
- Detect duplicates of UDP queries we are recursing on and
- drop them. New stats category "duplicates".
-
- "USE INTERNAL MALLOC" is now runtime selectable.
-
- The lame cache is now done on a <qname,qclass,qtype> basis
- as some servers only appear to be lame for certain query
- types.
-
- Limit the number of recursive clients that can be waiting
- for a single query (<qname,qtype,qclass>) to resolve. New
- options clients-per-query and max-clients-per-query.
-
- dig: report the number of extra bytes still left in the
- packet after processing all the records.
-
- Support for IPSECKEY rdata type.
-
- Raise the UDP recieve buffer size to 32k if it is less than 32k.
-
- x86 and x86_64 now have seperate atomic locking implementations.
-
- named-checkconf now validates update-policy entries.
-
- Attempt to make the amount of work performed in a iteration
- self tuning. The covers nodes clean from the cache per
- iteration, nodes written to disk when rewriting a master
- file and nodes destroyed per iteration when destroying a
- zone or a cache.
-
- ISC string copy API.
-
- Automatic empty zone creation for D.F.IP6.ARPA and friends.
- Note: RFC 1918 zones are not yet covered by this but are
- likely to be in a future release.
-
- New options: empty-server, empty-contact, empty-zones-enable
- and disable-empty-zone.
-
- dig now has a '-q queryname' and '+showsearch' options.
-
- host/nslookup now continue (default)/fail on SERVFAIL.
-
- dig now warns if 'RA' is not set in the answer when 'RD'
- was set in the query. host/nslookup skip servers that fail
- to set 'RA' when 'RD' is set unless a server is explicitly
- set.
-
- Integrate contibuted DLZ code into named.
-
- Integrate contibuted IDN code from JPNIC.
-
- libbind: corresponds to that from BIND 8.4.7.
-
-BIND 9.3.0
-
- BIND 9.3.0 has a number of new features over 9.2,
- including:
-
- DNSSEC is now DS based (RFC 3658).
- See also RFC 3845, doc/draft/draft-ietf-dnsext-dnssec-*.
-
- DNSSEC lookaside validation.
-
- check-names is now implemented.
- rrset-order in more complete.
-
- IPv4/IPv6 transition support, dual-stack-servers.
-
- IXFR deltas can now be generated when loading master files,
- ixfr-from-differences.
-
- It is now possible to specify the size of a journal, max-journal-size.
-
- It is now possible to define a named set of master servers to be
- used in masters clause, masters.
-
- The advertised EDNS UDP size can now be set, edns-udp-size.
-
- allow-v6-synthesis has been obsoleted.
-
- NOTE:
- * Zones containing MD and MF will now be rejected.
- * dig, nslookup name. now report "Not Implemented" as
- NOTIMP rather than NOTIMPL. This will have impact on scripts
- that are looking for NOTIMPL.
-
- libbind: corresponds to that from BIND 8.4.5.
-
-BIND 9.2.0
-
- BIND 9.2.0 has a number of new features over 9.1,
- including:
-
- - The size of the cache can now be limited using the
- "max-cache-size" option.
-
- - The server can now automatically convert RFC1886-style
- recursive lookup requests into RFC2874-style lookups,
- when enabled using the new option "allow-v6-synthesis".
- This allows stub resolvers that support AAAA records
- but not A6 record chains or binary labels to perform
- lookups in domains that make use of these IPv6 DNS
- features.
-
- - Performance has been improved.
-
- - The man pages now use the more portable "man" macros
- rather than the "mandoc" macros, and are installed
- by "make install".
-
- - The named.conf parser has been completely rewritten.
- It now supports "include" directives in more
- places such as inside "view" statements, and it no
- longer has any reserved words.
-
- - The "rndc status" command is now implemented.
-
- - rndc can now be configured automatically.
-
- - A BIND 8 compatible stub resolver library is now
- included in lib/bind.
-
- - OpenSSL has been removed from the distribution. This
- means that to use DNSSEC, OpenSSL must be installed and
- the --with-openssl option must be supplied to configure.
- This does not apply to the use of TSIG, which does not
- require OpenSSL.
-
- - The source distribution now builds on Windows.
- See win32utils/readme1.txt and win32utils/win32-build.txt
- for details.
-
- This distribution also includes a new lightweight stub
- resolver library and associated resolver daemon that fully
- support forward and reverse lookups of both IPv4 and IPv6
- addresses. This library is considered experimental and
- is not a complete replacement for the BIND 8 resolver library.
- Applications that use the BIND 8 res_* functions to perform
- DNS lookups or dynamic updates still need to be linked against
- the BIND 8 libraries. For DNS lookups, they can also use the
- new "getrrsetbyname()" API.
-
- BIND 9.2 is capable of acting as an authoritative server
- for DNSSEC secured zones. This functionality is believed to
- be stable and complete except for lacking support for
- verifications involving wildcard records in secure zones.
-
- When acting as a caching server, BIND 9.2 can be configured
- to perform DNSSEC secure resolution on behalf of its clients.
- This part of the DNSSEC implementation is still considered
- experimental. For detailed information about the state of the
- DNSSEC implementation, see the file doc/misc/dnssec.
-
- There are a few known bugs:
-
- On some systems, IPv6 and IPv4 sockets interact in
- unexpected ways. For details, see doc/misc/ipv6.
- To reduce the impact of these problems, the server
- no longer listens for requests on IPv6 addresses
- by default. If you need to accept DNS queries over
- IPv6, you must specify "listen-on-v6 { any; };"
- in the named.conf options statement.
-
- FreeBSD prior to 4.2 (and 4.2 if running as non-root)
- and OpenBSD prior to 2.8 log messages like
- "fcntl(8, F_SETFL, 4): Inappropriate ioctl for device".
- This is due to a bug in "/dev/random" and impacts the
- server's DNSSEC support.
-
- OS X 10.1.4 (Darwin 5.4), OS X 10.1.5 (Darwin 5.5) and
- OS X 10.2 (Darwin 6.0) reports errors like
- "fcntl(3, F_SETFL, 4): Operation not supported by device".
- This is due to a bug in "/dev/random" and impacts the
- server's DNSSEC support.
-
- --with-libtool does not work on AIX.
-
- A bug in some versions of the Microsoft 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 summary of functional enhancements in previous
+ releases, see the HISTORY file.
For a detailed list of user-visible changes from
previous releases, see the CHANGES file.
+BIND 9.8.0
+
+ BIND 9.8.0 includes a number of changes from BIND 9.7 and earlier
+ releases. New features include:
+
+ - Built-in trust anchor for the root zone, which can be
+ switched on via "dnssec-validation auto;"
+ - Support for DNS64.
+ - Support for response policy zones (RPZ).
+ - Support for writable DLZ zones.
+ - Improved ease of configuration of GSS/TSIG for
+ interoperability with Active Directory
+ - Support for GOST signing algorithm for DNSSEC.
+ - Removed RTT Banding from server selection algorithm.
+ - New "static-stub" zone type.
+ - Allow configuration of resolver timeouts via
+ "resolver-query-timeout" option.
+
+BIND 9.7.0
+
+ BIND 9.7.0 includes a number of changes from BIND 9.6 and earlier
+ releases. Most are intended to simplify DNSSEC configuration.
+
+ New features include:
+
+ - Fully automatic signing of zones by "named".
+ - Simplified configuration of DNSSEC Lookaside Validation (DLV).
+ - Simplified configuration of Dynamic DNS, using the "ddns-confgen"
+ command line tool or the "local" update-policy option. (As a side
+ effect, this also makes it easier to configure automatic zone
+ re-signing.)
+ - New named option "attach-cache" that allows multiple views to
+ share a single cache.
+ - DNS rebinding attack prevention.
+ - New default values for dnssec-keygen parameters.
+ - Support for RFC 5011 automated trust anchor maintenance
+ - Smart signing: simplified tools for zone signing and key
+ maintenance.
+ - The "statistics-channels" option is now available on Windows.
+ - A new DNSSEC-aware libdns API for use by non-BIND9 applications
+ - On some platforms, named and other binaries can now print out
+ a stack backtrace on assertion failure, to aid in debugging.
+ - A "tools only" installation mode on Windows, which only installs
+ dig, host, nslookup and nsupdate.
+ - Improved PKCS#11 support, including Keyper support and explicit
+ OpenSSL engine selection.
+
+ Known issues in this release:
+
+ - In rare cases, DNSSEC validation can leak memory. When this
+ happens, it will cause an assertion failure when named exits,
+ but is otherwise harmless. A fix exists, but was too late for
+ this release; it will be included in BIND 9.7.1.
+
+ Compatibility notes:
+
+ - If you had built BIND 9.6 with any of ALLOW_NSEC3PARAM_UPDATE,
+ ALLOW_SECURE_TO_INSECURE or ALLOW_INSECURE_TO_SECURE defined, then
+ you should ensure that all changes that are in progress have
+ completed prior to upgrading to BIND 9.7. BIND 9.7 implements
+ those features in a way which is not backwards compatible.
+
+ - Prior releases had a bug which caused HMAC-SHA* keys with long
+ secrets to be used incorrectly. Fixing this bug means that older
+ versions of BIND 9 may fail to interoperate with this version
+ when using TSIG keys. If this occurs, the new "isc-hmac-fixup"
+ tool will convert a key with a long secret into a form that works
+ correctly with all versions of BIND 9. See the "isc-hmac-fixup"
+ man page for additional details.
+
+ - Revoking a DNSSEC key with "dnssec-revoke" changes its key ID.
+ It is possible for the new key ID to collide with that of a
+ different key. Newly generated keys will not have this problem,
+ as "dnssec-keygen" looks for potential collisions before
+ generating keys, but exercise caution if using key revokation
+ with keys that were generated by older versions of BIND 9. See
+ the Administrator's Reference Manual, section 4.10 ("Dynamic
+ Trust Anchor Management") for more details.
+
+ - A bug was fixed in which a key's scheduled inactivity date was
+ stored incorectly. Users who participated in the 9.7.0 BETA test
+ and had DNSSEC keys with scheduled inactivity dates will need to
+ reset those keys' dates using "dnssec-settime -I".
Building
@@ -417,7 +144,7 @@ Building
FreeBSD 4.10, 5.2.1, 6.2
HP-UX 11.11
Mac OS X 10.5
- NetBSD 3.x and 4.0-beta
+ NetBSD 3.x, 4.0-beta, 5.0-beta
OpenBSD 3.3 and up
Solaris 8, 9, 9 (x86), 10
Ubuntu 7.04, 7.10
@@ -594,6 +321,9 @@ Documentation
Frequently asked questions and their answers can be found in
FAQ.
+ Additional information on various subjects can be found
+ in the other README files.
+
Bug Reports and Mailing Lists
diff --git a/README.idnkit b/README.idnkit
deleted file mode 100644
index f5255f5f97a9..000000000000
--- a/README.idnkit
+++ /dev/null
@@ -1,112 +0,0 @@
-
- BIND-9 IDN patch
-
- Japan Network Information Center (JPNIC)
-
-
-* What is this patch for?
-
-This patch adds internationalized domain name (IDN) support to BIND-9.
-You'll get internationalized version of dig/host/nslookup commands.
-
- + internationalized dig/host/nslookup
- dig/host/nslookup accepts non-ASCII domain names in the local
- codeset (such as Shift JIS, Big5 or ISO8859-1) determined by
- the locale information. The domain names are normalized and
- converted to the encoding on the DNS protocol, and sent to DNS
- servers. The replies are converted back to the local codeset
- and displayed.
-
-
-* Compilation & installation
-
-0. Prerequisite
-
-You have to build and install idnkit before building this patched version
-of bind-9.
-
-1. Running configure script
-
-Run `configure' in the top directory. See `README' for the
-configuration options.
-
-This patch adds the following 4 options to `configure'. You should
-at least specify `--with-idn' option to enable IDN support.
-
- --with-idn[=IDN_PREFIX]
- To enable IDN support, you have to specify `--with-idn' option.
- The argument IDN_PREFIX is the install prefix of idnkit. If
- IDN_PREFIX is omitted, PREFIX (derived from `--prefix=PREFIX')
- is assumed.
-
- --with-libiconv[=LIBICONV_PREFIX]
- Specify this option if idnkit you have installed links GNU
- libiconv. The argument LIBICONV_PREFIX is install prefix of
- GNU libiconv. If the argument is omitted, PREFIX (derived
- from `--prefix=PREFIX') is assumed.
-
- `--with-libiconv' is shorthand option for GNU libiconv.
-
- --with-libiconv=/usr/local
-
- This is equivalent to:
-
- --with-iconv='-L/usr/local/lib -R/usr/local/lib -liconv'
-
- `--with-libiconv' assumes that your C compiler has `-R'
- option, and that the option adds the specified run-time path
- to an executable binary. If `-R' option of your compiler has
- different meaning, or your compiler lacks the option, you
- should use `--with-iconv' option instead. Binary command
- without run-time path information might be unexecutable.
- In that case, you would see an error message like:
-
- error in loading shared libraries: libiconv.so.2: cannot
- open shared object file
-
- If both `--with-libiconv' and `--with-iconv' options are
- specified, `--with-iconv' is prior to `--with-libiconv'.
-
- --with-iconv=ICONV_LIBSPEC
- If your libc doesn't provide iconv(), you need to specify the
- library containing iconv() with this option. `ICONV_LIBSPEC'
- is the argument(s) to `cc' or `ld' to link the library, for
- example, `--with-iconv="-L/usr/local/lib -liconv"'.
- You don't need to specify the header file directory for "iconv.h"
- to the compiler, as it isn't included directly by bind-9 with
- this patch.
-
- --with-idnlib=IDN_LIBSPEC
- With this option, you can explicitly specify the argument(s)
- to `cc' or `ld' to link the idnkit's library, `libidnkit'. If
- this option is not specified, `-L${PREFIX}/lib -lidnkit' is
- assumed, where ${PREFIX} is the installation prefix specified
- with `--with-idn' option above. You may need to use this
- option to specify extra arguments, for example,
- `--with-idnlib="-L/usr/local/lib -R/usr/local/lib -lidnkit"'.
-
-Please consult `README' for other configuration options.
-
-Note that if you want to specify some extra header file directories,
-you should use the environment variable STD_CINCLUDES instead of
-CFLAGS, as described in README.
-
-2. Compilation and installation
-
-After running "configure", just do
-
- make
- make install
-
-for compiling and installing.
-
-
-* Contact information
-
-Please see http//www.nic.ad.jp/en/idn/ for the latest news
-about idnkit and this patch.
-
-Bug reports and comments on this kit should be sent to
-mdnkit-bugs@nic.ad.jp and idn-cmt@nic.ad.jp, respectively.
-
-; $Id: README.idnkit,v 1.2.762.1 2009-01-18 23:25:14 marka Exp $
diff --git a/README.pkcs11 b/README.pkcs11
deleted file mode 100644
index b58640de1c5a..000000000000
--- a/README.pkcs11
+++ /dev/null
@@ -1,61 +0,0 @@
-
- BIND-9 PKCS#11 support
-
-Prerequisite
-
-The PKCS#11 support needs a PKCS#11 OpenSSL engine based on the Solaris one,
-released the 2007-11-21 for OpenSSL 0.9.8g, with a bug fix (call to free)
-and some improvements, including user friendly PIN management.
-
-Compilation
-
-"configure --with-pkcs11 ..."
-
-PKCS#11 Libraries
-
-Tested with Solaris one with a SCA board and with openCryptoki with the
-software token.
-
-OpenSSL Engines
-
-With PKCS#11 support the PKCS#11 engine is statically loaded but at its
-initialization it dynamically loads the PKCS#11 objects.
-Even the pre commands are therefore unused they are defined with:
- SO_PATH:
- define: PKCS11_SO_PATH
- default: /usr/local/lib/engines/engine_pkcs11.so
- MODULE_PATH:
- define: PKCS11_MODULE_PATH
- default: /usr/lib/libpkcs11.so
-Without PKCS#11 support, a specific OpenSSL engine can be still used
-by defining ENGINE_ID at compile time.
-
-PKCS#11 tools
-
-The contrib/pkcs11-keygen directory contains a set of experimental tools
-to handle keys stored in a Hardware Security Module at the benefit of BIND.
-
-The patch for OpenSSL 0.9.8g is in this directory. Read its README.pkcs11
-for the way to use it (these are the original notes so with the original
-path, etc. Define OPENCRYPTOKI to use it with openCryptoki.)
-
-PIN management
-
-With the just fixed PKCS#11 OpenSSL engine, the PIN should be entered
-each time it is required. With the improved engine, the PIN should be
-entered the first time it is required or can be configured in the
-OpenSSL configuration file (aka. openssl.cnf) by adding in it:
- - at the beginning:
- openssl_conf = openssl_def
- - at any place these sections:
- [ openssl_def ]
- engines = engine_section
- [ engine_section ]
- pkcs11 = pkcs11_section
- [ pkcs11_section ]
- PIN = put__your__pin__value__here
-
-Note
-
-Some names here are registered trademarks, at least Solaris is a trademark
-of Sun Microsystems Inc...
diff --git a/acconfig.h b/acconfig.h
index d64404ad1e3f..d9da221f83f1 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: acconfig.h,v 1.51.334.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: acconfig.h,v 1.53 2008-12-01 23:47:44 tbox Exp $ */
/*! \file */
diff --git a/bin/Makefile.in b/bin/Makefile.in
index 1694268fb79e..d263d795eb02 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,13 +13,14 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.25 2007-06-19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.29 2009-10-05 12:07:08 fdupont Exp $
srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-SUBDIRS = named rndc dig dnssec tests nsupdate check
+SUBDIRS = named rndc dig dnssec tests tools nsupdate \
+ check confgen @PKCS11_TOOLS@
TARGETS =
@BIND9_MAKE_RULES@
diff --git a/bin/check/Makefile.in b/bin/check/Makefile.in
index 46271c77de7f..d5827dcce11e 100644
--- a/bin/check/Makefile.in
+++ b/bin/check/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.32 2007-06-19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.36 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -32,6 +32,7 @@ CWARNINGS =
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
@@ -39,7 +40,8 @@ ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@
-LIBS = @LIBS@
+LIBS = ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@
SUBDIRS =
@@ -69,14 +71,14 @@ named-checkzone.@O@: named-checkzone.c
named-checkconf@EXEEXT@: named-checkconf.@O@ check-tool.@O@ ${ISCDEPLIBS} \
${ISCCFGDEPLIBS} ${BIND9DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- named-checkconf.@O@ check-tool.@O@ ${BIND9LIBS} ${ISCCFGLIBS} \
- ${DNSLIBS} ${ISCLIBS} ${LIBS}
+ export BASEOBJS="named-checkconf.@O@ check-tool.@O@"; \
+ export LIBS0="${BIND9LIBS} ${ISCCFGLIBS} ${DNSLIBS}"; \
+ ${FINALBUILDCMD}
named-checkzone@EXEEXT@: named-checkzone.@O@ check-tool.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- named-checkzone.@O@ check-tool.@O@ ${ISCCFGLIBS} ${DNSLIBS} \
- ${ISCLIBS} ${LIBS}
+ export BASEOBJS="named-checkzone.@O@ check-tool.@O@"; \
+ export LIBS0="${ISCCFGLIBS} ${DNSLIBS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/check/check-tool.c b/bin/check/check-tool.c
index ed9224bb9aa2..4d2ca5c45ab5 100644
--- a/bin/check/check-tool.c
+++ b/bin/check/check-tool.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check-tool.c,v 1.35.36.5 2010-09-07 23:46:05 tbox Exp $ */
+/* $Id: check-tool.c,v 1.41 2010-09-07 23:46:59 tbox Exp $ */
/*! \file */
@@ -601,8 +601,7 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
isc_buffer_add(&buffer, strlen(zonename));
dns_fixedname_init(&fixorigin);
origin = dns_fixedname_name(&fixorigin);
- CHECK(dns_name_fromtext(origin, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL));
CHECK(dns_zone_setorigin(zone, origin));
CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype));
CHECK(dns_zone_setfile2(zone, filename, fileformat));
diff --git a/bin/check/check-tool.h b/bin/check/check-tool.h
index f9273ff152e8..4371ae29ec20 100644
--- a/bin/check/check-tool.h
+++ b/bin/check/check-tool.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check-tool.h,v 1.14.334.2 2010-09-07 23:46:05 tbox Exp $ */
+/* $Id: check-tool.h,v 1.16 2010-09-07 23:46:59 tbox Exp $ */
#ifndef CHECK_TOOL_H
#define CHECK_TOOL_H
diff --git a/bin/check/named-checkconf.8 b/bin/check/named-checkconf.8
index 71310073e8d0..fabcfa916eb7 100644
--- a/bin/check/named-checkconf.8
+++ b/bin/check/named-checkconf.8
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2002 Internet Software Consortium.
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: named-checkconf.8,v 1.30.334.1 2009-07-11 01:55:20 tbox Exp $
+.\" $Id: named-checkconf.8,v 1.33 2009-12-29 01:14:03 tbox Exp $
.\"
.hy 0
.ad l
@@ -33,11 +33,29 @@
named\-checkconf \- named configuration file syntax checking tool
.SH "SYNOPSIS"
.HP 16
-\fBnamed\-checkconf\fR [\fB\-h\fR] [\fB\-v\fR] [\fB\-j\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] {filename} [\fB\-z\fR]
+\fBnamed\-checkconf\fR [\fB\-h\fR] [\fB\-v\fR] [\fB\-j\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] {filename} [\fB\-p\fR] [\fB\-z\fR]
.SH "DESCRIPTION"
.PP
\fBnamed\-checkconf\fR
-checks the syntax, but not the semantics, of a named configuration file.
+checks the syntax, but not the semantics, of a
+\fBnamed\fR
+configuration file. The file is parsed and checked for syntax errors, along with all files included by it. If no file is specified,
+\fI/etc/named.conf\fR
+is read by default.
+.PP
+Note: files that
+\fBnamed\fR
+reads in separate parser contexts, such as
+\fIrndc.key\fR
+and
+\fIbind.keys\fR, are not automatically read by
+\fBnamed\-checkconf\fR. Configuration errors in these files may cause
+\fBnamed\fR
+to fail to run, even if
+\fBnamed\-checkconf\fR
+was successful.
+\fBnamed\-checkconf\fR
+can be run on these files explicitly, however.
.SH "OPTIONS"
.PP
\-h
@@ -59,6 +77,13 @@ Print the version of the
program and exit.
.RE
.PP
+\-p
+.RS 4
+Print out the
+\fInamed.conf\fR
+and included files in canonical form if no errors were detected.
+.RE
+.PP
\-z
.RS 4
Perform a test load of all master zones found in
@@ -88,7 +113,7 @@ BIND 9 Administrator Reference Manual.
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
.br
Copyright \(co 2000\-2002 Internet Software Consortium.
.br
diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c
index 20983b5b9392..521ed31916c5 100644
--- a/bin/check/named-checkconf.c
+++ b/bin/check/named-checkconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: named-checkconf.c,v 1.46.222.4 2010-09-07 23:46:05 tbox Exp $ */
+/* $Id: named-checkconf.c,v 1.54 2010-09-07 01:49:08 marka Exp $ */
/*! \file */
@@ -59,9 +59,12 @@ isc_log_t *logc = NULL;
} while (0)
/*% usage */
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(void) {
- fprintf(stderr, "usage: %s [-h] [-j] [-v] [-z] [-t directory] "
+ fprintf(stderr, "usage: %s [-h] [-j] [-p] [-v] [-z] [-t directory] "
"[named.conf]\n", program);
exit(1);
}
@@ -203,6 +206,24 @@ configure_zone(const char *vclass, const char *view,
zfile = cfg_obj_asstring(fileobj);
obj = NULL;
+ if (get_maps(maps, "check-dup-records", &obj)) {
+ if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
+ zone_options |= DNS_ZONEOPT_CHECKDUPRR;
+ zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
+ } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
+ zone_options |= DNS_ZONEOPT_CHECKDUPRR;
+ zone_options |= DNS_ZONEOPT_CHECKDUPRRFAIL;
+ } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
+ zone_options &= ~DNS_ZONEOPT_CHECKDUPRR;
+ zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
+ } else
+ INSIST(0);
+ } else {
+ zone_options |= DNS_ZONEOPT_CHECKDUPRR;
+ zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
+ }
+
+ obj = NULL;
if (get_maps(maps, "check-mx", &obj)) {
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
zone_options |= DNS_ZONEOPT_CHECKMX;
@@ -387,6 +408,15 @@ load_zones_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx) {
return (result);
}
+static void
+output(void *closure, const char *text, int textlen) {
+ UNUSED(closure);
+ if (fwrite(text, 1, textlen, stdout) != (size_t)textlen) {
+ perror("fwrite");
+ exit(1);
+ }
+}
+
/*% The main processing routine */
int
main(int argc, char **argv) {
@@ -399,10 +429,11 @@ main(int argc, char **argv) {
int exit_status = 0;
isc_entropy_t *ectx = NULL;
isc_boolean_t load_zones = ISC_FALSE;
+ isc_boolean_t print = ISC_FALSE;
isc_commandline_errprint = ISC_FALSE;
- while ((c = isc_commandline_parse(argc, argv, "dhjt:vz")) != EOF) {
+ while ((c = isc_commandline_parse(argc, argv, "dhjt:pvz")) != EOF) {
switch (c) {
case 'd':
debug++;
@@ -421,6 +452,10 @@ main(int argc, char **argv) {
}
break;
+ case 'p':
+ print = ISC_TRUE;
+ break;
+
case 'v':
printf(VERSION "\n");
exit(0);
@@ -485,6 +520,8 @@ main(int argc, char **argv) {
exit_status = 1;
}
+ if (print && exit_status == 0)
+ cfg_print(config, output, NULL);
cfg_obj_destroy(parser, &config);
cfg_parser_destroy(&parser);
diff --git a/bin/check/named-checkconf.docbook b/bin/check/named-checkconf.docbook
index e0c43d17118b..fe12cb3ea278 100644
--- a/bin/check/named-checkconf.docbook
+++ b/bin/check/named-checkconf.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2002 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named-checkconf.docbook,v 1.19 2007-06-19 06:58:03 marka Exp $ -->
+<!-- $Id: named-checkconf.docbook,v 1.22 2009-12-28 23:21:16 each Exp $ -->
<refentry id="man.named-checkconf">
<refentryinfo>
<date>June 14, 2000</date>
@@ -35,6 +35,7 @@
<year>2004</year>
<year>2005</year>
<year>2007</year>
+ <year>2009</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
@@ -58,6 +59,7 @@
<arg><option>-j</option></arg>
<arg><option>-t <replaceable class="parameter">directory</replaceable></option></arg>
<arg choice="req">filename</arg>
+ <arg><option>-p</option></arg>
<arg><option>-z</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -65,8 +67,21 @@
<refsect1>
<title>DESCRIPTION</title>
<para><command>named-checkconf</command>
- checks the syntax, but not the semantics, of a named
- configuration file.
+ checks the syntax, but not the semantics, of a
+ <command>named</command> configuration file. The file is parsed
+ and checked for syntax errors, along with all files included by it.
+ If no file is specified, <filename>/etc/named.conf</filename> is read
+ by default.
+ </para>
+ <para>
+ Note: files that <command>named</command> reads in separate
+ parser contexts, such as <filename>rndc.key</filename> and
+ <filename>bind.keys</filename>, are not automatically read
+ by <command>named-checkconf</command>. Configuration
+ errors in these files may cause <command>named</command> to
+ fail to run, even if <command>named-checkconf</command> was
+ successful. <command>named-checkconf</command> can be run
+ on these files explicitly, however.
</para>
</refsect1>
@@ -87,8 +102,7 @@
<term>-t <replaceable class="parameter">directory</replaceable></term>
<listitem>
<para>
- Chroot to <filename>directory</filename> so that
- include
+ Chroot to <filename>directory</filename> so that include
directives in the configuration file are processed as if
run by a similarly chrooted named.
</para>
@@ -106,6 +120,16 @@
</varlistentry>
<varlistentry>
+ <term>-p</term>
+ <listitem>
+ <para>
+ Print out the <filename>named.conf</filename> and included files
+ in canonical form if no errors were detected.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-z</term>
<listitem>
<para>
diff --git a/bin/check/named-checkconf.html b/bin/check/named-checkconf.html
index 458b486e90fd..f5e4cd385114 100644
--- a/bin/check/named-checkconf.html
+++ b/bin/check/named-checkconf.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2002 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named-checkconf.html,v 1.30.334.1 2009-07-11 01:55:20 tbox Exp $ -->
+<!-- $Id: named-checkconf.html,v 1.33 2009-12-29 01:14:03 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,17 +29,30 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">named-checkconf</code> [<code class="option">-h</code>] [<code class="option">-v</code>] [<code class="option">-j</code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] {filename} [<code class="option">-z</code>]</p></div>
+<div class="cmdsynopsis"><p><code class="command">named-checkconf</code> [<code class="option">-h</code>] [<code class="option">-v</code>] [<code class="option">-j</code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] {filename} [<code class="option">-p</code>] [<code class="option">-z</code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543387"></a><h2>DESCRIPTION</h2>
+<a name="id2543395"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named-checkconf</strong></span>
- checks the syntax, but not the semantics, of a named
- configuration file.
+ checks the syntax, but not the semantics, of a
+ <span><strong class="command">named</strong></span> configuration file. The file is parsed
+ and checked for syntax errors, along with all files included by it.
+ If no file is specified, <code class="filename">/etc/named.conf</code> is read
+ by default.
+ </p>
+<p>
+ Note: files that <span><strong class="command">named</strong></span> reads in separate
+ parser contexts, such as <code class="filename">rndc.key</code> and
+ <code class="filename">bind.keys</code>, are not automatically read
+ by <span><strong class="command">named-checkconf</strong></span>. Configuration
+ errors in these files may cause <span><strong class="command">named</strong></span> to
+ fail to run, even if <span><strong class="command">named-checkconf</strong></span> was
+ successful. <span><strong class="command">named-checkconf</strong></span> can be run
+ on these files explicitly, however.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543399"></a><h2>OPTIONS</h2>
+<a name="id2543444"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-h</span></dt>
<dd><p>
@@ -47,8 +60,7 @@
</p></dd>
<dt><span class="term">-t <em class="replaceable"><code>directory</code></em></span></dt>
<dd><p>
- Chroot to <code class="filename">directory</code> so that
- include
+ Chroot to <code class="filename">directory</code> so that include
directives in the configuration file are processed as if
run by a similarly chrooted named.
</p></dd>
@@ -57,6 +69,11 @@
Print the version of the <span><strong class="command">named-checkconf</strong></span>
program and exit.
</p></dd>
+<dt><span class="term">-p</span></dt>
+<dd><p>
+ Print out the <code class="filename">named.conf</code> and included files
+ in canonical form if no errors were detected.
+ </p></dd>
<dt><span class="term">-z</span></dt>
<dd><p>
Perform a test load of all master zones found in
@@ -74,21 +91,21 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543507"></a><h2>RETURN VALUES</h2>
+<a name="id2543568"></a><h2>RETURN VALUES</h2>
<p><span><strong class="command">named-checkconf</strong></span>
returns an exit status of 1 if
errors were detected and 0 otherwise.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543518"></a><h2>SEE ALSO</h2>
+<a name="id2543579"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543548"></a><h2>AUTHOR</h2>
+<a name="id2543609"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/check/named-checkzone.8 b/bin/check/named-checkzone.8
index e5f07906a457..1bb784606d8d 100644
--- a/bin/check/named-checkzone.8
+++ b/bin/check/named-checkzone.8
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2002 Internet Software Consortium.
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: named-checkzone.8,v 1.42.334.3 2009-11-11 01:56:22 tbox Exp $
+.\" $Id: named-checkzone.8,v 1.47 2010-01-17 01:14:02 tbox Exp $
.\"
.hy 0
.ad l
@@ -33,9 +33,9 @@
named\-checkzone, named\-compilezone \- zone file validity checking or converting tool
.SH "SYNOPSIS"
.HP 16
-\fBnamed\-checkzone\fR [\fB\-d\fR] [\fB\-h\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-M\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename}
+\fBnamed\-checkzone\fR [\fB\-d\fR] [\fB\-h\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-M\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-r\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename}
.HP 18
-\fBnamed\-compilezone\fR [\fB\-d\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-C\ \fR\fB\fImode\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {\fB\-o\ \fR\fB\fIfilename\fR\fR} {zonename} {filename}
+\fBnamed\-compilezone\fR [\fB\-d\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-C\ \fR\fB\fImode\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-r\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {\fB\-o\ \fR\fB\fIfilename\fR\fR} {zonename} {filename}
.SH "DESCRIPTION"
.PP
\fBnamed\-checkzone\fR
@@ -201,6 +201,15 @@ then write to standard out. This is mandatory for
\fBnamed\-compilezone\fR.
.RE
.PP
+\-r \fImode\fR
+.RS 4
+Check for records that are treated as different by DNSSEC but are semantically equal in plain DNS. Possible modes are
+\fB"fail"\fR,
+\fB"warn"\fR
+(default) and
+\fB"ignore"\fR.
+.RE
+.PP
\-s \fIstyle\fR
.RS 4
Specify the style of the dumped zone file. Possible styles are
@@ -272,7 +281,7 @@ BIND 9 Administrator Reference Manual.
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2004\-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2004\-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
.br
Copyright \(co 2000\-2002 Internet Software Consortium.
.br
diff --git a/bin/check/named-checkzone.c b/bin/check/named-checkzone.c
index 3b86e576df5a..100e809867d1 100644
--- a/bin/check/named-checkzone.c
+++ b/bin/check/named-checkzone.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: named-checkzone.c,v 1.51.34.6 2010-09-07 23:46:06 tbox Exp $ */
+/* $Id: named-checkzone.c,v 1.61 2010-09-07 23:46:59 tbox Exp $ */
/*! \file */
@@ -70,6 +70,9 @@ static enum { progmode_check, progmode_compile } progmode;
} \
} while (0)
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(void) {
fprintf(stderr,
@@ -77,12 +80,13 @@ usage(void) {
"[-f inputformat] [-F outputformat] "
"[-t directory] [-w directory] [-k (ignore|warn|fail)] "
"[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] "
+ "[-r (ignore|warn|fail)] "
"[-i (full|full-sibling|local|local-sibling|none)] "
"[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] "
"[-W (ignore|warn)] "
"%s zonename filename\n",
prog_name,
- progmode == progmode_check ? "[-o filename]" : "{-o filename}");
+ progmode == progmode_check ? "[-o filename]" : "-o filename");
exit(1);
}
@@ -140,17 +144,19 @@ main(int argc, char **argv) {
if (progmode == progmode_compile) {
zone_options |= (DNS_ZONEOPT_CHECKNS |
DNS_ZONEOPT_FATALNS |
+ DNS_ZONEOPT_CHECKDUPRR |
DNS_ZONEOPT_CHECKNAMES |
DNS_ZONEOPT_CHECKNAMESFAIL |
DNS_ZONEOPT_CHECKWILDCARD);
- }
+ } else
+ zone_options |= DNS_ZONEOPT_CHECKDUPRR;
#define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)
isc_commandline_errprint = ISC_FALSE;
while ((c = isc_commandline_parse(argc, argv,
- "c:df:hi:jk:m:n:qs:t:o:vw:DF:M:S:W:"))
+ "c:df:hi:jk:m:n:qr:s:t:o:vw:DF:M:S:W:"))
!= EOF) {
switch (c) {
case 'c':
@@ -262,16 +268,27 @@ main(int argc, char **argv) {
}
break;
+ case 'o':
+ output_filename = isc_commandline_argument;
+ break;
+
case 'q':
quiet++;
break;
- case 't':
- result = isc_dir_chroot(isc_commandline_argument);
- if (result != ISC_R_SUCCESS) {
- fprintf(stderr, "isc_dir_chroot: %s: %s\n",
- isc_commandline_argument,
- isc_result_totext(result));
+ case 'r':
+ if (ARGCMP("warn")) {
+ zone_options |= DNS_ZONEOPT_CHECKDUPRR;
+ zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL;
+ } else if (ARGCMP("fail")) {
+ zone_options |= DNS_ZONEOPT_CHECKDUPRR |
+ DNS_ZONEOPT_CHECKDUPRRFAIL;
+ } else if (ARGCMP("ignore")) {
+ zone_options &= ~(DNS_ZONEOPT_CHECKDUPRR |
+ DNS_ZONEOPT_CHECKDUPRRFAIL);
+ } else {
+ fprintf(stderr, "invalid argument to -r: %s\n",
+ isc_commandline_argument);
exit(1);
}
break;
@@ -289,8 +306,14 @@ main(int argc, char **argv) {
}
break;
- case 'o':
- output_filename = isc_commandline_argument;
+ case 't':
+ result = isc_dir_chroot(isc_commandline_argument);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "isc_dir_chroot: %s: %s\n",
+ isc_commandline_argument,
+ isc_result_totext(result));
+ exit(1);
+ }
break;
case 'v':
diff --git a/bin/check/named-checkzone.docbook b/bin/check/named-checkzone.docbook
index 0e04c033f38b..415ee1c34499 100644
--- a/bin/check/named-checkzone.docbook
+++ b/bin/check/named-checkzone.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2002 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named-checkzone.docbook,v 1.34.334.3 2009-11-10 20:01:41 each Exp $ -->
+<!-- $Id: named-checkzone.docbook,v 1.40 2010-01-16 23:48:15 tbox Exp $ -->
<refentry id="man.named-checkzone">
<refentryinfo>
<date>June 13, 2000</date>
@@ -37,6 +37,7 @@
<year>2006</year>
<year>2007</year>
<year>2009</year>
+ <year>2010</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
@@ -69,6 +70,8 @@
<arg><option>-m <replaceable class="parameter">mode</replaceable></option></arg>
<arg><option>-M <replaceable class="parameter">mode</replaceable></option></arg>
<arg><option>-n <replaceable class="parameter">mode</replaceable></option></arg>
+ <arg><option>-o <replaceable class="parameter">filename</replaceable></option></arg>
+ <arg><option>-r <replaceable class="parameter">mode</replaceable></option></arg>
<arg><option>-s <replaceable class="parameter">style</replaceable></option></arg>
<arg><option>-S <replaceable class="parameter">mode</replaceable></option></arg>
<arg><option>-t <replaceable class="parameter">directory</replaceable></option></arg>
@@ -92,7 +95,7 @@
<arg><option>-k <replaceable class="parameter">mode</replaceable></option></arg>
<arg><option>-m <replaceable class="parameter">mode</replaceable></option></arg>
<arg><option>-n <replaceable class="parameter">mode</replaceable></option></arg>
- <arg><option>-o <replaceable class="parameter">filename</replaceable></option></arg>
+ <arg><option>-r <replaceable class="parameter">mode</replaceable></option></arg>
<arg><option>-s <replaceable class="parameter">style</replaceable></option></arg>
<arg><option>-t <replaceable class="parameter">directory</replaceable></option></arg>
<arg><option>-w <replaceable class="parameter">directory</replaceable></option></arg>
@@ -320,6 +323,19 @@
</varlistentry>
<varlistentry>
+ <term>-r <replaceable class="parameter">mode</replaceable></term>
+ <listitem>
+ <para>
+ Check for records that are treated as different by DNSSEC but
+ are semantically equal in plain DNS.
+ Possible modes are <command>"fail"</command>,
+ <command>"warn"</command> (default) and
+ <command>"ignore"</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-s <replaceable class="parameter">style</replaceable></term>
<listitem>
<para>
diff --git a/bin/check/named-checkzone.html b/bin/check/named-checkzone.html
index 24f5c0586dde..e0532af0f590 100644
--- a/bin/check/named-checkzone.html
+++ b/bin/check/named-checkzone.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2002 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named-checkzone.html,v 1.42.334.3 2009-11-11 01:56:22 tbox Exp $ -->
+<!-- $Id: named-checkzone.html,v 1.47 2010-01-17 01:14:02 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,11 +29,11 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">named-checkzone</code> [<code class="option">-d</code>] [<code class="option">-h</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-M <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-S <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
-<div class="cmdsynopsis"><p><code class="command">named-compilezone</code> [<code class="option">-d</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-C <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {<code class="option">-o <em class="replaceable"><code>filename</code></em></code>} {zonename} {filename}</p></div>
+<div class="cmdsynopsis"><p><code class="command">named-checkzone</code> [<code class="option">-d</code>] [<code class="option">-h</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-M <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-r <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-S <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
+<div class="cmdsynopsis"><p><code class="command">named-compilezone</code> [<code class="option">-d</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-C <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-r <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {<code class="option">-o <em class="replaceable"><code>filename</code></em></code>} {zonename} {filename}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543674"></a><h2>DESCRIPTION</h2>
+<a name="id2543694"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named-checkzone</strong></span>
checks the syntax and integrity of a zone file. It performs the
same checks as <span><strong class="command">named</strong></span> does when loading a
@@ -53,7 +53,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543709"></a><h2>OPTIONS</h2>
+<a name="id2543730"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-d</span></dt>
<dd><p>
@@ -177,6 +177,14 @@
write to standard out.
This is mandatory for <span><strong class="command">named-compilezone</strong></span>.
</p></dd>
+<dt><span class="term">-r <em class="replaceable"><code>mode</code></em></span></dt>
+<dd><p>
+ Check for records that are treated as different by DNSSEC but
+ are semantically equal in plain DNS.
+ Possible modes are <span><strong class="command">"fail"</strong></span>,
+ <span><strong class="command">"warn"</strong></span> (default) and
+ <span><strong class="command">"ignore"</strong></span>.
+ </p></dd>
<dt><span class="term">-s <em class="replaceable"><code>style</code></em></span></dt>
<dd><p>
Specify the style of the dumped zone file.
@@ -239,14 +247,14 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544330"></a><h2>RETURN VALUES</h2>
+<a name="id2544377"></a><h2>RETURN VALUES</h2>
<p><span><strong class="command">named-checkzone</strong></span>
returns an exit status of 1 if
errors were detected and 0 otherwise.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544342"></a><h2>SEE ALSO</h2>
+<a name="id2544389"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkconf</span>(8)</span>,
<em class="citetitle">RFC 1035</em>,
@@ -254,7 +262,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544375"></a><h2>AUTHOR</h2>
+<a name="id2544422"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/confgen/Makefile.in b/bin/confgen/Makefile.in
new file mode 100644
index 000000000000..da3587982cd3
--- /dev/null
+++ b/bin/confgen/Makefile.in
@@ -0,0 +1,101 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.8 2009-12-05 23:31:40 each Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/include ${ISC_INCLUDES} ${ISCCC_INCLUDES} \
+ ${ISCCFG_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
+ISCCCLIBS = ../../lib/isccc/libisccc.@A@
+ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
+DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
+BIND9LIBS = ../../lib/bind9/libbind9.@A@
+
+ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
+ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@
+ISCDEPLIBS = ../../lib/isc/libisc.@A@
+DNSDEPLIBS = ../../lib/dns/libdns.@A@
+BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@
+
+RNDCLIBS = ${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS} ${ISCLIBS} @LIBS@
+RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS}
+
+LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
+
+NOSYMLIBS = ${DNSLIBS} ${ISCNOSYMLIBS} @LIBS@
+
+CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
+
+SRCS= rndc-confgen.c ddns-confgen.c
+
+SUBDIRS = unix
+
+TARGETS = rndc-confgen@EXEEXT@ ddns-confgen@EXEEXT@
+
+MANPAGES = rndc-confgen.8 ddns-confgen.8
+
+HTMLPAGES = rndc-confgen.html ddns-confgen.html
+
+MANOBJS = ${MANPAGES} ${HTMLPAGES}
+
+UOBJS = unix/os.@O@
+
+@BIND9_MAKE_RULES@
+
+rndc-confgen.@O@: rndc-confgen.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \
+ -c ${srcdir}/rndc-confgen.c
+
+ddns-confgen.@O@: ddns-confgen.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c ${srcdir}/ddns-confgen.c
+
+rndc-confgen@EXEEXT@: rndc-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS} ${CONFDEPLIBS}
+ export BASEOBJS="rndc-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
+
+ddns-confgen@EXEEXT@: ddns-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS} ${CONFDEPLIBS}
+ export BASEOBJS="ddns-confgen.@O@ util.@O@ keygen.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
+
+doc man:: ${MANOBJS}
+
+docclean manclean maintainer-clean::
+ rm -f ${MANOBJS}
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir}
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8
+
+install:: rndc-confgen@EXEEXT@ ddns-confgen@EXEEXT@ installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc-confgen@EXEEXT@ ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} ddns-confgen@EXEEXT@ ${DESTDIR}${sbindir}
+ ${INSTALL_DATA} ${srcdir}/rndc-confgen.8 ${DESTDIR}${mandir}/man8
+ ${INSTALL_DATA} ${srcdir}/ddns-confgen.8 ${DESTDIR}${mandir}/man8
+
+clean distclean maintainer-clean::
+ rm -f ${TARGETS}
diff --git a/bin/confgen/ddns-confgen.8 b/bin/confgen/ddns-confgen.8
new file mode 100644
index 000000000000..d69af398e614
--- /dev/null
+++ b/bin/confgen/ddns-confgen.8
@@ -0,0 +1,143 @@
+.\" Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: ddns-confgen.8,v 1.10 2009-09-19 01:14:52 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: ddns\-confgen
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: Jan 29, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "DDNS\-CONFGEN" "8" "Jan 29, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+ddns\-confgen \- ddns key generation tool
+.SH "SYNOPSIS"
+.HP 13
+\fBddns\-confgen\fR [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkeyname\fR\fR] [\fB\-r\ \fR\fB\fIrandomfile\fR\fR] [\-s\ \fIname\fR | \-z\ \fIzone\fR] [\fB\-q\fR] [name]
+.SH "DESCRIPTION"
+.PP
+\fBddns\-confgen\fR
+generates a key for use by
+\fBnsupdate\fR
+and
+\fBnamed\fR. It simplifies configuration of dynamic zones by generating a key and providing the
+\fBnsupdate\fR
+and
+\fBnamed.conf\fR
+syntax that will be needed to use it, including an example
+\fBupdate\-policy\fR
+statement.
+.PP
+If a domain name is specified on the command line, it will be used in the name of the generated key and in the sample
+\fBnamed.conf\fR
+syntax. For example,
+\fBddns\-confgen example.com\fR
+would generate a key called "ddns\-key.example.com", and sample
+\fBnamed.conf\fR
+command that could be used in the zone definition for "example.com".
+.PP
+Note that
+\fBnamed\fR
+itself can configure a local DDNS key for use with
+\fBnsupdate \-l\fR.
+\fBddns\-confgen\fR
+is only needed when a more elaborate configuration is required: for instance, if
+\fBnsupdate\fR
+is to be used from a remote system.
+.SH "OPTIONS"
+.PP
+\-a \fIalgorithm\fR
+.RS 4
+Specifies the algorithm to use for the TSIG key. Available choices are: hmac\-md5, hmac\-sha1, hmac\-sha224, hmac\-sha256, hmac\-sha384 and hmac\-sha512. The default is hmac\-sha256.
+.RE
+.PP
+\-h
+.RS 4
+Prints a short summary of the options and arguments to
+\fBddns\-confgen\fR.
+.RE
+.PP
+\-k \fIkeyname\fR
+.RS 4
+Specifies the key name of the DDNS authentication key. The default is
+\fBddns\-key\fR
+when neither the
+\fB\-s\fR
+nor
+\fB\-z\fR
+option is specified; otherwise, the default is
+\fBddns\-key\fR
+as a separate label followed by the argument of the option, e.g.,
+\fBddns\-key.example.com.\fR
+The key name must have the format of a valid domain name, consisting of letters, digits, hyphens and periods.
+.RE
+.PP
+\-q
+.RS 4
+Quiet mode: Print only the key, with no explanatory text or usage examples.
+.RE
+.PP
+\-r \fIrandomfile\fR
+.RS 4
+Specifies a source of random data for generating the authorization. If the operating system does not provide a
+\fI/dev/random\fR
+or equivalent device, the default source of randomness is keyboard input.
+\fIrandomdev\fR
+specifies the name of a character device or file containing random data to be used instead of the default. The special value
+\fIkeyboard\fR
+indicates that keyboard input should be used.
+.RE
+.PP
+\-s \fIname\fR
+.RS 4
+Single host mode: The example
+\fBnamed.conf\fR
+text shows how to set an update policy for the specified
+\fIname\fR
+using the "name" nametype. The default key name is ddns\-key.\fIname\fR. Note that the "self" nametype cannot be used, since the name to be updated may differ from the key name. This option cannot be used with the
+\fB\-z\fR
+option.
+.RE
+.PP
+\-z \fIzone\fR
+.RS 4
+zone mode: The example
+\fBnamed.conf\fR
+text shows how to set an update policy for the specified
+\fIzone\fR
+using the "zonesub" nametype, allowing updates to all subdomain names within that
+\fIzone\fR. This option cannot be used with the
+\fB\-s\fR
+option.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBnsupdate\fR(1),
+\fBnamed.conf\fR(5),
+\fBnamed\fR(8),
+BIND 9 Administrator Reference Manual.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/confgen/ddns-confgen.c b/bin/confgen/ddns-confgen.c
new file mode 100644
index 000000000000..814a5657bb4d
--- /dev/null
+++ b/bin/confgen/ddns-confgen.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ddns-confgen.c,v 1.9 2009-09-29 15:06:05 fdupont Exp $ */
+
+/*! \file */
+
+/**
+ * ddns-confgen generates configuration files for dynamic DNS. It can
+ * be used as a convenient alternative to writing the ddns.key file
+ * and the corresponding key and update-policy statements in named.conf.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <isc/assertions.h>
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/commandline.h>
+#include <isc/entropy.h>
+#include <isc/file.h>
+#include <isc/keyboard.h>
+#include <isc/mem.h>
+#include <isc/net.h>
+#include <isc/print.h>
+#include <isc/result.h>
+#include <isc/string.h>
+#include <isc/time.h>
+#include <isc/util.h>
+
+#include <dns/keyvalues.h>
+#include <dns/name.h>
+
+#include <dst/dst.h>
+#include <confgen/os.h>
+
+#include "util.h"
+#include "keygen.h"
+
+#define DEFAULT_KEYNAME "ddns-key"
+
+static char program[256];
+const char *progname;
+
+isc_boolean_t verbose = ISC_FALSE;
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(int status) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(int status) {
+
+ fprintf(stderr, "\
+Usage:\n\
+ %s [-a alg] [-k keyname] [-r randomfile] [-q] [-s name | -z zone]\n\
+ -a alg: algorithm (default hmac-sha256)\n\
+ -k keyname: name of the key as it will be used in named.conf\n\
+ -r randomfile: source of random data (use \"keyboard\" for key timing)\n\
+ -s name: domain name to be updated using the created key\n\
+ -z zone: name of the zone as it will be used in named.conf\n\
+ -q: quiet mode: print the key, with no explanatory text\n",
+ progname);
+
+ exit (status);
+}
+
+int
+main(int argc, char **argv) {
+ isc_boolean_t show_final_mem = ISC_FALSE;
+ isc_boolean_t quiet = ISC_FALSE;
+ isc_buffer_t key_txtbuffer;
+ char key_txtsecret[256];
+ isc_mem_t *mctx = NULL;
+ isc_result_t result = ISC_R_SUCCESS;
+ const char *randomfile = NULL;
+ const char *keyname = NULL;
+ const char *zone = NULL;
+ const char *self_domain = NULL;
+ char *keybuf = NULL;
+ dns_secalg_t alg = DST_ALG_HMACSHA256;
+ const char *algname = alg_totext(alg);
+ int keysize = 256;
+ int len = 0;
+ int ch;
+
+ result = isc_file_progname(*argv, program, sizeof(program));
+ if (result != ISC_R_SUCCESS)
+ memcpy(program, "ddns-confgen", 13);
+ progname = program;
+
+ isc_commandline_errprint = ISC_FALSE;
+
+ while ((ch = isc_commandline_parse(argc, argv,
+ "a:hk:Mmr:qs:Vy:z:")) != -1) {
+ switch (ch) {
+ case 'a':
+ algname = isc_commandline_argument;
+ alg = alg_fromtext(algname);
+ if (alg == DST_ALG_UNKNOWN)
+ fatal("Unsupported algorithm '%s'", algname);
+ keysize = alg_bits(alg);
+ break;
+ case 'h':
+ usage(0);
+ case 'k':
+ case 'y':
+ keyname = isc_commandline_argument;
+ break;
+ case 'M':
+ isc_mem_debugging = ISC_MEM_DEBUGTRACE;
+ break;
+ case 'm':
+ show_final_mem = ISC_TRUE;
+ break;
+ case 'q':
+ quiet = ISC_TRUE;
+ break;
+ case 'r':
+ randomfile = isc_commandline_argument;
+ break;
+ case 's':
+ self_domain = isc_commandline_argument;
+ break;
+ case 'V':
+ verbose = ISC_TRUE;
+ break;
+ case 'z':
+ zone = isc_commandline_argument;
+ break;
+ case '?':
+ if (isc_commandline_option != '?') {
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
+ usage(1);
+ } else
+ usage(0);
+ break;
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
+ }
+ }
+
+ argc -= isc_commandline_index;
+ argv += isc_commandline_index;
+
+ if (self_domain != NULL && zone != NULL)
+ usage(1); /* -s and -z cannot coexist */
+
+ if (argc > 0)
+ usage(1);
+
+ DO("create memory context", isc_mem_create(0, 0, &mctx));
+
+ if (keyname == NULL) {
+ const char *suffix = NULL;
+
+ keyname = DEFAULT_KEYNAME;
+ if (self_domain != NULL)
+ suffix = self_domain;
+ else if (zone != NULL)
+ suffix = zone;
+ if (suffix != NULL) {
+ len = strlen(keyname) + strlen(suffix) + 2;
+ keybuf = isc_mem_get(mctx, len);
+ if (keybuf == NULL)
+ fatal("failed to allocate memory for keyname");
+ snprintf(keybuf, len, "%s.%s", keyname, suffix);
+ keyname = (const char *) keybuf;
+ }
+ }
+
+ isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret));
+
+ generate_key(mctx, randomfile, alg, keysize, &key_txtbuffer);
+
+
+ if (!quiet)
+ printf("\
+# To activate this key, place the following in named.conf, and\n\
+# in a separate keyfile on the system or systems from which nsupdate\n\
+# will be run:\n");
+
+ printf("\
+key \"%s\" {\n\
+ algorithm %s;\n\
+ secret \"%.*s\";\n\
+};\n",
+ keyname, algname,
+ (int)isc_buffer_usedlength(&key_txtbuffer),
+ (char *)isc_buffer_base(&key_txtbuffer));
+
+ if (!quiet) {
+ if (self_domain != NULL) {
+ printf("\n\
+# Then, in the \"zone\" statement for the zone containing the\n\
+# name \"%s\", place an \"update-policy\" statement\n\
+# like this one, adjusted as needed for your preferred permissions:\n\
+update-policy {\n\
+ grant %s name %s ANY;\n\
+};\n",
+ self_domain, keyname, self_domain);
+ } else if (zone != NULL) {
+ printf("\n\
+# Then, in the \"zone\" definition statement for \"%s\",\n\
+# place an \"update-policy\" statement like this one, adjusted as \n\
+# needed for your preferred permissions:\n\
+update-policy {\n\
+ grant %s zonesub ANY;\n\
+};\n",
+ zone, keyname);
+ } else {
+ printf("\n\
+# Then, in the \"zone\" statement for each zone you wish to dynamically\n\
+# update, place an \"update-policy\" statement granting update permission\n\
+# to this key. For example, the following statement grants this key\n\
+# permission to update any name within the zone:\n\
+update-policy {\n\
+ grant %s zonesub ANY;\n\
+};\n",
+ keyname);
+ }
+
+ printf("\n\
+# After the keyfile has been placed, the following command will\n\
+# execute nsupdate using this key:\n\
+nsupdate -k <keyfile>\n");
+
+ }
+
+ if (keybuf != NULL)
+ isc_mem_put(mctx, keybuf, len);
+
+ if (show_final_mem)
+ isc_mem_stats(mctx, stderr);
+
+ isc_mem_destroy(&mctx);
+
+ return (0);
+}
diff --git a/bin/confgen/ddns-confgen.docbook b/bin/confgen/ddns-confgen.docbook
new file mode 100644
index 000000000000..2b3e1c0556a5
--- /dev/null
+++ b/bin/confgen/ddns-confgen.docbook
@@ -0,0 +1,218 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: ddns-confgen.docbook,v 1.6 2009-09-18 22:08:55 fdupont Exp $ -->
+<refentry id="man.ddns-confgen">
+ <refentryinfo>
+ <date>Jan 29, 2009</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>ddns-confgen</application></refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>ddns-confgen</application></refname>
+ <refpurpose>ddns key generation tool</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2009</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>ddns-confgen</command>
+ <arg><option>-a <replaceable class="parameter">algorithm</replaceable></option></arg>
+ <arg><option>-h</option></arg>
+ <arg><option>-k <replaceable class="parameter">keyname</replaceable></option></arg>
+ <arg><option>-r <replaceable class="parameter">randomfile</replaceable></option></arg>
+ <group>
+ <arg choice="plain">-s <replaceable class="parameter">name</replaceable></arg>
+ <arg choice="plain">-z <replaceable class="parameter">zone</replaceable></arg>
+ </group>
+ <arg><option>-q</option></arg>
+ <arg choice="opt">name</arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para><command>ddns-confgen</command>
+ generates a key for use by <command>nsupdate</command>
+ and <command>named</command>. It simplifies configuration
+ of dynamic zones by generating a key and providing the
+ <command>nsupdate</command> and <command>named.conf</command>
+ syntax that will be needed to use it, including an example
+ <command>update-policy</command> statement.
+ </para>
+
+ <para>
+ If a domain name is specified on the command line, it will
+ be used in the name of the generated key and in the sample
+ <command>named.conf</command> syntax. For example,
+ <command>ddns-confgen example.com</command> would
+ generate a key called "ddns-key.example.com", and sample
+ <command>named.conf</command> command that could be used
+ in the zone definition for "example.com".
+ </para>
+
+ <para>
+ Note that <command>named</command> itself can configure a
+ local DDNS key for use with <command>nsupdate -l</command>.
+ <command>ddns-confgen</command> is only needed when a
+ more elaborate configuration is required: for instance, if
+ <command>nsupdate</command> is to be used from a remote system.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-a <replaceable class="parameter">algorithm</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the algorithm to use for the TSIG key. Available
+ choices are: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256,
+ hmac-sha384 and hmac-sha512. The default is hmac-sha256.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem>
+ <para>
+ Prints a short summary of the options and arguments to
+ <command>ddns-confgen</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-k <replaceable class="parameter">keyname</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the key name of the DDNS authentication key.
+ The default is <constant>ddns-key</constant> when neither
+ the <option>-s</option> nor <option>-z</option> option is
+ specified; otherwise, the default
+ is <constant>ddns-key</constant> as a separate label
+ followed by the argument of the option, e.g.,
+ <constant>ddns-key.example.com.</constant>
+ The key name must have the format of a valid domain name,
+ consisting of letters, digits, hyphens and periods.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-q</term>
+ <listitem>
+ <para>
+ Quiet mode: Print only the key, with no explanatory text or
+ usage examples.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-r <replaceable class="parameter">randomfile</replaceable></term>
+ <listitem>
+ <para>
+ Specifies a source of random data for generating the
+ authorization. If the operating system does not provide a
+ <filename>/dev/random</filename> or equivalent device, the
+ default source of randomness is keyboard input.
+ <filename>randomdev</filename> specifies the name of a
+ character device or file containing random data to be used
+ instead of the default. The special value
+ <filename>keyboard</filename> indicates that keyboard input
+ should be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-s <replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ Single host mode: The example <command>named.conf</command> text
+ shows how to set an update policy for the specified
+ <replaceable class="parameter">name</replaceable>
+ using the "name" nametype.
+ The default key name is
+ ddns-key.<replaceable class="parameter">name</replaceable>.
+ Note that the "self" nametype cannot be used, since
+ the name to be updated may differ from the key name.
+ This option cannot be used with the <option>-z</option> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-z <replaceable class="parameter">zone</replaceable></term>
+ <listitem>
+ <para>
+ zone mode: The example <command>named.conf</command> text
+ shows how to set an update policy for the specified
+ <replaceable class="parameter">zone</replaceable>
+ using the "zonesub" nametype, allowing updates to all subdomain
+ names within
+ that <replaceable class="parameter">zone</replaceable>.
+ This option cannot be used with the <option>-s</option> option.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para><citerefentry>
+ <refentrytitle>nsupdate</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>named.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>named</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citetitle>BIND 9 Administrator Reference Manual</citetitle>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>AUTHOR</title>
+ <para><corpauthor>Internet Systems Consortium</corpauthor>
+ </para>
+ </refsect1>
+
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->
diff --git a/bin/confgen/ddns-confgen.html b/bin/confgen/ddns-confgen.html
new file mode 100644
index 000000000000..17c3f26dccae
--- /dev/null
+++ b/bin/confgen/ddns-confgen.html
@@ -0,0 +1,141 @@
+<!--
+ - Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: ddns-confgen.html,v 1.10 2009-09-19 01:14:52 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>ddns-confgen</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
+<a name="man.ddns-confgen"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">ddns-confgen</span> &#8212; ddns key generation tool</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">ddns-confgen</code> [<code class="option">-a <em class="replaceable"><code>algorithm</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>keyname</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomfile</code></em></code>] [ -s <em class="replaceable"><code>name</code></em> | -z <em class="replaceable"><code>zone</code></em> ] [<code class="option">-q</code>] [name]</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543395"></a><h2>DESCRIPTION</h2>
+<p><span><strong class="command">ddns-confgen</strong></span>
+ generates a key for use by <span><strong class="command">nsupdate</strong></span>
+ and <span><strong class="command">named</strong></span>. It simplifies configuration
+ of dynamic zones by generating a key and providing the
+ <span><strong class="command">nsupdate</strong></span> and <span><strong class="command">named.conf</strong></span>
+ syntax that will be needed to use it, including an example
+ <span><strong class="command">update-policy</strong></span> statement.
+ </p>
+<p>
+ If a domain name is specified on the command line, it will
+ be used in the name of the generated key and in the sample
+ <span><strong class="command">named.conf</strong></span> syntax. For example,
+ <span><strong class="command">ddns-confgen example.com</strong></span> would
+ generate a key called "ddns-key.example.com", and sample
+ <span><strong class="command">named.conf</strong></span> command that could be used
+ in the zone definition for "example.com".
+ </p>
+<p>
+ Note that <span><strong class="command">named</strong></span> itself can configure a
+ local DDNS key for use with <span><strong class="command">nsupdate -l</strong></span>.
+ <span><strong class="command">ddns-confgen</strong></span> is only needed when a
+ more elaborate configuration is required: for instance, if
+ <span><strong class="command">nsupdate</strong></span> is to be used from a remote system.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543454"></a><h2>OPTIONS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
+<dd><p>
+ Specifies the algorithm to use for the TSIG key. Available
+ choices are: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256,
+ hmac-sha384 and hmac-sha512. The default is hmac-sha256.
+ </p></dd>
+<dt><span class="term">-h</span></dt>
+<dd><p>
+ Prints a short summary of the options and arguments to
+ <span><strong class="command">ddns-confgen</strong></span>.
+ </p></dd>
+<dt><span class="term">-k <em class="replaceable"><code>keyname</code></em></span></dt>
+<dd><p>
+ Specifies the key name of the DDNS authentication key.
+ The default is <code class="constant">ddns-key</code> when neither
+ the <code class="option">-s</code> nor <code class="option">-z</code> option is
+ specified; otherwise, the default
+ is <code class="constant">ddns-key</code> as a separate label
+ followed by the argument of the option, e.g.,
+ <code class="constant">ddns-key.example.com.</code>
+ The key name must have the format of a valid domain name,
+ consisting of letters, digits, hyphens and periods.
+ </p></dd>
+<dt><span class="term">-q</span></dt>
+<dd><p>
+ Quiet mode: Print only the key, with no explanatory text or
+ usage examples.
+ </p></dd>
+<dt><span class="term">-r <em class="replaceable"><code>randomfile</code></em></span></dt>
+<dd><p>
+ Specifies a source of random data for generating the
+ authorization. If the operating system does not provide a
+ <code class="filename">/dev/random</code> or equivalent device, the
+ default source of randomness is keyboard input.
+ <code class="filename">randomdev</code> specifies the name of a
+ character device or file containing random data to be used
+ instead of the default. The special value
+ <code class="filename">keyboard</code> indicates that keyboard input
+ should be used.
+ </p></dd>
+<dt><span class="term">-s <em class="replaceable"><code>name</code></em></span></dt>
+<dd><p>
+ Single host mode: The example <span><strong class="command">named.conf</strong></span> text
+ shows how to set an update policy for the specified
+ <em class="replaceable"><code>name</code></em>
+ using the "name" nametype.
+ The default key name is
+ ddns-key.<em class="replaceable"><code>name</code></em>.
+ Note that the "self" nametype cannot be used, since
+ the name to be updated may differ from the key name.
+ This option cannot be used with the <code class="option">-z</code> option.
+ </p></dd>
+<dt><span class="term">-z <em class="replaceable"><code>zone</code></em></span></dt>
+<dd><p>
+ zone mode: The example <span><strong class="command">named.conf</strong></span> text
+ shows how to set an update policy for the specified
+ <em class="replaceable"><code>zone</code></em>
+ using the "zonesub" nametype, allowing updates to all subdomain
+ names within
+ that <em class="replaceable"><code>zone</code></em>.
+ This option cannot be used with the <code class="option">-s</code> option.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543642"></a><h2>SEE ALSO</h2>
+<p><span class="citerefentry"><span class="refentrytitle">nsupdate</span>(1)</span>,
+ <span class="citerefentry"><span class="refentrytitle">named.conf</span>(5)</span>,
+ <span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543681"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div></body>
+</html>
diff --git a/bin/confgen/include/confgen/os.h b/bin/confgen/include/confgen/os.h
new file mode 100644
index 000000000000..bf80f00ef417
--- /dev/null
+++ b/bin/confgen/include/confgen/os.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: os.h,v 1.3 2009-06-11 23:47:55 tbox Exp $ */
+
+/*! \file */
+
+#ifndef RNDC_OS_H
+#define RNDC_OS_H 1
+
+#include <isc/lang.h>
+#include <stdio.h>
+
+ISC_LANG_BEGINDECLS
+
+int set_user(FILE *fd, const char *user);
+/*%<
+ * Set the owner of the file referenced by 'fd' to 'user'.
+ * Returns:
+ * 0 success
+ * -1 insufficient permissions, or 'user' does not exist.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif
diff --git a/bin/confgen/keygen.c b/bin/confgen/keygen.c
new file mode 100644
index 000000000000..c259e7e6a721
--- /dev/null
+++ b/bin/confgen/keygen.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: keygen.c,v 1.4 2009-11-12 14:02:38 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/entropy.h>
+#include <isc/file.h>
+#include <isc/keyboard.h>
+#include <isc/mem.h>
+#include <isc/result.h>
+#include <isc/string.h>
+
+#include <dns/keyvalues.h>
+#include <dns/name.h>
+
+#include <dst/dst.h>
+#include <confgen/os.h>
+
+#include "util.h"
+#include "keygen.h"
+
+/*%
+ * Convert algorithm type to string.
+ */
+const char *
+alg_totext(dns_secalg_t alg) {
+ switch (alg) {
+ case DST_ALG_HMACMD5:
+ return "hmac-md5";
+ case DST_ALG_HMACSHA1:
+ return "hmac-sha1";
+ case DST_ALG_HMACSHA224:
+ return "hmac-sha224";
+ case DST_ALG_HMACSHA256:
+ return "hmac-sha256";
+ case DST_ALG_HMACSHA384:
+ return "hmac-sha384";
+ case DST_ALG_HMACSHA512:
+ return "hmac-sha512";
+ default:
+ return "(unknown)";
+ }
+}
+
+/*%
+ * Convert string to algorithm type.
+ */
+dns_secalg_t
+alg_fromtext(const char *name) {
+ if (strcmp(name, "hmac-md5") == 0)
+ return DST_ALG_HMACMD5;
+ if (strcmp(name, "hmac-sha1") == 0)
+ return DST_ALG_HMACSHA1;
+ if (strcmp(name, "hmac-sha224") == 0)
+ return DST_ALG_HMACSHA224;
+ if (strcmp(name, "hmac-sha256") == 0)
+ return DST_ALG_HMACSHA256;
+ if (strcmp(name, "hmac-sha384") == 0)
+ return DST_ALG_HMACSHA384;
+ if (strcmp(name, "hmac-sha512") == 0)
+ return DST_ALG_HMACSHA512;
+ return DST_ALG_UNKNOWN;
+}
+
+/*%
+ * Return default keysize for a given algorithm type.
+ */
+int
+alg_bits(dns_secalg_t alg) {
+ switch (alg) {
+ case DST_ALG_HMACMD5:
+ return 128;
+ case DST_ALG_HMACSHA1:
+ return 160;
+ case DST_ALG_HMACSHA224:
+ return 224;
+ case DST_ALG_HMACSHA256:
+ return 256;
+ case DST_ALG_HMACSHA384:
+ return 384;
+ case DST_ALG_HMACSHA512:
+ return 512;
+ default:
+ return 0;
+ }
+}
+
+/*%
+ * Generate a key of size 'keysize' using entropy source 'randomfile',
+ * and place it in 'key_txtbuffer'
+ */
+void
+generate_key(isc_mem_t *mctx, const char *randomfile, dns_secalg_t alg,
+ int keysize, isc_buffer_t *key_txtbuffer) {
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_entropysource_t *entropy_source = NULL;
+ int open_keyboard = ISC_ENTROPY_KEYBOARDMAYBE;
+ int entropy_flags = 0;
+ isc_entropy_t *ectx = NULL;
+ isc_buffer_t key_rawbuffer;
+ isc_region_t key_rawregion;
+ char key_rawsecret[64];
+ dst_key_t *key = NULL;
+
+ switch (alg) {
+ case DST_ALG_HMACMD5:
+ if (keysize < 1 || keysize > 512)
+ fatal("keysize %d out of range (must be 1-512)\n",
+ keysize);
+ break;
+ case DST_ALG_HMACSHA256:
+ if (keysize < 1 || keysize > 256)
+ fatal("keysize %d out of range (must be 1-256)\n",
+ keysize);
+ break;
+ default:
+ fatal("unsupported algorithm %d\n", alg);
+ }
+
+
+ DO("create entropy context", isc_entropy_create(mctx, &ectx));
+
+ if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
+ randomfile = NULL;
+ open_keyboard = ISC_ENTROPY_KEYBOARDYES;
+ }
+ DO("start entropy source", isc_entropy_usebestsource(ectx,
+ &entropy_source,
+ randomfile,
+ open_keyboard));
+
+ entropy_flags = ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY;
+
+ DO("initialize dst library", dst_lib_init(mctx, ectx, entropy_flags));
+
+ DO("generate key", dst_key_generate(dns_rootname, alg,
+ keysize, 0, 0,
+ DNS_KEYPROTO_ANY,
+ dns_rdataclass_in, mctx, &key));
+
+ isc_buffer_init(&key_rawbuffer, &key_rawsecret, sizeof(key_rawsecret));
+
+ DO("dump key to buffer", dst_key_tobuffer(key, &key_rawbuffer));
+
+ isc_buffer_usedregion(&key_rawbuffer, &key_rawregion);
+
+ DO("bsse64 encode secret", isc_base64_totext(&key_rawregion, -1, "",
+ key_txtbuffer));
+
+ /*
+ * Shut down the entropy source now so the "stop typing" message
+ * does not muck with the output.
+ */
+ if (entropy_source != NULL)
+ isc_entropy_destroysource(&entropy_source);
+
+ if (key != NULL)
+ dst_key_free(&key);
+
+ isc_entropy_detach(&ectx);
+ dst_lib_destroy();
+}
+
+/*%
+ * Write a key file to 'keyfile'. If 'user' is non-NULL,
+ * make that user the owner of the file. The key will have
+ * the name 'keyname' and the secret in the buffer 'secret'.
+ */
+void
+write_key_file(const char *keyfile, const char *user,
+ const char *keyname, isc_buffer_t *secret,
+ dns_secalg_t alg) {
+ isc_result_t result;
+ const char *algname = alg_totext(alg);
+ FILE *fd = NULL;
+
+ DO("create keyfile", isc_file_safecreate(keyfile, &fd));
+
+ if (user != NULL) {
+ if (set_user(fd, user) == -1)
+ fatal("unable to set file owner\n");
+ }
+
+ fprintf(fd, "key \"%s\" {\n\talgorithm %s;\n"
+ "\tsecret \"%.*s\";\n};\n",
+ keyname, algname,
+ (int)isc_buffer_usedlength(secret),
+ (char *)isc_buffer_base(secret));
+ fflush(fd);
+ if (ferror(fd))
+ fatal("write to %s failed\n", keyfile);
+ if (fclose(fd))
+ fatal("fclose(%s) failed\n", keyfile);
+ fprintf(stderr, "wrote key file \"%s\"\n", keyfile);
+}
+
diff --git a/bin/confgen/keygen.h b/bin/confgen/keygen.h
new file mode 100644
index 000000000000..cea25dd4f92a
--- /dev/null
+++ b/bin/confgen/keygen.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: keygen.h,v 1.3 2009-06-11 23:47:55 tbox Exp $ */
+
+#ifndef RNDC_KEYGEN_H
+#define RNDC_KEYGEN_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+void generate_key(isc_mem_t *mctx, const char *randomfile, dns_secalg_t alg,
+ int keysize, isc_buffer_t *key_txtbuffer);
+
+void write_key_file(const char *keyfile, const char *user,
+ const char *keyname, isc_buffer_t *secret,
+ dns_secalg_t alg);
+
+const char *alg_totext(dns_secalg_t alg);
+dns_secalg_t alg_fromtext(const char *name);
+int alg_bits(dns_secalg_t alg);
+
+ISC_LANG_ENDDECLS
+
+#endif /* RNDC_KEYGEN_H */
diff --git a/bin/rndc/rndc-confgen.8 b/bin/confgen/rndc-confgen.8
index db45df4dd7c3..a1b3ae86b735 100644
--- a/bin/rndc/rndc-confgen.8
+++ b/bin/confgen/rndc-confgen.8
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2001, 2003 Internet Software Consortium.
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: rndc-confgen.8,v 1.20.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: rndc-confgen.8,v 1.7 2009-07-11 01:12:45 tbox Exp $
.\"
.hy 0
.ad l
@@ -205,7 +205,7 @@ BIND 9 Administrator Reference Manual.
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
.br
Copyright \(co 2001, 2003 Internet Software Consortium.
.br
diff --git a/bin/rndc/rndc-confgen.c b/bin/confgen/rndc-confgen.c
index 1cb0a0a7c9b9..766e3b49444e 100644
--- a/bin/rndc/rndc-confgen.c
+++ b/bin/confgen/rndc-confgen.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rndc-confgen.c,v 1.26 2008-10-15 23:47:31 tbox Exp $ */
+/* $Id: rndc-confgen.c,v 1.5 2009-09-29 15:06:05 fdupont Exp $ */
/*! \file */
@@ -52,9 +52,10 @@
#include <dns/name.h>
#include <dst/dst.h>
-#include <rndc/os.h>
+#include <confgen/os.h>
#include "util.h"
+#include "keygen.h"
#define DEFAULT_KEYLENGTH 128 /*% Bits. */
#define DEFAULT_KEYNAME "rndc-key"
@@ -68,6 +69,9 @@ isc_boolean_t verbose = ISC_FALSE;
const char *keyfile, *keydef;
+ISC_PLATFORM_NORETURN_PRE static void
+usage(int status) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(int status) {
@@ -75,72 +79,36 @@ usage(int status) {
Usage:\n\
%s [-a] [-b bits] [-c keyfile] [-k keyname] [-p port] [-r randomfile] \
[-s addr] [-t chrootdir] [-u user]\n\
- -a: generate just the key clause and write it to keyfile (%s)\n\
- -b bits: from 1 through 512, default %d; total length of the secret\n\
- -c keyfile: specify an alternate key file (requires -a)\n\
- -k keyname: the name as it will be used in named.conf and rndc.conf\n\
- -p port: the port named will listen on and rndc will connect to\n\
- -r randomfile: a file containing random data\n\
- -s addr: the address to which rndc should connect\n\
- -t chrootdir: write a keyfile in chrootdir as well (requires -a)\n\
- -u user: set the keyfile owner to \"user\" (requires -a)\n",
- progname, keydef, DEFAULT_KEYLENGTH);
+ -a: generate just the key clause and write it to keyfile (%s)\n\
+ -b bits: from 1 through 512, default %d; total length of the secret\n\
+ -c keyfile: specify an alternate key file (requires -a)\n\
+ -k keyname: the name as it will be used in named.conf and rndc.conf\n\
+ -p port: the port named will listen on and rndc will connect to\n\
+ -r randomfile: source of random data (use \"keyboard\" for key timing)\n\
+ -s addr: the address to which rndc should connect\n\
+ -t chrootdir: write a keyfile in chrootdir as well (requires -a)\n\
+ -u user: set the keyfile owner to \"user\" (requires -a)\n",
+ progname, keydef, DEFAULT_KEYLENGTH);
exit (status);
}
-/*%
- * Write an rndc.key file to 'keyfile'. If 'user' is non-NULL,
- * make that user the owner of the file. The key will have
- * the name 'keyname' and the secret in the buffer 'secret'.
- */
-static void
-write_key_file(const char *keyfile, const char *user,
- const char *keyname, isc_buffer_t *secret )
-{
- FILE *fd;
-
- fd = safe_create(keyfile);
- if (fd == NULL)
- fatal( "unable to create \"%s\"\n", keyfile);
- if (user != NULL) {
- if (set_user(fd, user) == -1)
- fatal("unable to set file owner\n");
- }
- fprintf(fd, "key \"%s\" {\n\talgorithm hmac-md5;\n"
- "\tsecret \"%.*s\";\n};\n", keyname,
- (int)isc_buffer_usedlength(secret),
- (char *)isc_buffer_base(secret));
- fflush(fd);
- if (ferror(fd))
- fatal("write to %s failed\n", keyfile);
- if (fclose(fd))
- fatal("fclose(%s) failed\n", keyfile);
- fprintf(stderr, "wrote key file \"%s\"\n", keyfile);
-}
-
int
main(int argc, char **argv) {
isc_boolean_t show_final_mem = ISC_FALSE;
- isc_buffer_t key_rawbuffer;
isc_buffer_t key_txtbuffer;
- isc_region_t key_rawregion;
+ char key_txtsecret[256];
isc_mem_t *mctx = NULL;
- isc_entropy_t *ectx = NULL;
- isc_entropysource_t *entropy_source = NULL;
isc_result_t result = ISC_R_SUCCESS;
- dst_key_t *key = NULL;
const char *keyname = NULL;
const char *randomfile = NULL;
const char *serveraddr = NULL;
- char key_rawsecret[64];
- char key_txtsecret[256];
+ dns_secalg_t alg = DST_ALG_HMACMD5;
+ const char *algname = alg_totext(alg);
char *p;
int ch;
int port;
int keysize;
- int entropy_flags = 0;
- int open_keyboard = ISC_ENTROPY_KEYBOARDMAYBE;
struct in_addr addr4_dummy;
struct in6_addr addr6_dummy;
char *chrootdir = NULL;
@@ -237,53 +205,13 @@ main(int argc, char **argv) {
usage(1);
DO("create memory context", isc_mem_create(0, 0, &mctx));
-
- DO("create entropy context", isc_entropy_create(mctx, &ectx));
-
- if (randomfile != NULL && strcmp(randomfile, "keyboard") == 0) {
- randomfile = NULL;
- open_keyboard = ISC_ENTROPY_KEYBOARDYES;
- }
- DO("start entropy source", isc_entropy_usebestsource(ectx,
- &entropy_source,
- randomfile,
- open_keyboard));
-
- entropy_flags = ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY;
-
- DO("initialize dst library", dst_lib_init(mctx, ectx, entropy_flags));
-
- DO("generate key", dst_key_generate(dns_rootname, DST_ALG_HMACMD5,
- keysize, 0, 0,
- DNS_KEYPROTO_ANY,
- dns_rdataclass_in, mctx, &key));
-
- isc_buffer_init(&key_rawbuffer, &key_rawsecret, sizeof(key_rawsecret));
-
- DO("dump key to buffer", dst_key_tobuffer(key, &key_rawbuffer));
-
isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret));
- isc_buffer_usedregion(&key_rawbuffer, &key_rawregion);
-
- DO("bsse64 encode secret", isc_base64_totext(&key_rawregion, -1, "",
- &key_txtbuffer));
-
- /*
- * Shut down the entropy source now so the "stop typing" message
- * does not muck with the output.
- */
- if (entropy_source != NULL)
- isc_entropy_destroysource(&entropy_source);
-
- if (key != NULL)
- dst_key_free(&key);
- isc_entropy_detach(&ectx);
- dst_lib_destroy();
+ generate_key(mctx, randomfile, alg, keysize, &key_txtbuffer);
if (keyonly) {
write_key_file(keyfile, chrootdir == NULL ? user : NULL,
- keyname, &key_txtbuffer);
+ keyname, &key_txtbuffer, alg);
if (chrootdir != NULL) {
char *buf;
@@ -294,14 +222,14 @@ main(int argc, char **argv) {
snprintf(buf, len, "%s%s%s", chrootdir,
(*keyfile != '/') ? "/" : "", keyfile);
- write_key_file(buf, user, keyname, &key_txtbuffer);
+ write_key_file(buf, user, keyname, &key_txtbuffer, alg);
isc_mem_put(mctx, buf, len);
}
} else {
printf("\
# Start of rndc.conf\n\
key \"%s\" {\n\
- algorithm hmac-md5;\n\
+ algorithm %s;\n\
secret \"%.*s\";\n\
};\n\
\n\
@@ -314,7 +242,7 @@ options {\n\
\n\
# Use with the following in named.conf, adjusting the allow list as needed:\n\
# key \"%s\" {\n\
-# algorithm hmac-md5;\n\
+# algorithm %s;\n\
# secret \"%.*s\";\n\
# };\n\
# \n\
@@ -323,11 +251,11 @@ options {\n\
# allow { %s; } keys { \"%s\"; };\n\
# };\n\
# End of named.conf\n",
- keyname,
+ keyname, algname,
(int)isc_buffer_usedlength(&key_txtbuffer),
(char *)isc_buffer_base(&key_txtbuffer),
keyname, serveraddr, port,
- keyname,
+ keyname, algname,
(int)isc_buffer_usedlength(&key_txtbuffer),
(char *)isc_buffer_base(&key_txtbuffer),
serveraddr, port, serveraddr, keyname);
diff --git a/bin/rndc/rndc-confgen.docbook b/bin/confgen/rndc-confgen.docbook
index f71dd9f94c7b..d43fcfbe8aa4 100644
--- a/bin/rndc/rndc-confgen.docbook
+++ b/bin/confgen/rndc-confgen.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2001, 2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: rndc-confgen.docbook,v 1.13 2007-06-18 23:47:25 tbox Exp $ -->
+<!-- $Id: rndc-confgen.docbook,v 1.4 2009-06-15 23:47:59 tbox Exp $ -->
<refentry id="man.rndc-confgen">
<refentryinfo>
<date>Aug 27, 2001</date>
@@ -40,6 +40,7 @@
<year>2004</year>
<year>2005</year>
<year>2007</year>
+ <year>2009</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
diff --git a/bin/rndc/rndc-confgen.html b/bin/confgen/rndc-confgen.html
index 6ef10737ae43..82a712091614 100644
--- a/bin/rndc/rndc-confgen.html
+++ b/bin/confgen/rndc-confgen.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2001, 2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: rndc-confgen.html,v 1.25.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: rndc-confgen.html,v 1.7 2009-07-11 01:12:45 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -32,7 +32,7 @@
<div class="cmdsynopsis"><p><code class="command">rndc-confgen</code> [<code class="option">-a</code>] [<code class="option">-b <em class="replaceable"><code>keysize</code></em></code>] [<code class="option">-c <em class="replaceable"><code>keyfile</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>keyname</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomfile</code></em></code>] [<code class="option">-s <em class="replaceable"><code>address</code></em></code>] [<code class="option">-t <em class="replaceable"><code>chrootdir</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543429"></a><h2>DESCRIPTION</h2>
+<a name="id2543432"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">rndc-confgen</strong></span>
generates configuration files
for <span><strong class="command">rndc</strong></span>. It can be used as a
@@ -48,7 +48,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543474"></a><h2>OPTIONS</h2>
+<a name="id2543477"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd>
@@ -155,7 +155,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543787"></a><h2>EXAMPLES</h2>
+<a name="id2543790"></a><h2>EXAMPLES</h2>
<p>
To allow <span><strong class="command">rndc</strong></span> to be used with
no manual configuration, run
@@ -172,7 +172,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543829"></a><h2>SEE ALSO</h2>
+<a name="id2543832"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc.conf</span>(5)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
@@ -180,7 +180,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543867"></a><h2>AUTHOR</h2>
+<a name="id2543870"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/rndc/unix/Makefile.in b/bin/confgen/unix/Makefile.in
index e503db3b0b27..1785e0d0f4de 100644
--- a/bin/rndc/unix/Makefile.in
+++ b/bin/confgen/unix/Makefile.in
@@ -1,5 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
-# Copyright (C) 2001 Internet Software Consortium.
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -13,7 +12,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.5 2007-06-19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.3 2009-06-11 23:47:55 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/bin/rndc/unix/os.c b/bin/confgen/unix/os.c
index e9ece1ba776c..e439a5182648 100644
--- a/bin/rndc/unix/os.c
+++ b/bin/confgen/unix/os.c
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2001 Internet Software Consortium.
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -15,13 +14,13 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.c,v 1.10 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: os.c,v 1.3 2009-06-11 23:47:55 tbox Exp $ */
/*! \file */
#include <config.h>
-#include <rndc/os.h>
+#include <confgen/os.h>
#include <fcntl.h>
#include <unistd.h>
@@ -42,29 +41,3 @@ set_user(FILE *fd, const char *user) {
}
return (fchown(fileno(fd), pw->pw_uid, -1));
}
-
-FILE *
-safe_create(const char *filename) {
- int fd;
- FILE *f;
- struct stat sb;
- int flags = O_WRONLY;
-
- if (stat(filename, &sb) == -1) {
- if (errno != ENOENT)
- return (NULL);
- flags = O_WRONLY | O_CREAT | O_EXCL;
- } else if ((sb.st_mode & S_IFREG) == 0) {
- errno = EOPNOTSUPP;
- return (NULL);
- } else
- flags = O_WRONLY | O_TRUNC;
-
- fd = open(filename, flags, S_IRUSR | S_IWUSR);
- if (fd == -1)
- return (NULL);
- f = fdopen(fd, "w");
- if (f == NULL)
- close(fd);
- return (f);
-}
diff --git a/bin/confgen/util.c b/bin/confgen/util.c
new file mode 100644
index 000000000000..158a8d355818
--- /dev/null
+++ b/bin/confgen/util.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: util.c,v 1.3 2009-06-11 23:47:55 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <isc/boolean.h>
+
+#include "util.h"
+
+extern isc_boolean_t verbose;
+extern const char *progname;
+
+void
+notify(const char *fmt, ...) {
+ va_list ap;
+
+ if (verbose) {
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fputs("\n", stderr);
+ }
+}
+
+void
+fatal(const char *format, ...) {
+ va_list args;
+
+ fprintf(stderr, "%s: ", progname);
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ exit(1);
+}
diff --git a/bin/confgen/util.h b/bin/confgen/util.h
new file mode 100644
index 000000000000..651b6e558cf2
--- /dev/null
+++ b/bin/confgen/util.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: util.h,v 1.4 2009-09-29 15:06:05 fdupont Exp $ */
+
+#ifndef RNDC_UTIL_H
+#define RNDC_UTIL_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+#include <isc/formatcheck.h>
+
+#define NS_CONTROL_PORT 953
+
+#undef DO
+#define DO(name, function) \
+ do { \
+ result = function; \
+ if (result != ISC_R_SUCCESS) \
+ fatal("%s: %s", name, isc_result_totext(result)); \
+ else \
+ notify("%s", name); \
+ } while (0)
+
+ISC_LANG_BEGINDECLS
+
+void
+notify(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2);
+
+ISC_PLATFORM_NORETURN_PRE void
+fatal(const char *format, ...)
+ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
+
+ISC_LANG_ENDDECLS
+
+#endif /* RNDC_UTIL_H */
diff --git a/bin/dig/Makefile.in b/bin/dig/Makefile.in
index ad20553d532b..bebef6f45d34 100644
--- a/bin/dig/Makefile.in
+++ b/bin/dig/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.41 2007-06-19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.47 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -24,7 +24,7 @@ top_srcdir = @top_srcdir@
@BIND9_MAKE_INCLUDES@
CINCLUDES = -I${srcdir}/include ${DNS_INCLUDES} ${BIND9_INCLUDES} \
- ${ISC_INCLUDES} ${LWRES_INCLUDES}
+ ${ISC_INCLUDES} ${LWRES_INCLUDES} ${ISCCFG_INCLUDES}
CDEFINES = -DVERSION=\"${VERSION}\"
CWARNINGS =
@@ -33,6 +33,7 @@ ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
LWRESLIBS = ../../lib/lwres/liblwres.@A@
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
@@ -44,8 +45,11 @@ LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} \
${LWRESDEPLIBS}
-LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCLIBS} \
- ${ISCCFGLIBS} @IDNLIBS@ @LIBS@
+LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \
+ ${ISCLIBS} @IDNLIBS@ @LIBS@
+
+NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \
+ ${ISCNOSYMLIBS} @IDNLIBS@ @LIBS@
SUBDIRS =
@@ -66,16 +70,16 @@ MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
dig@EXEEXT@: dig.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dig.@O@ dighost.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="dig.@O@ dighost.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
host@EXEEXT@: host.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- host.@O@ dighost.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="host.@O@ dighost.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
nslookup@EXEEXT@: nslookup.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- nslookup.@O@ dighost.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="nslookup.@O@ dighost.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/dig/dig.1 b/bin/dig/dig.1
index 93f90b2ea84c..87d5045701ce 100644
--- a/bin/dig/dig.1
+++ b/bin/dig/dig.1
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000-2003 Internet Software Consortium.
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dig.1,v 1.50.44.3 2009-07-11 01:55:20 tbox Exp $
+.\" $Id: dig.1,v 1.54 2010-03-05 01:14:15 tbox Exp $
.\"
.hy 0
.ad l
@@ -455,6 +455,11 @@ Print records like the SOA records in a verbose multi\-line format with human\-r
output.
.RE
.PP
+\fB+[no]onesoa\fR
+.RS 4
+Print only one (starting) SOA record when performing an AXFR. The default is to print both the starting and ending SOA records.
+.RE
+.PP
\fB+[no]fail\fR
.RS 4
Do not try the next server if you receive a SERVFAIL. The default is to not try the next server which is the reverse of normal stub resolver behavior.
@@ -562,7 +567,7 @@ RFC1035.
.PP
There are probably too many query options.
.SH "COPYRIGHT"
-Copyright \(co 2004\-2009 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2004\-2010 Internet Systems Consortium, Inc. ("ISC")
.br
Copyright \(co 2000\-2003 Internet Software Consortium.
.br
diff --git a/bin/dig/dig.c b/bin/dig/dig.c
index 7de934bb50d2..a3143c93d273 100644
--- a/bin/dig/dig.c
+++ b/bin/dig/dig.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dig.c,v 1.225.26.7 2010-05-13 00:43:37 marka Exp $ */
+/* $Id: dig.c,v 1.237 2010-05-13 00:40:46 marka Exp $ */
/*! \file */
@@ -68,7 +68,8 @@ static char domainopt[DNS_NAME_MAXTEXT];
static isc_boolean_t short_form = ISC_FALSE, printcmd = ISC_TRUE,
ip6_int = ISC_FALSE, plusquest = ISC_FALSE, pluscomm = ISC_FALSE,
- multiline = ISC_FALSE, nottl = ISC_FALSE, noclass = ISC_FALSE;
+ multiline = ISC_FALSE, nottl = ISC_FALSE, noclass = ISC_FALSE,
+ onesoa = ISC_FALSE;
/*% opcode text */
static const char * const opcodetext[] = {
@@ -138,6 +139,9 @@ print_usage(FILE *fp) {
" [ host [@local-server] {local-d-opt} [...]]\n", fp);
}
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(void) {
print_usage(stderr);
@@ -222,6 +226,7 @@ help(void) {
#endif
#endif
" +[no]multiline (Print records in an expanded format)\n"
+" +[no]onesoa (AXFR prints only one soa record)\n"
" global d-opts and servers (before host name) affect all queries.\n"
" local d-opts and servers (after host name) affect only that lookup.\n"
" -h (print help and exit)\n"
@@ -468,6 +473,9 @@ printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) {
flags |= DNS_MESSAGETEXTFLAG_NOHEADERS;
flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS;
}
+ if (onesoa && query->lookup->rdtype == dns_rdatatype_axfr)
+ flags |= (query->msg_count == 0) ? DNS_MESSAGETEXTFLAG_ONESOA :
+ DNS_MESSAGETEXTFLAG_OMITSOA;
if (!query->lookup->comments)
flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS;
@@ -673,19 +681,6 @@ printgreeting(int argc, char **argv, dig_lookup_t *lookup) {
}
}
-static isc_uint32_t
-parse_uint(char *arg, const char *desc, isc_uint32_t max) {
- isc_result_t result;
- isc_uint32_t tmp;
-
- result = isc_parse_uint32(&tmp, arg, 10);
- if (result == ISC_R_SUCCESS && tmp > max)
- result = ISC_R_RANGE;
- if (result != ISC_R_SUCCESS)
- fatal("%s '%s': %s", desc, arg, isc_result_totext(result));
- return (tmp);
-}
-
/*%
* We're not using isc_commandline_parse() here since the command line
* syntax of dig is quite a bit different from that which can be described
@@ -697,8 +692,10 @@ static void
plus_option(char *option, isc_boolean_t is_batchfile,
dig_lookup_t *lookup)
{
+ isc_result_t result;
char option_store[256];
char *cmd, *value, *ptr;
+ isc_uint32_t num;
isc_boolean_t state = ISC_TRUE;
#ifdef DIG_SIGCHASE
size_t n;
@@ -746,6 +743,7 @@ plus_option(char *option, isc_boolean_t is_batchfile,
lookup->section_additional = state;
break;
case 'f': /* adflag */
+ case '\0': /* +ad is a synonym for +adflag */
FULLCHECK("adflag");
lookup->adflag = state;
break;
@@ -787,8 +785,11 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto need_value;
if (!state)
goto invalid_option;
- lookup->udpsize = (isc_uint16_t) parse_uint(value,
- "buffer size", COMMSIZE);
+ result = parse_uint(&num, value, COMMSIZE,
+ "buffer size");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse buffer size");
+ lookup->udpsize = num;
break;
default:
goto invalid_option;
@@ -797,8 +798,15 @@ plus_option(char *option, isc_boolean_t is_batchfile,
case 'c':
switch (cmd[1]) {
case 'd':/* cdflag */
- FULLCHECK("cdflag");
- lookup->cdflag = state;
+ switch (cmd[2]) {
+ case 'f': /* cdflag */
+ case '\0': /* +cd is a synonym for +cdflag */
+ FULLCHECK("cdflag");
+ lookup->cdflag = state;
+ break;
+ default:
+ goto invalid_option;
+ }
break;
case 'l': /* cl */
FULLCHECK("cl");
@@ -853,7 +861,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
}
if (value == NULL)
goto need_value;
- lookup->edns = (isc_int16_t) parse_uint(value, "edns", 255);
+ result = parse_uint(&num, value, 255, "edns");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse edns");
+ lookup->edns = num;
break;
case 'f': /* fail */
FULLCHECK("fail");
@@ -883,7 +894,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto need_value;
if (!state)
goto invalid_option;
- ndots = parse_uint(value, "ndots", MAXNDOTS);
+ result = parse_uint(&num, value, MAXNDOTS, "ndots");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse ndots");
+ ndots = num;
break;
case 's':
switch (cmd[2]) {
@@ -918,6 +932,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto invalid_option;
}
break;
+ case 'o':
+ FULLCHECK("onesoa");
+ onesoa = state;
+ break;
case 'q':
switch (cmd[1]) {
case 'r': /* qr */
@@ -948,8 +966,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto need_value;
if (!state)
goto invalid_option;
- lookup->retries = parse_uint(value, "retries",
- MAXTRIES - 1);
+ result = parse_uint(&lookup->retries, value,
+ MAXTRIES - 1, "retries");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse retries");
lookup->retries++;
break;
default:
@@ -1025,7 +1045,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto need_value;
if (!state)
goto invalid_option;
- timeout = parse_uint(value, "timeout", MAXTIMEOUT);
+ result = parse_uint(&timeout, value, MAXTIMEOUT,
+ "timeout");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse timeout");
if (timeout == 0)
timeout = 1;
break;
@@ -1058,8 +1081,10 @@ plus_option(char *option, isc_boolean_t is_batchfile,
goto need_value;
if (!state)
goto invalid_option;
- lookup->retries = parse_uint(value, "tries",
- MAXTRIES);
+ result = parse_uint(&lookup->retries, value,
+ MAXTRIES, "tries");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse tries");
if (lookup->retries == 0)
lookup->retries = 1;
break;
@@ -1125,6 +1150,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
struct in6_addr in6;
in_port_t srcport;
char *hash, *cmd;
+ isc_uint32_t num;
while (strpbrk(option, single_dash_opts) == &option[0]) {
/*
@@ -1140,6 +1166,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
have_ipv6 = ISC_FALSE;
} else {
fatal("can't find IPv4 networking");
+ /* NOTREACHED */
return (ISC_FALSE);
}
break;
@@ -1149,6 +1176,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
have_ipv4 = ISC_FALSE;
} else {
fatal("can't find IPv6 networking");
+ /* NOTREACHED */
return (ISC_FALSE);
}
break;
@@ -1199,9 +1227,11 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
case 'b':
hash = strchr(value, '#');
if (hash != NULL) {
- srcport = (in_port_t)
- parse_uint(hash + 1,
- "port number", MAXPORT);
+ result = parse_uint(&num, hash + 1, MAXPORT,
+ "port number");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse port number");
+ srcport = num;
*hash = '\0';
} else
srcport = 0;
@@ -1245,7 +1275,10 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
keyfile[sizeof(keyfile)-1]=0;
return (value_from_next);
case 'p':
- port = (in_port_t) parse_uint(value, "port number", MAXPORT);
+ result = parse_uint(&num, value, MAXPORT, "port number");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse port number");
+ port = num;
return (value_from_next);
case 'q':
if (!config_only) {
@@ -1288,11 +1321,14 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
"extra type option\n");
}
if (rdtype == dns_rdatatype_ixfr) {
+ isc_uint32_t serial;
(*lookup)->rdtype = dns_rdatatype_ixfr;
(*lookup)->rdtypeset = ISC_TRUE;
- (*lookup)->ixfr_serial =
- parse_uint(&value[5], "serial number",
- MAXSERIAL);
+ result = parse_uint(&serial, &value[5],
+ MAXSERIAL, "serial number");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse serial number");
+ (*lookup)->ixfr_serial = serial;
(*lookup)->section_question = plusquest;
(*lookup)->comments = pluscomm;
(*lookup)->tcp_mode = ISC_TRUE;
@@ -1320,65 +1356,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
usage();
ptr3 = next_token(&value,":"); /* secret or NULL */
if (ptr3 != NULL) {
- if (strcasecmp(ptr, "hmac-md5") == 0) {
- hmacname = DNS_TSIG_HMACMD5_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-md5-", 9) == 0) {
- hmacname = DNS_TSIG_HMACMD5_NAME;
- digestbits = parse_uint(&ptr[9],
- "digest-bits [0..128]",
- 128);
- digestbits = (digestbits + 7) & ~0x7U;
- } else if (strcasecmp(ptr, "hmac-sha1") == 0) {
- hmacname = DNS_TSIG_HMACSHA1_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-sha1-", 10) == 0) {
- hmacname = DNS_TSIG_HMACSHA1_NAME;
- digestbits = parse_uint(&ptr[10],
- "digest-bits [0..160]",
- 160);
- digestbits = (digestbits + 7) & ~0x7U;
- } else if (strcasecmp(ptr, "hmac-sha224") == 0) {
- hmacname = DNS_TSIG_HMACSHA224_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-sha224-", 12) == 0) {
- hmacname = DNS_TSIG_HMACSHA224_NAME;
- digestbits = parse_uint(&ptr[12],
- "digest-bits [0..224]",
- 224);
- digestbits = (digestbits + 7) & ~0x7U;
- } else if (strcasecmp(ptr, "hmac-sha256") == 0) {
- hmacname = DNS_TSIG_HMACSHA256_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-sha256-", 12) == 0) {
- hmacname = DNS_TSIG_HMACSHA256_NAME;
- digestbits = parse_uint(&ptr[12],
- "digest-bits [0..256]",
- 256);
- digestbits = (digestbits + 7) & ~0x7U;
- } else if (strcasecmp(ptr, "hmac-sha384") == 0) {
- hmacname = DNS_TSIG_HMACSHA384_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-sha384-", 12) == 0) {
- hmacname = DNS_TSIG_HMACSHA384_NAME;
- digestbits = parse_uint(&ptr[12],
- "digest-bits [0..384]",
- 384);
- digestbits = (digestbits + 7) & ~0x7U;
- } else if (strcasecmp(ptr, "hmac-sha512") == 0) {
- hmacname = DNS_TSIG_HMACSHA512_NAME;
- digestbits = 0;
- } else if (strncasecmp(ptr, "hmac-sha512-", 12) == 0) {
- hmacname = DNS_TSIG_HMACSHA512_NAME;
- digestbits = parse_uint(&ptr[12],
- "digest-bits [0..512]",
- 512);
- digestbits = (digestbits + 7) & ~0x7U;
- } else {
- fprintf(stderr, ";; Warning, ignoring "
- "invalid TSIG algorithm %s\n", ptr);
- return (value_from_next);
- }
+ parse_hmac(ptr);
ptr = ptr2;
ptr2 = ptr3;
} else {
@@ -1422,6 +1400,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
fprintf(stderr, "Invalid option: -%s\n", option);
usage();
}
+ /* NOTREACHED */
return (ISC_FALSE);
}
@@ -1626,13 +1605,18 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only,
"extra type option\n");
}
if (rdtype == dns_rdatatype_ixfr) {
+ isc_uint32_t serial;
lookup->rdtype =
dns_rdatatype_ixfr;
lookup->rdtypeset = ISC_TRUE;
- lookup->ixfr_serial =
- parse_uint(&rv[0][5],
- "serial number",
- MAXSERIAL);
+ result = parse_uint(&serial,
+ &rv[0][5],
+ MAXSERIAL,
+ "serial number");
+ if (result != ISC_R_SUCCESS)
+ fatal("Couldn't parse "
+ "serial number");
+ lookup->ixfr_serial = serial;
lookup->section_question =
plusquest;
lookup->comments = pluscomm;
diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook
index d8e358644c9c..19e2ca2afbf3 100644
--- a/bin/dig/dig.docbook
+++ b/bin/dig/dig.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dig.docbook,v 1.42.44.3 2009-02-02 04:42:48 marka Exp $ -->
+<!-- $Id: dig.docbook,v 1.47 2010-03-04 23:50:34 tbox Exp $ -->
<refentry id="man.dig">
<refentryinfo>
@@ -44,6 +44,7 @@
<year>2007</year>
<year>2008</year>
<year>2009</year>
+ <year>2010</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
@@ -766,6 +767,17 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>+[no]onesoa</option></term>
+ <listitem>
+ <para>
+ Print only one (starting) SOA record when performing
+ an AXFR. The default is to print both the starting and
+ ending SOA records.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>+[no]fail</option></term>
<listitem>
diff --git a/bin/dig/dig.html b/bin/dig/dig.html
index 17fd5bb3bc75..c9ce8f0e254c 100644
--- a/bin/dig/dig.html
+++ b/bin/dig/dig.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dig.html,v 1.45.44.3 2009-07-11 01:55:20 tbox Exp $ -->
+<!-- $Id: dig.html,v 1.49 2010-03-05 01:14:15 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -34,7 +34,7 @@
<div class="cmdsynopsis"><p><code class="command">dig</code> [global-queryopt...] [query...]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543518"></a><h2>DESCRIPTION</h2>
+<a name="id2543522"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dig</strong></span>
(domain information groper) is a flexible tool
for interrogating DNS name servers. It performs DNS lookups and
@@ -80,7 +80,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543592"></a><h2>SIMPLE USAGE</h2>
+<a name="id2543595"></a><h2>SIMPLE USAGE</h2>
<p>
A typical invocation of <span><strong class="command">dig</strong></span> looks like:
</p>
@@ -126,7 +126,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543683"></a><h2>OPTIONS</h2>
+<a name="id2543686"></a><h2>OPTIONS</h2>
<p>
The <code class="option">-b</code> option sets the source IP address of the query
to <em class="parameter"><code>address</code></em>. This must be a valid
@@ -230,7 +230,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544032"></a><h2>QUERY OPTIONS</h2>
+<a name="id2544035"></a><h2>QUERY OPTIONS</h2>
<p><span><strong class="command">dig</strong></span>
provides a number of query options which affect
the way in which lookups are made and the results displayed. Some of
@@ -499,6 +499,12 @@
each record on a single line, to facilitate machine parsing
of the <span><strong class="command">dig</strong></span> output.
</p></dd>
+<dt><span class="term"><code class="option">+[no]onesoa</code></span></dt>
+<dd><p>
+ Print only one (starting) SOA record when performing
+ an AXFR. The default is to print both the starting and
+ ending SOA records.
+ </p></dd>
<dt><span class="term"><code class="option">+[no]fail</code></span></dt>
<dd><p>
Do not try the next server if you receive a SERVFAIL. The
@@ -555,7 +561,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2545166"></a><h2>MULTIPLE QUERIES</h2>
+<a name="id2545184"></a><h2>MULTIPLE QUERIES</h2>
<p>
The BIND 9 implementation of <span><strong class="command">dig </strong></span>
supports
@@ -601,7 +607,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2545228"></a><h2>IDN SUPPORT</h2>
+<a name="id2545245"></a><h2>IDN SUPPORT</h2>
<p>
If <span><strong class="command">dig</strong></span> has been built with IDN (internationalized
domain name) support, it can accept and display non-ASCII domain names.
@@ -615,14 +621,14 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2545251"></a><h2>FILES</h2>
+<a name="id2545336"></a><h2>FILES</h2>
<p><code class="filename">/etc/resolv.conf</code>
</p>
<p><code class="filename">${HOME}/.digrc</code>
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2545336"></a><h2>SEE ALSO</h2>
+<a name="id2545353"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">host</span>(1)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
@@ -630,7 +636,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2545373"></a><h2>BUGS</h2>
+<a name="id2545390"></a><h2>BUGS</h2>
<p>
There are probably too many query options.
</p>
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index df5a0c09f5fc..e92bc6edceec 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dighost.c,v 1.311.70.17 2010-12-09 01:12:54 marka Exp $ */
+/* $Id: dighost.c,v 1.336 2010-12-09 00:54:33 marka Exp $ */
/*! \file
* \note
@@ -53,6 +53,7 @@
#include <ctype.h>
#endif
#include <dns/fixedname.h>
+#include <dns/log.h>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/rdata.h>
@@ -71,10 +72,12 @@
#include <isc/entropy.h>
#include <isc/file.h>
#include <isc/lang.h>
+#include <isc/log.h>
#include <isc/netaddr.h>
#ifdef DIG_SIGCHASE
#include <isc/netdb.h>
#endif
+#include <isc/parseint.h>
#include <isc/print.h>
#include <isc/random.h>
#include <isc/result.h>
@@ -84,6 +87,8 @@
#include <isc/types.h>
#include <isc/util.h>
+#include <isccfg/namedconf.h>
+
#include <lwres/lwres.h>
#include <lwres/net.h>
@@ -121,6 +126,7 @@ in_port_t port = 53;
unsigned int timeout = 0;
unsigned int extrabytes;
isc_mem_t *mctx = NULL;
+isc_log_t *lctx = NULL;
isc_taskmgr_t *taskmgr = NULL;
isc_task_t *global_task = NULL;
isc_timermgr_t *timermgr = NULL;
@@ -393,7 +399,7 @@ count_dots(char *string) {
static void
hex_dump(isc_buffer_t *b) {
- unsigned int len;
+ unsigned int len, i;
isc_region_t r;
isc_buffer_usedregion(b, &r);
@@ -401,11 +407,29 @@ hex_dump(isc_buffer_t *b) {
printf("%d bytes\n", r.length);
for (len = 0; len < r.length; len++) {
printf("%02x ", r.base[len]);
- if (len % 16 == 15)
+ if (len % 16 == 15) {
+ fputs(" ", stdout);
+ for (i = len - 15; i <= len; i++) {
+ if (r.base[i] >= '!' && r.base[i] <= '}')
+ putchar(r.base[i]);
+ else
+ putchar('.');
+ }
printf("\n");
+ }
}
- if (len % 16 != 0)
+ if (len % 16 != 0) {
+ for (i = len; (i % 16) != 0; i++)
+ fputs(" ", stdout);
+ fputs(" ", stdout);
+ for (i = ((len>>4)<<4); i < len; i++) {
+ if (r.base[i] >= '!' && r.base[i] <= '}')
+ putchar(r.base[i]);
+ else
+ putchar('.');
+ }
printf("\n");
+ }
}
/*%
@@ -903,9 +927,7 @@ setup_text_key(void) {
secretsize = isc_buffer_usedlength(&secretbuf);
- result = dns_name_fromtext(&keyname, namebuf,
- dns_rootname, ISC_FALSE,
- namebuf);
+ result = dns_name_fromtext(&keyname, namebuf, dns_rootname, 0, namebuf);
if (result != ISC_R_SUCCESS)
goto failure;
@@ -924,14 +946,164 @@ setup_text_key(void) {
isc_buffer_free(&namebuf);
}
+isc_result_t
+parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
+ const char *desc) {
+ isc_uint32_t n;
+ isc_result_t result = isc_parse_uint32(&n, value, 10);
+ if (result == ISC_R_SUCCESS && n > max)
+ result = ISC_R_RANGE;
+ if (result != ISC_R_SUCCESS) {
+ printf("invalid %s '%s': %s\n", desc,
+ value, isc_result_totext(result));
+ return (result);
+ }
+ *uip = n;
+ return (ISC_R_SUCCESS);
+}
+
+static isc_uint32_t
+parse_bits(char *arg, const char *desc, isc_uint32_t max) {
+ isc_result_t result;
+ isc_uint32_t tmp;
+
+ result = parse_uint(&tmp, arg, max, desc);
+ if (result != ISC_R_SUCCESS)
+ fatal("couldn't parse digest bits");
+ tmp = (tmp + 7) & ~0x7U;
+ return (tmp);
+}
+
+
+/*
+ * Parse HMAC algorithm specification
+ */
+void
+parse_hmac(const char *hmac) {
+ char buf[20];
+ int len;
+
+ REQUIRE(hmac != NULL);
+
+ len = strlen(hmac);
+ if (len >= (int) sizeof(buf))
+ fatal("unknown key type '%.*s'", len, hmac);
+ strncpy(buf, hmac, sizeof(buf));
+
+ digestbits = 0;
+
+ if (strcasecmp(buf, "hmac-md5") == 0) {
+ hmacname = DNS_TSIG_HMACMD5_NAME;
+ } else if (strncasecmp(buf, "hmac-md5-", 9) == 0) {
+ hmacname = DNS_TSIG_HMACMD5_NAME;
+ digestbits = parse_bits(&buf[9], "digest-bits [0..128]", 128);
+ } else if (strcasecmp(buf, "hmac-sha1") == 0) {
+ hmacname = DNS_TSIG_HMACSHA1_NAME;
+ digestbits = 0;
+ } else if (strncasecmp(buf, "hmac-sha1-", 10) == 0) {
+ hmacname = DNS_TSIG_HMACSHA1_NAME;
+ digestbits = parse_bits(&buf[10], "digest-bits [0..160]", 160);
+ } else if (strcasecmp(buf, "hmac-sha224") == 0) {
+ hmacname = DNS_TSIG_HMACSHA224_NAME;
+ } else if (strncasecmp(buf, "hmac-sha224-", 12) == 0) {
+ hmacname = DNS_TSIG_HMACSHA224_NAME;
+ digestbits = parse_bits(&buf[12], "digest-bits [0..224]", 224);
+ } else if (strcasecmp(buf, "hmac-sha256") == 0) {
+ hmacname = DNS_TSIG_HMACSHA256_NAME;
+ } else if (strncasecmp(buf, "hmac-sha256-", 12) == 0) {
+ hmacname = DNS_TSIG_HMACSHA256_NAME;
+ digestbits = parse_bits(&buf[12], "digest-bits [0..256]", 256);
+ } else if (strcasecmp(buf, "hmac-sha384") == 0) {
+ hmacname = DNS_TSIG_HMACSHA384_NAME;
+ } else if (strncasecmp(buf, "hmac-sha384-", 12) == 0) {
+ hmacname = DNS_TSIG_HMACSHA384_NAME;
+ digestbits = parse_bits(&buf[12], "digest-bits [0..384]", 384);
+ } else if (strcasecmp(buf, "hmac-sha512") == 0) {
+ hmacname = DNS_TSIG_HMACSHA512_NAME;
+ } else if (strncasecmp(buf, "hmac-sha512-", 12) == 0) {
+ hmacname = DNS_TSIG_HMACSHA512_NAME;
+ digestbits = parse_bits(&buf[12], "digest-bits [0..512]", 512);
+ } else {
+ fprintf(stderr, ";; Warning, ignoring "
+ "invalid TSIG algorithm %s\n", buf);
+ }
+}
+
+/*
+ * Get a key from a named.conf format keyfile
+ */
+static isc_result_t
+read_confkey(void) {
+ isc_log_t *lctx = NULL;
+ cfg_parser_t *pctx = NULL;
+ cfg_obj_t *file = NULL;
+ const cfg_obj_t *key = NULL;
+ const cfg_obj_t *secretobj = NULL;
+ const cfg_obj_t *algorithmobj = NULL;
+ const char *keyname;
+ const char *secretstr;
+ const char *algorithm;
+ isc_result_t result;
+
+ if (! isc_file_exists(keyfile))
+ return (ISC_R_FILENOTFOUND);
+
+ result = cfg_parser_create(mctx, lctx, &pctx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey,
+ &file);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = cfg_map_get(file, "key", &key);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ (void) cfg_map_get(key, "secret", &secretobj);
+ (void) cfg_map_get(key, "algorithm", &algorithmobj);
+ if (secretobj == NULL || algorithmobj == NULL)
+ fatal("key must have algorithm and secret");
+
+ keyname = cfg_obj_asstring(cfg_map_getname(key));
+ secretstr = cfg_obj_asstring(secretobj);
+ algorithm = cfg_obj_asstring(algorithmobj);
+
+ strncpy(keynametext, keyname, sizeof(keynametext));
+ strncpy(keysecret, secretstr, sizeof(keysecret));
+ parse_hmac(algorithm);
+ setup_text_key();
+
+ cleanup:
+ if (pctx != NULL) {
+ if (file != NULL)
+ cfg_obj_destroy(pctx, &file);
+ cfg_parser_destroy(&pctx);
+ }
+
+ return (result);
+}
+
static void
setup_file_key(void) {
isc_result_t result;
dst_key_t *dstkey = NULL;
debug("setup_file_key()");
- result = dst_key_fromnamedfile(keyfile, DST_TYPE_PRIVATE | DST_TYPE_KEY,
- mctx, &dstkey);
+
+ /* Try reading the key from a K* pair */
+ result = dst_key_fromnamedfile(keyfile, NULL,
+ DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx,
+ &dstkey);
+
+ /* If that didn't work, try reading it as a session.key keyfile */
+ if (result != ISC_R_SUCCESS) {
+ result = read_confkey();
+ if (result == ISC_R_SUCCESS)
+ return;
+ }
+
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "Couldn't read key from %s: %s\n",
keyfile, isc_result_totext(result));
@@ -1119,6 +1291,7 @@ set_search_domain(char *domain) {
void
setup_libs(void) {
isc_result_t result;
+ isc_logconfig_t *logconfig = NULL;
debug("setup_libs()");
@@ -1135,6 +1308,18 @@ setup_libs(void) {
result = isc_mem_create(0, 0, &mctx);
check_result(result, "isc_mem_create");
+ result = isc_log_create(mctx, &lctx, &logconfig);
+ check_result(result, "isc_log_create");
+
+ isc_log_setcontext(lctx);
+ dns_log_init(lctx);
+ dns_log_setcontext(lctx);
+
+ result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL);
+ check_result(result, "isc_log_usechannel");
+
+ isc_log_setdebuglevel(lctx, 0);
+
result = isc_taskmgr_create(mctx, 1, 0, &taskmgr);
check_result(result, "isc_taskmgr_create");
@@ -1871,7 +2056,7 @@ setup_lookup(dig_lookup_t *lookup) {
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);
+ 0, &lookup->onamebuf);
if (result != ISC_R_SUCCESS) {
dns_message_puttempname(lookup->sendmsg,
&lookup->name);
@@ -1888,7 +2073,7 @@ setup_lookup(dig_lookup_t *lookup) {
isc_buffer_init(&b, lookup->textname, len);
isc_buffer_add(&b, len);
result = dns_name_fromtext(lookup->name, &b,
- lookup->oname, ISC_FALSE,
+ lookup->oname, 0,
&lookup->namebuf);
}
if (result != ISC_R_SUCCESS) {
@@ -1912,16 +2097,14 @@ setup_lookup(dig_lookup_t *lookup) {
isc_buffer_init(&b, idn_textname, len);
isc_buffer_add(&b, len);
result = dns_name_fromtext(lookup->name, &b,
- dns_rootname,
- ISC_FALSE,
+ dns_rootname, 0,
&lookup->namebuf);
#else
len = strlen(lookup->textname);
isc_buffer_init(&b, lookup->textname, len);
isc_buffer_add(&b, len);
result = dns_name_fromtext(lookup->name, &b,
- dns_rootname,
- ISC_FALSE,
+ dns_rootname, 0,
&lookup->namebuf);
#endif
}
@@ -3549,9 +3732,11 @@ destroy_libs(void) {
free_name(&chase_signame, mctx);
#endif
- debug("Destroy memory");
-
#endif
+ debug("Removing log context");
+ isc_log_destroy(&lctx);
+
+ debug("Destroy memory");
if (memdebugging != 0)
isc_mem_stats(mctx, stderr);
if (mctx != NULL)
@@ -4041,7 +4226,7 @@ get_trusted_key(isc_mem_t *mctx)
return (ISC_R_FAILURE);
}
fclose(fptemp);
- result = dst_key_fromnamedfile(filetemp, DST_TYPE_PUBLIC,
+ result = dst_key_fromnamedfile(filetemp, NULL, DST_TYPE_PUBLIC,
mctx, &key);
removetmpkey(mctx, filetemp);
isc_mem_free(mctx, filetemp);
@@ -4075,7 +4260,7 @@ nameFromString(const char *str, dns_name_t *p_ret) {
dns_fixedname_init(&fixedname);
result = dns_name_fromtext(dns_fixedname_name(&fixedname), &buffer,
- dns_rootname, ISC_TRUE, NULL);
+ dns_rootname, DNS_NAME_DOWNCASE, NULL);
check_result(result, "nameFromString");
if (dns_name_dynamic(p_ret))
diff --git a/bin/dig/host.1 b/bin/dig/host.1
index 1573effc8f2a..464d517a0b3d 100644
--- a/bin/dig/host.1
+++ b/bin/dig/host.1
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: host.1,v 1.29.114.2 2009-07-11 01:55:20 tbox Exp $
+.\" $Id: host.1,v 1.31 2009-07-11 01:12:45 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/bin/dig/host.c b/bin/dig/host.c
index ab0be99cd4bd..13569f63ac98 100644
--- a/bin/dig/host.c
+++ b/bin/dig/host.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: host.c,v 1.116.216.5 2010-10-19 23:45:58 tbox Exp $ */
+/* $Id: host.c,v 1.124 2010-11-16 05:38:30 marka Exp $ */
/*! \file */
@@ -141,6 +141,9 @@ rcode_totext(dns_rcode_t rcode)
return totext.deconsttext;
}
+ISC_PLATFORM_NORETURN_PRE static void
+show_usage(void) ISC_PLATFORM_NORETURN_POST;
+
static void
show_usage(void) {
fputs(
diff --git a/bin/dig/host.docbook b/bin/dig/host.docbook
index 41175aaffb2c..9ffd8e6ffb11 100644
--- a/bin/dig/host.docbook
+++ b/bin/dig/host.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: host.docbook,v 1.18.114.2 2009-01-22 23:47:05 tbox Exp $ -->
+<!-- $Id: host.docbook,v 1.20 2009-01-20 23:47:56 tbox Exp $ -->
<refentry id="man.host">
<refentryinfo>
diff --git a/bin/dig/host.html b/bin/dig/host.html
index de4b5797de99..531fc1d78968 100644
--- a/bin/dig/host.html
+++ b/bin/dig/host.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: host.html,v 1.28.114.2 2009-07-11 01:55:20 tbox Exp $ -->
+<!-- $Id: host.html,v 1.30 2009-07-11 01:12:45 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h
index 3d696c70bb8f..c0f778b5f142 100644
--- a/bin/dig/include/dig/dig.h
+++ b/bin/dig/include/dig/dig.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dig.h,v 1.107.120.2 2009-01-06 23:47:26 tbox Exp $ */
+/* $Id: dig.h,v 1.111 2009-09-29 15:06:06 fdupont Exp $ */
#ifndef DIG_H
#define DIG_H
@@ -292,8 +292,9 @@ isc_result_t
get_reverse(char *reverse, size_t len, char *value, isc_boolean_t ip6_int,
isc_boolean_t strict);
-void
-fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
+ISC_PLATFORM_NORETURN_PRE void
+fatal(const char *format, ...)
+ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
void
debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
@@ -325,6 +326,13 @@ setup_libs(void);
void
setup_system(void);
+isc_result_t
+parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
+ const char *desc);
+
+void
+parse_hmac(const char *hmacstr);
+
dig_lookup_t *
requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers);
diff --git a/bin/dig/nslookup.1 b/bin/dig/nslookup.1
index a8331f9b4c64..e97ee1f9ba39 100644
--- a/bin/dig/nslookup.1
+++ b/bin/dig/nslookup.1
@@ -12,7 +12,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: nslookup.1,v 1.14.354.2 2010-02-23 01:56:02 tbox Exp $
+.\" $Id: nslookup.1,v 1.16 2010-02-23 01:14:31 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c
index 8a166fd05535..0d368b15c800 100644
--- a/bin/dig/nslookup.c
+++ b/bin/dig/nslookup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nslookup.c,v 1.117.334.5 2009-10-20 01:11:22 marka Exp $ */
+/* $Id: nslookup.c,v 1.127 2010-11-17 23:47:08 tbox Exp $ */
#include <config.h>
@@ -541,22 +541,6 @@ safecpy(char *dest, char *src, int size) {
dest[size-1] = 0;
}
-static isc_result_t
-parse_uint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
- const char *desc) {
- isc_uint32_t n;
- isc_result_t result = isc_parse_uint32(&n, value, 10);
- if (result == ISC_R_SUCCESS && n > max)
- result = ISC_R_RANGE;
- if (result != ISC_R_SUCCESS) {
- printf("invalid %s '%s': %s\n", desc,
- value, isc_result_totext(result));
- return result;
- }
- *uip = n;
- return (ISC_R_SUCCESS);
-}
-
static void
set_port(const char *value) {
isc_uint32_t n;
diff --git a/bin/dig/nslookup.docbook b/bin/dig/nslookup.docbook
index fb6e70652c50..9c4789d4cb18 100644
--- a/bin/dig/nslookup.docbook
+++ b/bin/dig/nslookup.docbook
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: nslookup.docbook,v 1.16.334.2 2010-02-22 23:47:53 tbox Exp $ -->
+<!-- $Id: nslookup.docbook,v 1.18 2010-02-22 23:49:11 tbox Exp $ -->
<!--
- Copyright (c) 1985, 1989
- The Regents of the University of California. All rights reserved.
diff --git a/bin/dig/nslookup.html b/bin/dig/nslookup.html
index bff35282a79e..bae63bd0fd3d 100644
--- a/bin/dig/nslookup.html
+++ b/bin/dig/nslookup.html
@@ -13,7 +13,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: nslookup.html,v 1.21.354.2 2010-02-23 01:56:02 tbox Exp $ -->
+<!-- $Id: nslookup.html,v 1.23 2010-02-23 01:14:31 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/bin/dnssec/Makefile.in b/bin/dnssec/Makefile.in
index 50429be61337..0f5e4e842c20 100644
--- a/bin/dnssec/Makefile.in
+++ b/bin/dnssec/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.35 2008-11-07 02:28:49 marka Exp $
+# $Id: Makefile.in,v 1.42 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -25,11 +25,12 @@ top_srcdir = @top_srcdir@
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES}
-CDEFINES = -DVERSION=\"${VERSION}\"
+CDEFINES = -DVERSION=\"${VERSION}\" @USE_PKCS11@
CWARNINGS =
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
@@ -38,44 +39,56 @@ DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${DNSLIBS} ${ISCNOSYMLIBS} @LIBS@
+
# Alphabetically
TARGETS = dnssec-keygen@EXEEXT@ dnssec-signzone@EXEEXT@ \
- dnssec-keyfromlabel@EXEEXT@ dnssec-dsfromkey@EXEEXT@
+ dnssec-keyfromlabel@EXEEXT@ dnssec-dsfromkey@EXEEXT@ \
+ dnssec-revoke@EXEEXT@ dnssec-settime@EXEEXT@
OBJS = dnssectool.@O@
SRCS = dnssec-dsfromkey.c dnssec-keyfromlabel.c dnssec-keygen.c \
- dnssec-signzone.c dnssectool.c
+ dnssec-revoke.c dnssec-settime.c dnssec-signzone.c dnssectool.c
MANPAGES = dnssec-dsfromkey.8 dnssec-keyfromlabel.8 dnssec-keygen.8 \
- dnssec-signzone.8
+ dnssec-revoke.8 dnssec-settime.8 dnssec-signzone.8
HTMLPAGES = dnssec-dsfromkey.html dnssec-keyfromlabel.html \
- dnssec-keygen.html dnssec-signzone.html
+ dnssec-keygen.html dnssec-revoke.html \
+ dnssec-settime.html dnssec-signzone.html
MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
dnssec-dsfromkey@EXEEXT@: dnssec-dsfromkey.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-dsfromkey.@O@ ${OBJS} ${LIBS}
+ export BASEOBJS="dnssec-dsfromkey.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
dnssec-keyfromlabel@EXEEXT@: dnssec-keyfromlabel.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-keyfromlabel.@O@ ${OBJS} ${LIBS}
+ export BASEOBJS="dnssec-keyfromlabel.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
dnssec-keygen@EXEEXT@: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-keygen.@O@ ${OBJS} ${LIBS}
+ export BASEOBJS="dnssec-keygen.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
dnssec-signzone.@O@: dnssec-signzone.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \
-c ${srcdir}/dnssec-signzone.c
dnssec-signzone@EXEEXT@: dnssec-signzone.@O@ ${OBJS} ${DEPLIBS}
+ export BASEOBJS="dnssec-signzone.@O@ ${OBJS}"; \
+ ${FINALBUILDCMD}
+
+dnssec-revoke@EXEEXT@: dnssec-revoke.@O@ ${OBJS} ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ dnssec-revoke.@O@ ${OBJS} ${LIBS}
+
+dnssec-settime@EXEEXT@: dnssec-settime.@O@ ${OBJS} ${DEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- dnssec-signzone.@O@ ${OBJS} ${LIBS}
+ dnssec-settime.@O@ ${OBJS} ${LIBS}
doc man:: ${MANOBJS}
diff --git a/bin/dnssec/dnssec-dsfromkey.8 b/bin/dnssec/dnssec-dsfromkey.8
index c49ccdc82377..25aa2bf831fc 100644
--- a/bin/dnssec/dnssec-dsfromkey.8
+++ b/bin/dnssec/dnssec-dsfromkey.8
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2008-2010 Internet Systems Consortium, Inc. ("ISC")
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -12,18 +12,18 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-dsfromkey.8,v 1.5.14.1 2010-05-19 02:06:11 tbox Exp $
+.\" $Id: dnssec-dsfromkey.8,v 1.13 2010-12-24 01:14:20 tbox Exp $
.\"
.hy 0
.ad l
.\" Title: dnssec\-dsfromkey
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
-.\" Date: November 29, 2008
+.\" Date: August 26, 2009
.\" Manual: BIND9
.\" Source: BIND9
.\"
-.TH "DNSSEC\-DSFROMKEY" "8" "November 29, 2008" "BIND9" "BIND9"
+.TH "DNSSEC\-DSFROMKEY" "8" "August 26, 2009" "BIND9" "BIND9"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -32,9 +32,9 @@
dnssec\-dsfromkey \- DNSSEC DS RR generation tool
.SH "SYNOPSIS"
.HP 17
-\fBdnssec\-dsfromkey\fR [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] {keyfile}
+\fBdnssec\-dsfromkey\fR [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] {keyfile}
.HP 17
-\fBdnssec\-dsfromkey\fR {\-s} [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdir\fR\fR] {dnsname}
+\fBdnssec\-dsfromkey\fR {\-s} [\fB\-1\fR] [\fB\-2\fR] [\fB\-a\ \fR\fB\fIalg\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-s\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIfile\fR\fR] [\fB\-A\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {dnsname}
.SH "DESCRIPTION"
.PP
\fBdnssec\-dsfromkey\fR
@@ -55,31 +55,49 @@ Use SHA\-256 as the digest algorithm.
.RS 4
Select the digest algorithm. The value of
\fBalgorithm\fR
-must be one of SHA\-1 (SHA1) or SHA\-256 (SHA256). These values are case insensitive.
+must be one of SHA\-1 (SHA1), SHA\-256 (SHA256) or GOST. These values are case insensitive.
.RE
.PP
-\-v \fIlevel\fR
+\-K \fIdirectory\fR
.RS 4
-Sets the debugging level.
+Look for key files (or, in keyset mode,
+\fIkeyset\-\fR
+files) in
+\fBdirectory\fR.
+.RE
+.PP
+\-f \fIfile\fR
+.RS 4
+Zone file mode: in place of the keyfile name, the argument is the DNS domain name of a zone master file, which can be read from
+\fBfile\fR. If the zone name is the same as
+\fBfile\fR, then it may be omitted.
+.RE
+.PP
+\-A
+.RS 4
+Include ZSK's when generating DS records. Without this option, only keys which have the KSK flag set will be converted to DS records and printed. Useful only in zone file mode.
+.RE
+.PP
+\-l \fIdomain\fR
+.RS 4
+Generate a DLV set instead of a DS set. The specified
+\fBdomain\fR
+is appended to the name for each record in the set. The DNSSEC Lookaside Validation (DLV) RR is described in RFC 4431.
.RE
.PP
\-s
.RS 4
-Keyset mode: in place of the keyfile name, the argument is the DNS domain name of a keyset file. Following options make sense only in this mode.
+Keyset mode: in place of the keyfile name, the argument is the DNS domain name of a keyset file.
.RE
.PP
\-c \fIclass\fR
.RS 4
-Specifies the DNS class (default is IN), useful only in the keyset mode.
+Specifies the DNS class (default is IN). Useful only in keyset or zone file mode.
.RE
.PP
-\-d \fIdirectory\fR
+\-v \fIlevel\fR
.RS 4
-Look for
-\fIkeyset\fR
-files in
-\fBdirectory\fR
-as the directory, ignored when not in the keyset mode.
+Sets the debugging level.
.RE
.SH "EXAMPLE"
.PP
@@ -115,10 +133,11 @@ A keyfile error can give a "file not found" even if the file exists.
\fBdnssec\-signzone\fR(8),
BIND 9 Administrator Reference Manual,
RFC 3658,
+RFC 4431.
RFC 4509.
.SH "AUTHOR"
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2008 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2008\-2010 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/bin/dnssec/dnssec-dsfromkey.c b/bin/dnssec/dnssec-dsfromkey.c
index 934d25bd35ab..b7f84a041110 100644
--- a/bin/dnssec/dnssec-dsfromkey.c
+++ b/bin/dnssec/dnssec-dsfromkey.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-dsfromkey.c,v 1.2.14.6 2010-01-11 23:47:22 tbox Exp $ */
+/* $Id: dnssec-dsfromkey.c,v 1.19 2010-12-23 04:07:59 marka Exp $ */
/*! \file */
@@ -36,6 +36,8 @@
#include <dns/ds.h>
#include <dns/fixedname.h>
#include <dns/log.h>
+#include <dns/keyvalues.h>
+#include <dns/master.h>
#include <dns/name.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
@@ -48,54 +50,40 @@
#include "dnssectool.h"
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */
+#endif
+
const char *program = "dnssec-dsfromkey";
int verbose;
static dns_rdataclass_t rdclass;
-static dns_fixedname_t fixed;
-static dns_name_t *name = NULL;
-static dns_db_t *db = NULL;
-static dns_dbnode_t *node = NULL;
-static dns_rdataset_t keyset;
-static isc_mem_t *mctx = NULL;
+static dns_fixedname_t fixed;
+static dns_name_t *name = NULL;
+static isc_mem_t *mctx = NULL;
-static void
-loadkeys(char *dirname, char *setname)
-{
- isc_result_t result;
- char filename[1024];
- isc_buffer_t buf;
+static isc_result_t
+initname(char *setname) {
+ isc_result_t result;
+ isc_buffer_t buf;
- dns_rdataset_init(&keyset);
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
isc_buffer_init(&buf, setname, strlen(setname));
isc_buffer_add(&buf, strlen(setname));
- result = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL);
- if (result != ISC_R_SUCCESS)
- fatal("can't convert DNS name %s", setname);
+ result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
+ return (result);
+}
- isc_buffer_init(&buf, filename, sizeof(filename));
- if (dirname != NULL) {
- if (isc_buffer_availablelength(&buf) < strlen(dirname))
- fatal("directory name '%s' too long", dirname);
- isc_buffer_putstr(&buf, dirname);
- if (dirname[strlen(dirname) - 1] != '/') {
- if (isc_buffer_availablelength(&buf) < 1)
- fatal("directory name '%s' too long", dirname);
- isc_buffer_putstr(&buf, "/");
- }
- }
+static isc_result_t
+loadsetfromfile(char *filename, dns_rdataset_t *rdataset) {
+ isc_result_t result;
+ dns_db_t *db = NULL;
+ dns_dbnode_t *node = NULL;
+ char setname[DNS_NAME_FORMATSIZE];
- if (isc_buffer_availablelength(&buf) < strlen("keyset-"))
- fatal("directory name '%s' too long", dirname);
- isc_buffer_putstr(&buf, "keyset-");
- result = dns_name_tofilenametext(name, ISC_FALSE, &buf);
- check_result(result, "dns_name_tofilenametext()");
- if (isc_buffer_availablelength(&buf) == 0)
- fatal("name %s too long", setname);
- isc_buffer_putuint8(&buf, 0);
+ dns_name_format(name, setname, sizeof(setname));
result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
rdclass, 0, NULL, &db);
@@ -111,11 +99,49 @@ loadkeys(char *dirname, char *setname)
fatal("can't find %s node in %s", setname, filename);
result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey,
- 0, 0, &keyset, NULL);
+ 0, 0, rdataset, NULL);
+
if (result == ISC_R_NOTFOUND)
fatal("no DNSKEY RR for %s in %s", setname, filename);
else if (result != ISC_R_SUCCESS)
fatal("dns_db_findrdataset");
+
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ if (db != NULL)
+ dns_db_detach(&db);
+ return (result);
+}
+
+static isc_result_t
+loadkeyset(char *dirname, dns_rdataset_t *rdataset) {
+ isc_result_t result;
+ char filename[PATH_MAX + 1];
+ isc_buffer_t buf;
+
+ dns_rdataset_init(rdataset);
+
+ isc_buffer_init(&buf, filename, sizeof(filename));
+ if (dirname != NULL) {
+ /* allow room for a trailing slash */
+ if (strlen(dirname) >= isc_buffer_availablelength(&buf))
+ return (ISC_R_NOSPACE);
+ isc_buffer_putstr(&buf, dirname);
+ if (dirname[strlen(dirname) - 1] != '/')
+ isc_buffer_putstr(&buf, "/");
+ }
+
+ if (isc_buffer_availablelength(&buf) < 7)
+ return (ISC_R_NOSPACE);
+ isc_buffer_putstr(&buf, "keyset-");
+
+ result = dns_name_tofilenametext(name, ISC_FALSE, &buf);
+ check_result(result, "dns_name_tofilenametext()");
+ if (isc_buffer_availablelength(&buf) == 0)
+ return (ISC_R_NOSPACE);
+ isc_buffer_putuint8(&buf, 0);
+
+ return (loadsetfromfile(filename, rdataset));
}
static void
@@ -127,20 +153,20 @@ loadkey(char *filename, unsigned char *key_buf, unsigned int key_buf_size,
isc_buffer_t keyb;
isc_region_t r;
- dns_rdataset_init(&keyset);
dns_rdata_init(rdata);
isc_buffer_init(&keyb, key_buf, key_buf_size);
- result = dst_key_fromnamedfile(filename, DST_TYPE_PUBLIC, mctx, &key);
+ result = dst_key_fromnamedfile(filename, NULL, DST_TYPE_PUBLIC,
+ mctx, &key);
if (result != ISC_R_SUCCESS)
fatal("invalid keyfile name %s: %s",
filename, isc_result_totext(result));
if (verbose > 2) {
- char keystr[KEY_FORMATSIZE];
+ char keystr[DST_KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ dst_key_format(key, keystr, sizeof(keystr));
fprintf(stderr, "%s: %s\n", program, keystr);
}
@@ -169,7 +195,7 @@ logkey(dns_rdata_t *rdata)
isc_result_t result;
dst_key_t *key = NULL;
isc_buffer_t buf;
- char keystr[KEY_FORMATSIZE];
+ char keystr[DST_KEY_FORMATSIZE];
isc_buffer_init(&buf, rdata->data, rdata->length);
isc_buffer_add(&buf, rdata->length);
@@ -177,89 +203,132 @@ logkey(dns_rdata_t *rdata)
if (result != ISC_R_SUCCESS)
return;
- key_format(key, keystr, sizeof(keystr));
+ dst_key_format(key, keystr, sizeof(keystr));
fprintf(stderr, "%s: %s\n", program, keystr);
dst_key_free(&key);
}
static void
-emitds(unsigned int dtype, dns_rdata_t *rdata)
+emit(unsigned int dtype, isc_boolean_t showall, char *lookaside,
+ dns_rdata_t *rdata)
{
- isc_result_t result;
- unsigned char buf[DNS_DS_BUFFERSIZE];
- char text_buf[DST_KEY_MAXTEXTSIZE];
- char class_buf[10];
- isc_buffer_t textb, classb;
- isc_region_t r;
- dns_rdata_t ds;
+ isc_result_t result;
+ unsigned char buf[DNS_DS_BUFFERSIZE];
+ char text_buf[DST_KEY_MAXTEXTSIZE];
+ char name_buf[DNS_NAME_MAXWIRE];
+ char class_buf[10];
+ isc_buffer_t textb, nameb, classb;
+ isc_region_t r;
+ dns_rdata_t ds;
+ dns_rdata_dnskey_t dnskey;
isc_buffer_init(&textb, text_buf, sizeof(text_buf));
+ isc_buffer_init(&nameb, name_buf, sizeof(name_buf));
isc_buffer_init(&classb, class_buf, sizeof(class_buf));
dns_rdata_init(&ds);
+ result = dns_rdata_tostruct(rdata, &dnskey, NULL);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't convert DNSKEY");
+
+ if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && !showall)
+ return;
+
result = dns_ds_buildrdata(name, rdata, dtype, buf, &ds);
if (result != ISC_R_SUCCESS)
- fatal("can't build DS");
+ fatal("can't build record");
+
+ result = dns_name_totext(name, ISC_FALSE, &nameb);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't print name");
+
+ /* Add lookaside origin, if set */
+ if (lookaside != NULL) {
+ if (isc_buffer_availablelength(&nameb) < strlen(lookaside))
+ fatal("DLV origin '%s' is too long", lookaside);
+ isc_buffer_putstr(&nameb, lookaside);
+ if (lookaside[strlen(lookaside) - 1] != '.') {
+ if (isc_buffer_availablelength(&nameb) < 1)
+ fatal("DLV origin '%s' is too long", lookaside);
+ isc_buffer_putstr(&nameb, ".");
+ }
+ }
result = dns_rdata_totext(&ds, (dns_name_t *) NULL, &textb);
if (result != ISC_R_SUCCESS)
- fatal("can't print DS rdata");
+ fatal("can't print rdata");
result = dns_rdataclass_totext(rdclass, &classb);
if (result != ISC_R_SUCCESS)
- fatal("can't print DS class");
+ fatal("can't print class");
- result = dns_name_print(name, stdout);
- if (result != ISC_R_SUCCESS)
- fatal("can't print DS name");
+ isc_buffer_usedregion(&nameb, &r);
+ isc_util_fwrite(r.base, 1, r.length, stdout);
putchar(' ');
isc_buffer_usedregion(&classb, &r);
isc_util_fwrite(r.base, 1, r.length, stdout);
- printf(" DS ");
+ if (lookaside == NULL)
+ printf(" DS ");
+ else
+ printf(" DLV ");
isc_buffer_usedregion(&textb, &r);
isc_util_fwrite(r.base, 1, r.length, stdout);
putchar('\n');
}
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(void) {
fprintf(stderr, "Usage:\n");
- fprintf(stderr, " %s options keyfile\n\n", program);
- fprintf(stderr, " %s options [-c class] [-d dir] -s dnsname\n\n",
+ fprintf(stderr, " %s options [-K dir] keyfile\n\n", program);
+ fprintf(stderr, " %s options [-K dir] [-c class] -s dnsname\n\n",
program);
+ fprintf(stderr, " %s options -f zonefile (as zone name)\n\n", program);
+ fprintf(stderr, " %s options -f zonefile zonename\n\n", program);
fprintf(stderr, "Version: %s\n", VERSION);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -v <verbose level>\n");
+ fprintf(stderr, " -K <directory>: directory in which to find "
+ "key file or keyset file\n");
+ fprintf(stderr, " -a algorithm: digest algorithm "
+ "(SHA-1, SHA-256 or GOST)\n");
fprintf(stderr, " -1: use SHA-1\n");
fprintf(stderr, " -2: use SHA-256\n");
- fprintf(stderr, " -a algorithm: use algorithm\n");
- fprintf(stderr, "Keyset options:\n");
- fprintf(stderr, " -s: keyset mode\n");
- fprintf(stderr, " -c class\n");
- fprintf(stderr, " -d directory\n");
- fprintf(stderr, "Output: DS RRs\n");
+ fprintf(stderr, " -l: add lookaside zone and print DLV records\n");
+ fprintf(stderr, " -s: read keyset from keyset-<dnsname> file\n");
+ fprintf(stderr, " -c class: rdata class for DS set (default: IN)\n");
+ fprintf(stderr, " -f file: read keyset from zone file\n");
+ fprintf(stderr, " -A: when used with -f, "
+ "include all keys in DS set, not just KSKs\n");
+ fprintf(stderr, "Output: DS or DLV RRs\n");
exit (-1);
}
int
main(int argc, char **argv) {
- char *algname = NULL, *classname = NULL, *dirname = NULL;
- char *endp;
- int ch;
- unsigned int dtype = DNS_DSDIGEST_SHA1;
- isc_boolean_t both = ISC_TRUE;
- isc_boolean_t usekeyset = ISC_FALSE;
- isc_result_t result;
- isc_log_t *log = NULL;
- isc_entropy_t *ectx = NULL;
- dns_rdata_t rdata;
+ char *algname = NULL, *classname = NULL;
+ char *filename = NULL, *dir = NULL, *namestr;
+ char *lookaside = NULL;
+ char *endp;
+ int ch;
+ unsigned int dtype = DNS_DSDIGEST_SHA1;
+ isc_boolean_t both = ISC_TRUE;
+ isc_boolean_t usekeyset = ISC_FALSE;
+ isc_boolean_t showall = ISC_FALSE;
+ isc_result_t result;
+ isc_log_t *log = NULL;
+ isc_entropy_t *ectx = NULL;
+ dns_rdataset_t rdataset;
+ dns_rdata_t rdata;
dns_rdata_init(&rdata);
@@ -275,7 +344,7 @@ main(int argc, char **argv) {
isc_commandline_errprint = ISC_FALSE;
while ((ch = isc_commandline_parse(argc, argv,
- "12a:c:d:sv:h")) != -1) {
+ "12Aa:c:d:Ff:K:l:sv:h")) != -1) {
switch (ch) {
case '1':
dtype = DNS_DSDIGEST_SHA1;
@@ -285,6 +354,9 @@ main(int argc, char **argv) {
dtype = DNS_DSDIGEST_SHA256;
both = ISC_FALSE;
break;
+ case 'A':
+ showall = ISC_TRUE;
+ break;
case 'a':
algname = isc_commandline_argument;
both = ISC_FALSE;
@@ -293,7 +365,21 @@ main(int argc, char **argv) {
classname = isc_commandline_argument;
break;
case 'd':
- dirname = isc_commandline_argument;
+ fprintf(stderr, "%s: the -d option is deprecated; "
+ "use -K\n", program);
+ /* fall through */
+ case 'K':
+ dir = isc_commandline_argument;
+ if (strlen(dir) == 0U)
+ fatal("directory must be non-empty string");
+ break;
+ case 'f':
+ filename = isc_commandline_argument;
+ break;
+ case 'l':
+ lookaside = isc_commandline_argument;
+ if (strlen(lookaside) == 0U)
+ fatal("lookaside must be a non-empty string");
break;
case 's':
usekeyset = ISC_TRUE;
@@ -303,11 +389,14 @@ main(int argc, char **argv) {
if (*endp != '\0')
fatal("-v must be followed by a number");
break;
+ case 'F':
+ /* Reserved for FIPS mode */
+ /* FALLTHROUGH */
case '?':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
program, isc_commandline_option);
- /* Falls into */
+ /* FALLTHROUGH */
case 'h':
usage();
@@ -325,13 +414,24 @@ main(int argc, char **argv) {
else if (strcasecmp(algname, "SHA256") == 0 ||
strcasecmp(algname, "SHA-256") == 0)
dtype = DNS_DSDIGEST_SHA256;
+#ifdef HAVE_OPENSSL_GOST
+ else if (strcasecmp(algname, "GOST") == 0)
+ dtype = DNS_DSDIGEST_GOST;
+#endif
else
fatal("unknown algorithm %s", algname);
}
rdclass = strtoclass(classname);
- if (argc < isc_commandline_index + 1)
+ if (usekeyset && filename != NULL)
+ fatal("cannot use both -s and -f");
+
+ /* When not using -f, -A is implicit */
+ if (filename == NULL)
+ showall = ISC_TRUE;
+
+ if (argc < isc_commandline_index + 1 && filename == NULL)
fatal("the key file name was not specified");
if (argc > isc_commandline_index + 1)
fatal("extraneous arguments");
@@ -344,28 +444,50 @@ main(int argc, char **argv) {
result = dst_lib_init(mctx, ectx,
ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
if (result != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(result));
isc_entropy_stopcallbacksources(ectx);
setup_logging(verbose, mctx, &log);
- if (usekeyset) {
- loadkeys(dirname, argv[isc_commandline_index]);
+ dns_rdataset_init(&rdataset);
+
+ if (usekeyset || filename != NULL) {
+ if (argc < isc_commandline_index + 1 && filename != NULL) {
+ /* using zone name as the zone file name */
+ namestr = filename;
+ } else
+ namestr = argv[isc_commandline_index];
- for (result = dns_rdataset_first(&keyset);
+ result = initname(namestr);
+ if (result != ISC_R_SUCCESS)
+ fatal("could not initialize name %s", namestr);
+
+ if (usekeyset)
+ result = loadkeyset(dir, &rdataset);
+ else
+ result = loadsetfromfile(filename, &rdataset);
+
+ if (result != ISC_R_SUCCESS)
+ fatal("could not load DNSKEY set: %s\n",
+ isc_result_totext(result));
+
+ for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&keyset)) {
+ result = dns_rdataset_next(&rdataset)) {
dns_rdata_init(&rdata);
- dns_rdataset_current(&keyset, &rdata);
+ dns_rdataset_current(&rdataset, &rdata);
if (verbose > 2)
logkey(&rdata);
if (both) {
- emitds(DNS_DSDIGEST_SHA1, &rdata);
- emitds(DNS_DSDIGEST_SHA256, &rdata);
+ emit(DNS_DSDIGEST_SHA1, showall, lookaside,
+ &rdata);
+ emit(DNS_DSDIGEST_SHA256, showall, lookaside,
+ &rdata);
} else
- emitds(dtype, &rdata);
+ emit(dtype, showall, lookaside, &rdata);
}
} else {
unsigned char key_buf[DST_KEY_MAXSIZE];
@@ -374,18 +496,14 @@ main(int argc, char **argv) {
DST_KEY_MAXSIZE, &rdata);
if (both) {
- emitds(DNS_DSDIGEST_SHA1, &rdata);
- emitds(DNS_DSDIGEST_SHA256, &rdata);
+ emit(DNS_DSDIGEST_SHA1, showall, lookaside, &rdata);
+ emit(DNS_DSDIGEST_SHA256, showall, lookaside, &rdata);
} else
- emitds(dtype, &rdata);
+ emit(dtype, showall, lookaside, &rdata);
}
- if (dns_rdataset_isassociated(&keyset))
- dns_rdataset_disassociate(&keyset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- if (db != NULL)
- dns_db_detach(&db);
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
cleanup_logging(&log);
dst_lib_destroy();
isc_hash_destroy();
diff --git a/bin/dnssec/dnssec-dsfromkey.docbook b/bin/dnssec/dnssec-dsfromkey.docbook
index c4ea38d68d94..36410d5f35c1 100644
--- a/bin/dnssec/dnssec-dsfromkey.docbook
+++ b/bin/dnssec/dnssec-dsfromkey.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2008-2010 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -17,10 +17,10 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-dsfromkey.docbook,v 1.6 2008-11-07 13:54:11 jreed Exp $ -->
+<!-- $Id: dnssec-dsfromkey.docbook,v 1.12 2010-12-23 23:47:08 tbox Exp $ -->
<refentry id="man.dnssec-dsfromkey">
<refentryinfo>
- <date>November 29, 2008</date>
+ <date>August 26, 2009</date>
</refentryinfo>
<refmeta>
@@ -37,6 +37,8 @@
<docinfo>
<copyright>
<year>2008</year>
+ <year>2009</year>
+ <year>2010</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -48,17 +50,22 @@
<arg><option>-1</option></arg>
<arg><option>-2</option></arg>
<arg><option>-a <replaceable class="parameter">alg</replaceable></option></arg>
+ <arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
<arg choice="req">keyfile</arg>
</cmdsynopsis>
<cmdsynopsis>
<command>dnssec-dsfromkey</command>
<arg choice="req">-s</arg>
- <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
<arg><option>-1</option></arg>
<arg><option>-2</option></arg>
<arg><option>-a <replaceable class="parameter">alg</replaceable></option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
+ <arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
+ <arg><option>-s</option></arg>
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
- <arg><option>-d <replaceable class="parameter">dir</replaceable></option></arg>
+ <arg><option>-f <replaceable class="parameter">file</replaceable></option></arg>
+ <arg><option>-A</option></arg>
+ <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
<arg choice="req">dnsname</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -99,17 +106,55 @@
<listitem>
<para>
Select the digest algorithm. The value of
- <option>algorithm</option> must be one of SHA-1 (SHA1) or
- SHA-256 (SHA256). These values are case insensitive.
+ <option>algorithm</option> must be one of SHA-1 (SHA1),
+ SHA-256 (SHA256) or GOST. These values are case insensitive.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>-v <replaceable class="parameter">level</replaceable></term>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
<listitem>
<para>
- Sets the debugging level.
+ Look for key files (or, in keyset mode,
+ <filename>keyset-</filename> files) in
+ <option>directory</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-f <replaceable class="parameter">file</replaceable></term>
+ <listitem>
+ <para>
+ Zone file mode: in place of the keyfile name, the argument is
+ the DNS domain name of a zone master file, which can be read
+ from <option>file</option>. If the zone name is the same as
+ <option>file</option>, then it may be omitted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A</term>
+ <listitem>
+ <para>
+ Include ZSK's when generating DS records. Without this option,
+ only keys which have the KSK flag set will be converted to DS
+ records and printed. Useful only in zone file mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-l <replaceable class="parameter">domain</replaceable></term>
+ <listitem>
+ <para>
+ Generate a DLV set instead of a DS set. The specified
+ <option>domain</option> is appended to the name for each
+ record in the set.
+ The DNSSEC Lookaside Validation (DLV) RR is described
+ in RFC 4431.
</para>
</listitem>
</varlistentry>
@@ -119,8 +164,7 @@
<listitem>
<para>
Keyset mode: in place of the keyfile name, the argument is
- the DNS domain name of a keyset file. Following options make sense
- only in this mode.
+ the DNS domain name of a keyset file.
</para>
</listitem>
</varlistentry>
@@ -129,23 +173,20 @@
<term>-c <replaceable class="parameter">class</replaceable></term>
<listitem>
<para>
- Specifies the DNS class (default is IN), useful only
- in the keyset mode.
+ Specifies the DNS class (default is IN). Useful only
+ in keyset or zone file mode.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>-d <replaceable class="parameter">directory</replaceable></term>
+ <term>-v <replaceable class="parameter">level</replaceable></term>
<listitem>
<para>
- Look for <filename>keyset</filename> files in
- <option>directory</option> as the directory, ignored when
- not in the keyset mode.
+ Sets the debugging level.
</para>
</listitem>
</varlistentry>
-
</variablelist>
</refsect1>
@@ -197,6 +238,7 @@
</citerefentry>,
<citetitle>BIND 9 Administrator Reference Manual</citetitle>,
<citetitle>RFC 3658</citetitle>,
+ <citetitle>RFC 4431</citetitle>.
<citetitle>RFC 4509</citetitle>.
</para>
</refsect1>
diff --git a/bin/dnssec/dnssec-dsfromkey.html b/bin/dnssec/dnssec-dsfromkey.html
index 618648118dd6..54cc1ab61ca2 100644
--- a/bin/dnssec/dnssec-dsfromkey.html
+++ b/bin/dnssec/dnssec-dsfromkey.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2008-2010 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -13,7 +13,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-dsfromkey.html,v 1.5.14.1 2010-05-19 02:06:11 tbox Exp $ -->
+<!-- $Id: dnssec-dsfromkey.html,v 1.13 2010-12-24 01:14:19 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -28,18 +28,18 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] {keyfile}</p></div>
-<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>dir</code></em></code>] {dnsname}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] {keyfile}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-s</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>file</code></em></code>] [<code class="option">-A</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {dnsname}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543424"></a><h2>DESCRIPTION</h2>
+<a name="id2543464"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-dsfromkey</strong></span>
outputs the Delegation Signer (DS) resource record (RR), as defined in
RFC 3658 and RFC 4509, for the given key(s).
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543435"></a><h2>OPTIONS</h2>
+<a name="id2543476"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-1</span></dt>
<dd><p>
@@ -53,34 +53,54 @@
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd><p>
Select the digest algorithm. The value of
- <code class="option">algorithm</code> must be one of SHA-1 (SHA1) or
- SHA-256 (SHA256). These values are case insensitive.
+ <code class="option">algorithm</code> must be one of SHA-1 (SHA1),
+ SHA-256 (SHA256) or GOST. These values are case insensitive.
</p></dd>
-<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
<dd><p>
- Sets the debugging level.
+ Look for key files (or, in keyset mode,
+ <code class="filename">keyset-</code> files) in
+ <code class="option">directory</code>.
+ </p></dd>
+<dt><span class="term">-f <em class="replaceable"><code>file</code></em></span></dt>
+<dd><p>
+ Zone file mode: in place of the keyfile name, the argument is
+ the DNS domain name of a zone master file, which can be read
+ from <code class="option">file</code>. If the zone name is the same as
+ <code class="option">file</code>, then it may be omitted.
+ </p></dd>
+<dt><span class="term">-A</span></dt>
+<dd><p>
+ Include ZSK's when generating DS records. Without this option,
+ only keys which have the KSK flag set will be converted to DS
+ records and printed. Useful only in zone file mode.
+ </p></dd>
+<dt><span class="term">-l <em class="replaceable"><code>domain</code></em></span></dt>
+<dd><p>
+ Generate a DLV set instead of a DS set. The specified
+ <code class="option">domain</code> is appended to the name for each
+ record in the set.
+ The DNSSEC Lookaside Validation (DLV) RR is described
+ in RFC 4431.
</p></dd>
<dt><span class="term">-s</span></dt>
<dd><p>
Keyset mode: in place of the keyfile name, the argument is
- the DNS domain name of a keyset file. Following options make sense
- only in this mode.
+ the DNS domain name of a keyset file.
</p></dd>
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
<dd><p>
- Specifies the DNS class (default is IN), useful only
- in the keyset mode.
+ Specifies the DNS class (default is IN). Useful only
+ in keyset or zone file mode.
</p></dd>
-<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
+<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
<dd><p>
- Look for <code class="filename">keyset</code> files in
- <code class="option">directory</code> as the directory, ignored when
- not in the keyset mode.
+ Sets the debugging level.
</p></dd>
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543563"></a><h2>EXAMPLE</h2>
+<a name="id2543662"></a><h2>EXAMPLE</h2>
<p>
To build the SHA-256 DS RR from the
<strong class="userinput"><code>Kexample.com.+003+26160</code></strong>
@@ -95,7 +115,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543593"></a><h2>FILES</h2>
+<a name="id2543692"></a><h2>FILES</h2>
<p>
The keyfile can be designed by the key identification
<code class="filename">Knnnn.+aaa+iiiii</code> or the full file name
@@ -109,22 +129,23 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543628"></a><h2>CAVEAT</h2>
+<a name="id2543728"></a><h2>CAVEAT</h2>
<p>
A keyfile error can give a "file not found" even if the file exists.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543638"></a><h2>SEE ALSO</h2>
+<a name="id2543737"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 3658</em>,
+ <em class="citetitle">RFC 4431</em>.
<em class="citetitle">RFC 4509</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543674"></a><h2>AUTHOR</h2>
+<a name="id2543777"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/dnssec/dnssec-keyfromlabel.8 b/bin/dnssec/dnssec-keyfromlabel.8
index 45fc0877b725..d8c19f2e527a 100644
--- a/bin/dnssec/dnssec-keyfromlabel.8
+++ b/bin/dnssec/dnssec-keyfromlabel.8
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2008-2011 Internet Systems Consortium, Inc. ("ISC")
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-keyfromlabel.8,v 1.6.14.3 2010-01-16 01:55:32 tbox Exp $
+.\" $Id: dnssec-keyfromlabel.8,v 1.18.14.1.2.1 2011-06-09 03:41:05 tbox Exp $
.\"
.hy 0
.ad l
@@ -32,18 +32,22 @@
dnssec\-keyfromlabel \- DNSSEC key generation tool
.SH "SYNOPSIS"
.HP 20
-\fBdnssec\-keyfromlabel\fR {\-a\ \fIalgorithm\fR} {\-l\ \fIlabel\fR} [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-k\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name}
+\fBdnssec\-keyfromlabel\fR {\-l\ \fIlabel\fR} [\fB\-3\fR] [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-k\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-y\fR] {name}
.SH "DESCRIPTION"
.PP
\fBdnssec\-keyfromlabel\fR
gets keys with the given label from a crypto hardware and builds key files for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034.
+.PP
+The
+\fBname\fR
+of the key is specified on the command line. This must match the name of the zone for which the key is being generated.
.SH "OPTIONS"
.PP
\-a \fIalgorithm\fR
.RS 4
Selects the cryptographic algorithm. The value of
\fBalgorithm\fR
-must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or DH (Diffie Hellman). These values are case insensitive.
+must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST. These values are case insensitive.
.sp
If no algorithm is specified, then RSASHA1 will be used by default, unless the
\fB\-3\fR
@@ -56,9 +60,19 @@ Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA
Note 2: DH automatically sets the \-k flag.
.RE
.PP
+\-3
+.RS 4
+Use an NSEC3\-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Specifies the name of the crypto hardware (OpenSSL engine). When compiled with PKCS#11 support it defaults to "pkcs11".
+.RE
+.PP
\-l \fIlabel\fR
.RS 4
-Specifies the label of keys in the crypto hardware (PKCS#11 device).
+Specifies the label of the key pair in the crypto hardware. The label may be preceded by an optional OpenSSL engine name, separated by a colon, as in "pkcs11:keylabel".
.RE
.PP
\-n \fInametype\fR
@@ -68,6 +82,15 @@ Specifies the owner type of the key. The value of
must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive.
.RE
.PP
+\-C
+.RS 4
+Compatibility mode: generates an old\-style key, without any metadata. By default,
+\fBdnssec\-keyfromlabel\fR
+will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the
+\fB\-C\fR
+option suppresses them.
+.RE
+.PP
\-c \fIclass\fR
.RS 4
Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used.
@@ -75,13 +98,23 @@ Indicates that the DNS record containing the key should have the specified class
.PP
\-f \fIflag\fR
.RS 4
-Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flag is KSK (Key Signing Key) DNSKEY.
+Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.
+.RE
+.PP
+\-G
+.RS 4
+Generate a key, but do not publish it or sign with it. This option is incompatible with \-P and \-A.
.RE
.PP
\-h
.RS 4
Prints a short summary of the options and arguments to
-\fBdnssec\-keygen\fR.
+\fBdnssec\-keyfromlabel\fR.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to be written.
.RE
.PP
\-k
@@ -91,7 +124,7 @@ Generate KEY records rather than DNSKEY records.
.PP
\-p \fIprotocol\fR
.RS 4
-Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.
+Sets the protocol value for the key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.
.RE
.PP
\-t \fItype\fR
@@ -105,6 +138,39 @@ must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF.
.RS 4
Sets the debugging level.
.RE
+.PP
+\-y
+.RS 4
+Allows DNSSEC key files to be generated even if the key ID would collide with that of an existing key, in the event of either key being revoked. (This is only safe to use if you are sure you won't be using RFC 5011 trust anchor maintenance with either of the keys involved.)
+.RE
+.SH "TIMING OPTIONS"
+.PP
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds.
+.PP
+\-P \fIdate/offset\fR
+.RS 4
+Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-A \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-R \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.
+.RE
+.PP
+\-I \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.
+.RE
+.PP
+\-D \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)
+.RE
.SH "GENERATED KEY FILES"
.PP
When
@@ -138,7 +204,7 @@ file contains a DNS KEY record that can be inserted into a zone file (directly o
.PP
The
\fI.private\fR
-file contains algorithm specific fields. For obvious security reasons, this file does not have general read permission.
+file contains algorithm\-specific fields. For obvious security reasons, this file does not have general read permission.
.SH "SEE ALSO"
.PP
\fBdnssec\-keygen\fR(8),
@@ -149,5 +215,5 @@ RFC 4034.
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2008\-2011 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c
index 8e9a53bb798e..323f9187c64a 100644
--- a/bin/dnssec/dnssec-keyfromlabel.c
+++ b/bin/dnssec/dnssec-keyfromlabel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2007-2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,12 +14,13 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keyfromlabel.c,v 1.4.50.2 2010-01-15 23:47:31 tbox Exp $ */
+/* $Id: dnssec-keyfromlabel.c,v 1.32 2010-12-23 04:07:59 marka Exp $ */
/*! \file */
#include <config.h>
+#include <ctype.h>
#include <stdlib.h>
#include <isc/buffer.h>
@@ -27,9 +28,11 @@
#include <isc/entropy.h>
#include <isc/mem.h>
#include <isc/region.h>
+#include <isc/print.h>
#include <isc/string.h>
#include <isc/util.h>
+#include <dns/dnssec.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/log.h>
@@ -47,35 +50,60 @@
const char *program = "dnssec-keyfromlabel";
int verbose;
+#define DEFAULT_ALGORITHM "RSASHA1"
+#define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1"
+
static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 |"
" NSEC3DSA | NSEC3RSASHA1 |"
- " RSASHA256 | RSASHA512";
+ " RSASHA256 | RSASHA512 | ECCGOST";
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
static void
usage(void) {
fprintf(stderr, "Usage:\n");
- fprintf(stderr, " %s -a alg -l label [options] name\n\n",
+ fprintf(stderr, " %s -l label [options] name\n\n",
program);
fprintf(stderr, "Version: %s\n", VERSION);
fprintf(stderr, "Required options:\n");
- fprintf(stderr, " -a algorithm: %s\n", algs);
- fprintf(stderr, " -l label: label of the key\n");
+ fprintf(stderr, " -l label: label of the key pair\n");
fprintf(stderr, " name: owner of the key\n");
fprintf(stderr, "Other options:\n");
+ fprintf(stderr, " -a algorithm: %s\n", algs);
+ fprintf(stderr, " (default: RSASHA1, or "
+ "NSEC3RSASHA1 if using -3)\n");
+ fprintf(stderr, " -3: use NSEC3-capable algorithm\n");
+ fprintf(stderr, " -c class (default: IN)\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E enginename (default: pkcs11)\n");
+#else
+ fprintf(stderr, " -E enginename\n");
+#endif
+ fprintf(stderr, " -f keyflag: KSK | REVOKE\n");
+ fprintf(stderr, " -K directory: directory in which to place "
+ "key files\n");
+ fprintf(stderr, " -k: generate a TYPE=KEY key\n");
fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n");
fprintf(stderr, " (DNSKEY generation defaults to ZONE\n");
- fprintf(stderr, " -c <class> (default: IN)\n");
- fprintf(stderr, " -f keyflag: KSK\n");
- fprintf(stderr, " -t <type>: "
+ fprintf(stderr, " -p protocol: default: 3 [dnssec]\n");
+ fprintf(stderr, " -t type: "
"AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
"(default: AUTHCONF)\n");
- fprintf(stderr, " -p <protocol>: "
- "default: 3 [dnssec]\n");
- fprintf(stderr, " -v <verbose level>\n");
- fprintf(stderr, " -k : generate a TYPE=KEY key\n");
+ fprintf(stderr, " -y: permit keys that might collide\n");
+ fprintf(stderr, " -v verbose level\n");
+ fprintf(stderr, "Date options:\n");
+ fprintf(stderr, " -P date/[+-]offset: set key publication date\n");
+ fprintf(stderr, " -A date/[+-]offset: set key activation date\n");
+ fprintf(stderr, " -R date/[+-]offset: set key revocation date\n");
+ fprintf(stderr, " -I date/[+-]offset: set key inactivation date\n");
+ fprintf(stderr, " -D date/[+-]offset: set key deletion date\n");
+ fprintf(stderr, " -G: generate key only; do not set -P or -A\n");
+ fprintf(stderr, " -C: generate a backward-compatible key, omitting"
+ " all dates\n");
fprintf(stderr, "Output:\n");
fprintf(stderr, " K<name>+<alg>+<id>.key, "
- "K<name>+<alg>+<id>.private\n");
+ "K<name>+<alg>+<id>.private\n");
exit (-1);
}
@@ -83,14 +111,20 @@ usage(void) {
int
main(int argc, char **argv) {
char *algname = NULL, *nametype = NULL, *type = NULL;
+ const char *directory = NULL;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
char *classname = NULL;
char *endp;
- dst_key_t *key = NULL, *oldkey;
+ dst_key_t *key = NULL;
dns_fixedname_t fname;
dns_name_t *name;
- isc_uint16_t flags = 0, ksk = 0;
+ isc_uint16_t flags = 0, kskflag = 0, revflag = 0;
dns_secalg_t alg;
- isc_boolean_t null_key = ISC_FALSE;
+ isc_boolean_t oldstyle = ISC_FALSE;
isc_mem_t *mctx = NULL;
int ch;
int protocol = -1, signatory = 0;
@@ -103,6 +137,20 @@ main(int argc, char **argv) {
dns_rdataclass_t rdclass;
int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC;
char *label = NULL;
+ isc_stdtime_t publish = 0, activate = 0, revoke = 0;
+ isc_stdtime_t inactive = 0, delete = 0;
+ isc_stdtime_t now;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
+ isc_boolean_t genonly = ISC_FALSE;
+ isc_boolean_t use_nsec3 = ISC_FALSE;
+ isc_boolean_t avoid_collisions = ISC_TRUE;
+ isc_boolean_t exact;
+ unsigned char c;
if (argc == 1)
usage();
@@ -113,28 +161,49 @@ main(int argc, char **argv) {
isc_commandline_errprint = ISC_FALSE;
+ isc_stdtime_get(&now);
+
while ((ch = isc_commandline_parse(argc, argv,
- "a:c:f:kl:n:p:t:v:h")) != -1)
+ "3a:Cc:E:f:K:kl:n:p:t:v:yFhGP:A:R:I:D:")) != -1)
{
switch (ch) {
+ case '3':
+ use_nsec3 = ISC_TRUE;
+ break;
case 'a':
algname = isc_commandline_argument;
break;
+ case 'C':
+ oldstyle = ISC_TRUE;
+ break;
case 'c':
classname = isc_commandline_argument;
break;
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
case 'f':
- if (strcasecmp(isc_commandline_argument, "KSK") == 0)
- ksk = DNS_KEYFLAG_KSK;
+ c = (unsigned char)(isc_commandline_argument[0]);
+ if (toupper(c) == 'K')
+ kskflag = DNS_KEYFLAG_KSK;
+ else if (toupper(c) == 'R')
+ revflag = DNS_KEYFLAG_REVOKE;
else
fatal("unknown flag '%s'",
isc_commandline_argument);
break;
+ case 'K':
+ directory = isc_commandline_argument;
+ ret = try_dir(directory);
+ if (ret != ISC_R_SUCCESS)
+ fatal("cannot open directory %s: %s",
+ directory, isc_result_totext(ret));
+ break;
case 'k':
options |= DST_TYPE_KEY;
break;
case 'l':
- label = isc_commandline_argument;
+ label = isc_mem_strdup(mctx, isc_commandline_argument);
break;
case 'n':
nametype = isc_commandline_argument;
@@ -153,11 +222,80 @@ main(int argc, char **argv) {
if (*endp != '\0')
fatal("-v must be followed by a number");
break;
-
+ case 'y':
+ avoid_collisions = ISC_FALSE;
+ break;
+ case 'G':
+ genonly = ISC_TRUE;
+ break;
+ case 'P':
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setpub = ISC_TRUE;
+ publish = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetpub = ISC_TRUE;
+ }
+ break;
+ case 'A':
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setact = ISC_TRUE;
+ activate = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetact = ISC_TRUE;
+ }
+ break;
+ case 'R':
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setrev = ISC_TRUE;
+ revoke = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetrev = ISC_TRUE;
+ }
+ break;
+ case 'I':
+ if (setinact || unsetinact)
+ fatal("-I specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setinact = ISC_TRUE;
+ inactive = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetinact = ISC_TRUE;
+ }
+ break;
+ case 'D':
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setdel = ISC_TRUE;
+ delete = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetdel = ISC_TRUE;
+ }
+ break;
+ case 'F':
+ /* Reserved for FIPS mode */
+ /* FALLTHROUGH */
case '?':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
program, isc_commandline_option);
+ /* FALLTHROUGH */
case 'h':
usage();
@@ -170,10 +308,11 @@ main(int argc, char **argv) {
if (ectx == NULL)
setup_entropy(mctx, NULL, &ectx);
- ret = dst_lib_init(mctx, ectx,
- ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ ret = dst_lib_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
if (ret != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(ret));
setup_logging(verbose, mctx, &log);
@@ -184,8 +323,30 @@ main(int argc, char **argv) {
if (argc > isc_commandline_index + 1)
fatal("extraneous arguments");
- if (algname == NULL)
- fatal("no algorithm was specified");
+ if (strchr(label, ':') == NULL &&
+ engine != NULL && strlen(engine) != 0U) {
+ char *l;
+ int len;
+
+ len = strlen(label) + strlen(engine) + 2;
+ l = isc_mem_allocate(mctx, len);
+ if (l == NULL)
+ fatal("cannot allocate memory");
+ snprintf(l, len, "%s:%s", engine, label);
+ isc_mem_free(mctx, label);
+ label = l;
+ }
+
+ if (algname == NULL) {
+ if (use_nsec3)
+ algname = strdup(DEFAULT_NSEC3_ALGORITHM);
+ else
+ algname = strdup(DEFAULT_ALGORITHM);
+ if (verbose > 0)
+ fprintf(stderr, "no algorithm specified; "
+ "defaulting to %s\n", algname);
+ }
+
if (strcasecmp(algname, "RSA") == 0) {
fprintf(stderr, "The use of RSA (RSAMD5) is not recommended.\n"
"If you still wish to use RSA (RSAMD5) please "
@@ -201,6 +362,14 @@ main(int argc, char **argv) {
options |= DST_TYPE_KEY;
}
+ if (use_nsec3 &&
+ alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 &&
+ alg != DST_ALG_RSASHA256 && alg != DST_ALG_RSASHA512 &&
+ alg != DST_ALG_ECCGOST) {
+ fatal("%s is incompatible with NSEC3; "
+ "do not use the -3 option", algname);
+ }
+
if (type != NULL && (options & DST_TYPE_KEY) != 0) {
if (strcasecmp(type, "NOAUTH") == 0)
flags |= DNS_KEYTYPE_NOAUTH;
@@ -234,10 +403,15 @@ main(int argc, char **argv) {
rdclass = strtoclass(classname);
+ if (directory == NULL)
+ directory = ".";
+
if ((options & DST_TYPE_KEY) != 0) /* KEY */
flags |= signatory;
- else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */
- flags |= ksk;
+ else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */
+ flags |= kskflag;
+ flags |= revflag;
+ }
if (protocol == -1)
protocol = DNS_KEYPROTO_DNSSEC;
@@ -260,53 +434,108 @@ main(int argc, char **argv) {
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);
+ ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
if (ret != ISC_R_SUCCESS)
fatal("invalid key name %s: %s", argv[isc_commandline_index],
isc_result_totext(ret));
- if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY)
- null_key = ISC_TRUE;
-
isc_buffer_init(&buf, filename, sizeof(filename) - 1);
/* associate the key */
ret = dst_key_fromlabel(name, alg, flags, protocol,
- rdclass, "", label, NULL, mctx, &key);
+ rdclass, engine, label, NULL, mctx, &key);
isc_entropy_stopcallbacksources(ectx);
if (ret != ISC_R_SUCCESS) {
char namestr[DNS_NAME_FORMATSIZE];
- char algstr[ALG_FORMATSIZE];
+ char algstr[DNS_SECALG_FORMATSIZE];
dns_name_format(name, namestr, sizeof(namestr));
- alg_format(alg, algstr, sizeof(algstr));
- fatal("failed to generate key %s/%s: %s\n",
+ dns_secalg_format(alg, algstr, sizeof(algstr));
+ fatal("failed to get key %s/%s: %s\n",
namestr, algstr, isc_result_totext(ret));
+ /* NOTREACHED */
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.
+ * Set key timing metadata (unless using -C)
+ *
+ * Publish and activation dates are set to "now" by default, but
+ * can be overridden. Creation date is always set to "now".
*/
- 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) {
+ if (!oldstyle) {
+ dst_key_settime(key, DST_TIME_CREATED, now);
+
+ if (genonly && (setpub || setact))
+ fatal("cannot use -G together with -P or -A options");
+
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, publish);
+ else if (setact)
+ dst_key_settime(key, DST_TIME_PUBLISH, activate);
+ else if (!genonly && !unsetpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, now);
+
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, activate);
+ else if (!genonly && !unsetact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, now);
+
+ if (setrev) {
+ if (kskflag == 0)
+ fprintf(stderr, "%s: warning: Key is "
+ "not flagged as a KSK, but -R "
+ "was used. Revoking a ZSK is "
+ "legal, but undefined.\n",
+ program);
+ dst_key_settime(key, DST_TIME_REVOKE, revoke);
+ }
+
+ if (setinact)
+ dst_key_settime(key, DST_TIME_INACTIVE, inactive);
+
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, delete);
+ } else {
+ if (setpub || setact || setrev || setinact ||
+ setdel || unsetpub || unsetact ||
+ unsetrev || unsetinact || unsetdel || genonly)
+ fatal("cannot use -C together with "
+ "-P, -A, -R, -I, -D, or -G options");
+ /*
+ * Compatibility mode: Private-key-format
+ * should be set to 1.2.
+ */
+ dst_key_setprivateformat(key, 1, 2);
+ }
+
+ /*
+ * Do not overwrite an existing key. Warn LOUDLY if there
+ * is a risk of ID collision due to this key or another key
+ * being revoked.
+ */
+ if (key_collision(dst_key_id(key), name, directory, alg, mctx, &exact))
+ {
isc_buffer_clear(&buf);
- ret = dst_key_buildfilename(key, 0, NULL, &buf);
- fprintf(stderr, "%s: %s already exists\n",
- program, filename);
- dst_key_free(&key);
- exit (1);
+ ret = dst_key_buildfilename(key, 0, directory, &buf);
+ if (exact)
+ fatal("%s: %s already exists\n", program, filename);
+
+ if (avoid_collisions)
+ fatal("%s: %s could collide with another key upon "
+ "revokation\n", program, filename);
+
+ fprintf(stderr, "%s: WARNING: Key %s could collide with "
+ "another key upon revokation. If you plan "
+ "to revoke keys, destroy this key and "
+ "generate a different one.\n",
+ program, filename);
}
- ret = dst_key_tofile(key, options, NULL);
+ ret = dst_key_tofile(key, options, directory);
if (ret != ISC_R_SUCCESS) {
- char keystr[KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ char keystr[DST_KEY_FORMATSIZE];
+ dst_key_format(key, keystr, sizeof(keystr));
fatal("failed to write key %s: %s\n", keystr,
isc_result_totext(ret));
}
@@ -322,6 +551,7 @@ main(int argc, char **argv) {
dns_name_destroy();
if (verbose > 10)
isc_mem_stats(mctx, stdout);
+ isc_mem_free(mctx, label);
isc_mem_destroy(&mctx);
return (0);
diff --git a/bin/dnssec/dnssec-keyfromlabel.docbook b/bin/dnssec/dnssec-keyfromlabel.docbook
index a2fff5a0d4b5..be38a2465785 100644
--- a/bin/dnssec/dnssec-keyfromlabel.docbook
+++ b/bin/dnssec/dnssec-keyfromlabel.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2008-2011 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keyfromlabel.docbook,v 1.6.14.2 2010-01-15 23:47:31 tbox Exp $ -->
+<!-- $Id: dnssec-keyfromlabel.docbook,v 1.18.14.1.2.1 2011-06-02 23:47:27 tbox Exp $ -->
<refentry id="man.dnssec-keyfromlabel">
<refentryinfo>
<date>February 8, 2008</date>
@@ -37,7 +37,9 @@
<docinfo>
<copyright>
<year>2008</year>
+ <year>2009</year>
<year>2010</year>
+ <year>2011</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -45,15 +47,25 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>dnssec-keyfromlabel</command>
- <arg choice="req">-a <replaceable class="parameter">algorithm</replaceable></arg>
<arg choice="req">-l <replaceable class="parameter">label</replaceable></arg>
+ <arg><option>-3</option></arg>
+ <arg><option>-a <replaceable class="parameter">algorithm</replaceable></option></arg>
+ <arg><option>-A <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
+ <arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
<arg><option>-f <replaceable class="parameter">flag</replaceable></option></arg>
+ <arg><option>-G</option></arg>
+ <arg><option>-I <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-k</option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
<arg><option>-n <replaceable class="parameter">nametype</replaceable></option></arg>
+ <arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-p <replaceable class="parameter">protocol</replaceable></option></arg>
+ <arg><option>-R <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-t <replaceable class="parameter">type</replaceable></option></arg>
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-y</option></arg>
<arg choice="req">name</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -65,6 +77,11 @@
key files for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034.
</para>
+ <para>
+ The <option>name</option> of the key is specified on the command
+ line. This must match the name of the zone for which the key is
+ being generated.
+ </para>
</refsect1>
<refsect1>
@@ -76,9 +93,8 @@
<listitem>
<para>
Selects the cryptographic algorithm. The value of
- <option>algorithm</option> must be one of RSAMD5,
- RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256,
- RSASHA512 or DH (Diffie Hellman).
+ <option>algorithm</option> must be one of RSAMD5, RSASHA1,
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
These values are case insensitive.
</para>
<para>
@@ -99,11 +115,34 @@
</varlistentry>
<varlistentry>
+ <term>-3</term>
+ <listitem>
+ <para>
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-E <replaceable class="parameter">engine</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the name of the crypto hardware (OpenSSL engine).
+ When compiled with PKCS#11 support it defaults to "pkcs11".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-l <replaceable class="parameter">label</replaceable></term>
<listitem>
<para>
- Specifies the label of keys in the crypto hardware
- (PKCS#11 device).
+ Specifies the label of the key pair in the crypto hardware.
+ The label may be preceded by an optional OpenSSL engine name,
+ separated by a colon, as in "pkcs11:keylabel".
</para>
</listitem>
</varlistentry>
@@ -117,8 +156,22 @@
zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
a host (KEY)),
USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
- These values are
- case insensitive.
+ These values are case insensitive.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-C</term>
+ <listitem>
+ <para>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <command>dnssec-keyfromlabel</command>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <option>-C</option> option suppresses them.
</para>
</listitem>
</varlistentry>
@@ -138,7 +191,17 @@
<listitem>
<para>
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-G</term>
+ <listitem>
+ <para>
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
</para>
</listitem>
</varlistentry>
@@ -148,7 +211,16 @@
<listitem>
<para>
Prints a short summary of the options and arguments to
- <command>dnssec-keygen</command>.
+ <command>dnssec-keyfromlabel</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Sets the directory in which the key files are to be written.
</para>
</listitem>
</varlistentry>
@@ -166,7 +238,7 @@
<term>-p <replaceable class="parameter">protocol</replaceable></term>
<listitem>
<para>
- Sets the protocol value for the generated key. The protocol
+ Sets the protocol value for the key. The protocol
is a number between 0 and 255. The default is 3 (DNSSEC).
Other possible values for this argument are listed in
RFC 2535 and its successors.
@@ -195,6 +267,93 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>-y</term>
+ <listitem>
+ <para>
+ Allows DNSSEC key files to be generated even if the key ID
+ would collide with that of an existing key, in the event of
+ either key being revoked. (This is only safe to use if you
+ are sure you won't be using RFC 5011 trust anchor maintenance
+ with either of the keys involved.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>TIMING OPTIONS</title>
+
+ <para>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-P <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-R <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-I <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-D <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
@@ -214,8 +373,7 @@
</listitem>
<listitem>
<para><filename>aaa</filename> is the numeric representation
- of the
- algorithm.
+ of the algorithm.
</para>
</listitem>
<listitem>
@@ -229,8 +387,7 @@
on the printed string. <filename>Knnnn.+aaa+iiiii.key</filename>
contains the public key, and
<filename>Knnnn.+aaa+iiiii.private</filename> contains the
- private
- key.
+ private key.
</para>
<para>
The <filename>.key</filename> file contains a DNS KEY record
@@ -239,8 +396,8 @@
statement).
</para>
<para>
- The <filename>.private</filename> file contains algorithm
- specific
+ The <filename>.private</filename> file contains
+ algorithm-specific
fields. For obvious security reasons, this file does not have
general read permission.
</para>
diff --git a/bin/dnssec/dnssec-keyfromlabel.html b/bin/dnssec/dnssec-keyfromlabel.html
index ad2a5621ba99..2b1b23690bb1 100644
--- a/bin/dnssec/dnssec-keyfromlabel.html
+++ b/bin/dnssec/dnssec-keyfromlabel.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2008-2011 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -13,7 +13,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keyfromlabel.html,v 1.5.44.3 2010-01-16 01:55:32 tbox Exp $ -->
+<!-- $Id: dnssec-keyfromlabel.html,v 1.17.14.1.2.1 2011-06-09 03:41:05 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -28,26 +28,30 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-k</code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-3</code>] [<code class="option">-a <em class="replaceable"><code>algorithm</code></em></code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-G</code>] [<code class="option">-I <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-k</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-y</code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543416"></a><h2>DESCRIPTION</h2>
+<a name="id2543494"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keyfromlabel</strong></span>
gets keys with the given label from a crypto hardware and builds
key files for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034.
</p>
+<p>
+ The <code class="option">name</code> of the key is specified on the command
+ line. This must match the name of the zone for which the key is
+ being generated.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543428"></a><h2>OPTIONS</h2>
+<a name="id2543512"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
<p>
Selects the cryptographic algorithm. The value of
- <code class="option">algorithm</code> must be one of RSAMD5,
- RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256,
- RSASHA512 or DH (Diffie Hellman).
+ <code class="option">algorithm</code> must be one of RSAMD5, RSASHA1,
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
These values are case insensitive.
</p>
<p>
@@ -65,10 +69,23 @@
Note 2: DH automatically sets the -k flag.
</p>
</dd>
+<dt><span class="term">-3</span></dt>
+<dd><p>
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default.
+ </p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Specifies the name of the crypto hardware (OpenSSL engine).
+ When compiled with PKCS#11 support it defaults to "pkcs11".
+ </p></dd>
<dt><span class="term">-l <em class="replaceable"><code>label</code></em></span></dt>
<dd><p>
- Specifies the label of keys in the crypto hardware
- (PKCS#11 device).
+ Specifies the label of the key pair in the crypto hardware.
+ The label may be preceded by an optional OpenSSL engine name,
+ separated by a colon, as in "pkcs11:keylabel".
</p></dd>
<dt><span class="term">-n <em class="replaceable"><code>nametype</code></em></span></dt>
<dd><p>
@@ -77,8 +94,17 @@
zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
a host (KEY)),
USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
- These values are
- case insensitive.
+ These values are case insensitive.
+ </p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <span><strong class="command">dnssec-keyfromlabel</strong></span>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <code class="option">-C</code> option suppresses them.
</p></dd>
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
<dd><p>
@@ -88,12 +114,21 @@
<dt><span class="term">-f <em class="replaceable"><code>flag</code></em></span></dt>
<dd><p>
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+ </p></dd>
+<dt><span class="term">-G</span></dt>
+<dd><p>
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
</p></dd>
<dt><span class="term">-h</span></dt>
<dd><p>
Prints a short summary of the options and arguments to
- <span><strong class="command">dnssec-keygen</strong></span>.
+ <span><strong class="command">dnssec-keyfromlabel</strong></span>.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to be written.
</p></dd>
<dt><span class="term">-k</span></dt>
<dd><p>
@@ -101,7 +136,7 @@
</p></dd>
<dt><span class="term">-p <em class="replaceable"><code>protocol</code></em></span></dt>
<dd><p>
- Sets the protocol value for the generated key. The protocol
+ Sets the protocol value for the key. The protocol
is a number between 0 and 255. The default is 3 (DNSSEC).
Other possible values for this argument are listed in
RFC 2535 and its successors.
@@ -117,10 +152,65 @@
<dd><p>
Sets the debugging level.
</p></dd>
+<dt><span class="term">-y</span></dt>
+<dd><p>
+ Allows DNSSEC key files to be generated even if the key ID
+ would collide with that of an existing key, in the event of
+ either key being revoked. (This is only safe to use if you
+ are sure you won't be using RFC 5011 trust anchor maintenance
+ with either of the keys involved.)
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543876"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-I <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </p></dd>
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543632"></a><h2>GENERATED KEY FILES</h2>
+<a name="id2544042"></a><h2>GENERATED KEY FILES</h2>
<p>
When <span><strong class="command">dnssec-keyfromlabel</strong></span> completes
successfully,
@@ -132,8 +222,7 @@
<li><p><code class="filename">nnnn</code> is the key name.
</p></li>
<li><p><code class="filename">aaa</code> is the numeric representation
- of the
- algorithm.
+ of the algorithm.
</p></li>
<li><p><code class="filename">iiiii</code> is the key identifier (or
footprint).
@@ -144,8 +233,7 @@
on the printed string. <code class="filename">Knnnn.+aaa+iiiii.key</code>
contains the public key, and
<code class="filename">Knnnn.+aaa+iiiii.private</code> contains the
- private
- key.
+ private key.
</p>
<p>
The <code class="filename">.key</code> file contains a DNS KEY record
@@ -154,14 +242,14 @@
statement).
</p>
<p>
- The <code class="filename">.private</code> file contains algorithm
- specific
+ The <code class="filename">.private</code> file contains
+ algorithm-specific
fields. For obvious security reasons, this file does not have
general read permission.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543704"></a><h2>SEE ALSO</h2>
+<a name="id2544115"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
@@ -169,7 +257,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543737"></a><h2>AUTHOR</h2>
+<a name="id2544148"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/dnssec/dnssec-keygen.8 b/bin/dnssec/dnssec-keygen.8
index c4be24eba0cf..ea4690eb71a1 100644
--- a/bin/dnssec/dnssec-keygen.8
+++ b/bin/dnssec/dnssec-keygen.8
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-keygen.8,v 1.40.44.4 2010-01-16 01:55:32 tbox Exp $
+.\" $Id: dnssec-keygen.8,v 1.55 2010-12-24 01:14:19 tbox Exp $
.\"
.hy 0
.ad l
@@ -33,11 +33,11 @@
dnssec\-keygen \- DNSSEC key generation tool
.SH "SYNOPSIS"
.HP 14
-\fBdnssec\-keygen\fR {\-a\ \fIalgorithm\fR} {\-b\ \fIkeysize\fR} {\-n\ \fInametype\fR} [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-e\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-k\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] {name}
+\fBdnssec\-keygen\fR [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-b\ \fR\fB\fIkeysize\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-3\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-C\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-e\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-q\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\ \fR\fB\fIkey\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] {name}
.SH "DESCRIPTION"
.PP
\fBdnssec\-keygen\fR
-generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures), as defined in RFC 2845.
+generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY (Transaction Key) as defined in RFC 2930.
.PP
The
\fBname\fR
@@ -48,16 +48,28 @@ of the key is specified on the command line. For DNSSEC keys, this must match th
.RS 4
Selects the cryptographic algorithm. For DNSSEC keys, the value of
\fBalgorithm\fR
-must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC\-MD5, HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256, HMAC\-SHA384, or HMAC\-SHA512. These values are case insensitive.
+must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC\-MD5, HMAC\-SHA1, HMAC\-SHA224, HMAC\-SHA256, HMAC\-SHA384, or HMAC\-SHA512. These values are case insensitive.
+.sp
+If no algorithm is specified, then RSASHA1 will be used by default, unless the
+\fB\-3\fR
+option is specified, in which case NSEC3RSASHA1 will be used instead. (If
+\fB\-3\fR
+is used and an algorithm is specified, that algorithm will be checked for compatibility with NSEC3.)
.sp
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement algorithm, and DSA is recommended. For TSIG, HMAC\-MD5 is mandatory.
.sp
-Note 2: HMAC\-MD5 and DH automatically set the \-k flag.
+Note 2: DH, HMAC\-MD5, and HMAC\-SHA1 through HMAC\-SHA512 automatically set the \-T KEY option.
.RE
.PP
\-b \fIkeysize\fR
.RS 4
Specifies the number of bits in the key. The choice of key size depends on the algorithm used. 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 keys must be between 1 and 512 bits.
+.sp
+The key size does not need to be specified if using a default algorithm. The default key size is 1024 bits for zone signing keys (ZSK's) and 2048 bits for key signing keys (KSK's, generated with
+\fB\-f KSK\fR). However, if an algorithm is explicitly specified with the
+\fB\-a\fR, then there is no default key size, and the
+\fB\-b\fR
+must be used.
.RE
.PP
\-n \fInametype\fR
@@ -67,11 +79,30 @@ Specifies the owner type of the key. The value of
must either be ZONE (for a DNSSEC zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with a host (KEY)), USER (for a key associated with a user(KEY)) or OTHER (DNSKEY). These values are case insensitive. Defaults to ZONE for DNSKEY generation.
.RE
.PP
+\-3
+.RS 4
+Use an NSEC3\-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms are NSEC3\-capable.
+.RE
+.PP
+\-C
+.RS 4
+Compatibility mode: generates an old\-style key, without any metadata. By default,
+\fBdnssec\-keygen\fR
+will include the key's creation date in the metadata stored with the private key, and other dates may be set there as well (publication date, activation date, etc). Keys that include this data may be incompatible with older versions of BIND; the
+\fB\-C\fR
+option suppresses them.
+.RE
+.PP
\-c \fIclass\fR
.RS 4
Indicates that the DNS record containing the key should have the specified class. If not specified, class IN is used.
.RE
.PP
+\-E \fIengine\fR
+.RS 4
+Uses a crypto hardware (OpenSSL engine) for random number and, when supported, key generation. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
+.RE
+.PP
\-e
.RS 4
If generating an RSAMD5/RSASHA1 key, use a large exponent.
@@ -79,7 +110,12 @@ If generating an RSAMD5/RSASHA1 key, use a large exponent.
.PP
\-f \fIflag\fR
.RS 4
-Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flag is KSK (Key Signing Key) DNSKEY.
+Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE.
+.RE
+.PP
+\-G
+.RS 4
+Generate a key, but do not publish it or sign with it. This option is incompatible with \-P and \-A.
.RE
.PP
\-g \fIgenerator\fR
@@ -93,9 +129,14 @@ Prints a short summary of the options and arguments to
\fBdnssec\-keygen\fR.
.RE
.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to be written.
+.RE
+.PP
\-k
.RS 4
-Generate KEY records rather than DNSKEY records.
+Deprecated in favor of \-T KEY.
.RE
.PP
\-p \fIprotocol\fR
@@ -103,6 +144,15 @@ Generate KEY records rather than DNSKEY records.
Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors.
.RE
.PP
+\-q
+.RS 4
+Quiet mode: Suppresses unnecessary output, including progress indication. Without this option, when
+\fBdnssec\-keygen\fR
+is run interactively to generate an RSA or DSA key pair, it will print a string of symbols to
+\fIstderr\fR
+indicating the progress of the key generation. A '.' indicates that a random number has been found which passed an initial sieve test; '+' means a number has passed a single round of the Miller\-Rabin primality test; a space means that the number has passed all the tests and is a satisfactory key.
+.RE
+.PP
\-r \fIrandomdev\fR
.RS 4
Specifies the source of randomness. If the operating system does not provide a
@@ -114,11 +164,24 @@ specifies the name of a character device or file containing random data to be us
indicates that keyboard input should be used.
.RE
.PP
+\-S \fIkey\fR
+.RS 4
+Create a new key which is an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the existing key. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.
+.RE
+.PP
\-s \fIstrength\fR
.RS 4
Specifies the strength value of the key. The strength is a number between 0 and 15, and currently has no defined purpose in DNSSEC.
.RE
.PP
+\-T \fIrrtype\fR
+.RS 4
+Specifies the resource record type to use for the key.
+\fBrrtype\fR
+must be either DNSKEY or KEY. The default is DNSKEY when using a DNSSEC algorithm, but it can be overridden to KEY for use with SIG(0).
+Using any TSIG algorithm (HMAC\-* or DH) forces this option to KEY.
+.RE
+.PP
\-t \fItype\fR
.RS 4
Indicates the use of the key.
@@ -130,6 +193,43 @@ must be one of AUTHCONF, NOAUTHCONF, NOAUTH, or NOCONF. The default is AUTHCONF.
.RS 4
Sets the debugging level.
.RE
+.SH "TIMING OPTIONS"
+.PP
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds.
+.PP
+\-P \fIdate/offset\fR
+.RS 4
+Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-A \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it. If not set, and if the \-G option has not been used, the default is "now".
+.RE
+.PP
+\-R \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.
+.RE
+.PP
+\-I \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.
+.RE
+.PP
+\-D \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)
+.RE
+.PP
+\-i \fIinterval\fR
+.RS 4
+Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.
+.sp
+If the key is being created as an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.
+.sp
+As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.
+.RE
.SH "GENERATED KEYS"
.PP
When
diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c
index 21841227d439..f369326aaf82 100644
--- a/bin/dnssec/dnssec-keygen.c
+++ b/bin/dnssec/dnssec-keygen.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -29,13 +29,15 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-keygen.c,v 1.81.48.2 2010-01-15 23:47:31 tbox Exp $ */
+/* $Id: dnssec-keygen.c,v 1.115 2010-12-23 04:07:59 marka Exp $ */
/*! \file */
#include <config.h>
+#include <ctype.h>
#include <stdlib.h>
+#include <unistd.h>
#include <isc/buffer.h>
#include <isc/commandline.h>
@@ -45,6 +47,7 @@
#include <isc/string.h>
#include <isc/util.h>
+#include <dns/dnssec.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/log.h>
@@ -62,103 +65,224 @@
const char *program = "dnssec-keygen";
int verbose;
-static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 | RSASHA256 |"
- " RSASHA512 | NSEC3DSA | NSEC3RSASHA1 | HMAC-MD5 |"
- " HMAC-SHA1 | HMAC-SHA224 | HMAC-SHA256 |"
- " HMAC-SHA384 | HMAC-SHA512";
+#define DEFAULT_ALGORITHM "RSASHA1"
+#define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1"
-static isc_boolean_t
-dsa_size_ok(int size) {
- return (ISC_TF(size >= 512 && size <= 1024 && size % 64 == 0));
-}
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void progress(int p);
static void
usage(void) {
fprintf(stderr, "Usage:\n");
- fprintf(stderr, " %s -a alg -b bits [-n type] [options] name\n\n",
- program);
+ fprintf(stderr, " %s [options] name\n\n", program);
fprintf(stderr, "Version: %s\n", VERSION);
- fprintf(stderr, "Required options:\n");
- fprintf(stderr, " -a algorithm: %s\n", algs);
- fprintf(stderr, " -b key size, in bits:\n");
- fprintf(stderr, " RSAMD5:\t\t[512..%d]\n", MAX_RSA);
- fprintf(stderr, " RSASHA1:\t\t[512..%d]\n", MAX_RSA);
- fprintf(stderr, " NSEC3RSASHA1:\t\t[512..%d]\n", MAX_RSA);
- fprintf(stderr, " RSASHA256:\t[512..%d]\n", MAX_RSA);
- fprintf(stderr, " RSASHA512:\t[1024..%d]\n", MAX_RSA);
+ fprintf(stderr, " name: owner of the key\n");
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -K <directory>: write keys into directory\n");
+ fprintf(stderr, " -a <algorithm>:\n");
+ fprintf(stderr, " RSA | RSAMD5 | DSA | RSASHA1 | NSEC3RSASHA1"
+ " | NSEC3DSA |\n");
+ fprintf(stderr, " RSASHA256 | RSASHA512 | ECCGOST |\n");
+ fprintf(stderr, " DH | HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | "
+ "HMAC-SHA256 | \n");
+ fprintf(stderr, " HMAC-SHA384 | HMAC-SHA512\n");
+ fprintf(stderr, " (default: RSASHA1, or "
+ "NSEC3RSASHA1 if using -3)\n");
+ fprintf(stderr, " -3: use NSEC3-capable algorithm\n");
+ fprintf(stderr, " -b <key size in bits>:\n");
+ fprintf(stderr, " RSAMD5:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA1:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " NSEC3RSASHA1:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA256:\t[512..%d]\n", MAX_RSA);
+ fprintf(stderr, " RSASHA512:\t[1024..%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, " NSEC3DSA:\t\t[512..1024] and divisible by 64\n");
+ fprintf(stderr, " NSEC3DSA:\t[512..1024] and divisible "
+ "by 64\n");
+ fprintf(stderr, " ECCGOST:\tignored\n");
fprintf(stderr, " HMAC-MD5:\t[1..512]\n");
fprintf(stderr, " HMAC-SHA1:\t[1..160]\n");
fprintf(stderr, " HMAC-SHA224:\t[1..224]\n");
fprintf(stderr, " HMAC-SHA256:\t[1..256]\n");
fprintf(stderr, " HMAC-SHA384:\t[1..384]\n");
fprintf(stderr, " HMAC-SHA512:\t[1..512]\n");
- fprintf(stderr, " -n nametype: ZONE | HOST | ENTITY | USER | OTHER\n");
- fprintf(stderr, " (DNSKEY generation defaults to ZONE\n");
- fprintf(stderr, " name: owner of the key\n");
- fprintf(stderr, "Other options:\n");
- fprintf(stderr, " -c <class> (default: IN)\n");
+ fprintf(stderr, " (if using the default algorithm, key size\n"
+ " defaults to 2048 for KSK, or 1024 for all "
+ "others)\n");
+ fprintf(stderr, " -n <nametype>: ZONE | HOST | ENTITY | "
+ "USER | OTHER\n");
+ fprintf(stderr, " (DNSKEY generation defaults to ZONE)\n");
+ fprintf(stderr, " -c <class>: (default: IN)\n");
fprintf(stderr, " -d <digest bits> (0 => max, default)\n");
- fprintf(stderr, " -e use large exponent (RSAMD5/RSASHA1 only)\n");
- fprintf(stderr, " -f keyflag: KSK\n");
- fprintf(stderr, " -g <generator> use specified generator "
- "(DH only)\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E <engine name> (default \"pkcs11\")\n");
+#else
+ fprintf(stderr, " -E <engine name>\n");
+#endif
+ fprintf(stderr, " -e: use large exponent (RSAMD5/RSASHA1 only)\n");
+ fprintf(stderr, " -f <keyflag>: KSK | REVOKE\n");
+ fprintf(stderr, " -g <generator>: use specified generator "
+ "(DH only)\n");
+ fprintf(stderr, " -p <protocol>: (default: 3 [dnssec])\n");
+ fprintf(stderr, " -s <strength>: strength value this key signs DNS "
+ "records with (default: 0)\n");
+ fprintf(stderr, " -T <rrtype>: DNSKEY | KEY (default: DNSKEY; "
+ "use KEY for SIG(0))\n");
+ fprintf(stderr, " ECCGOST:\tignored\n");
fprintf(stderr, " -t <type>: "
- "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
- "(default: AUTHCONF)\n");
- fprintf(stderr, " -p <protocol>: "
- "default: 3 [dnssec]\n");
- fprintf(stderr, " -s <strength> strength value this key signs DNS "
- "records with (default: 0)\n");
+ "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
+ "(default: AUTHCONF)\n");
fprintf(stderr, " -r <randomdev>: a file containing random data\n");
- fprintf(stderr, " -v <verbose level>\n");
- fprintf(stderr, " -k : generate a TYPE=KEY key\n");
+
+ fprintf(stderr, " -h: print usage and exit\n");
+ fprintf(stderr, " -m <memory debugging mode>:\n");
+ fprintf(stderr, " usage | trace | record | size | mctx\n");
+ fprintf(stderr, " -v <level>: set verbosity level (0 - 10)\n");
+ fprintf(stderr, "Timing options:\n");
+ fprintf(stderr, " -P date/[+-]offset/none: set key publication date "
+ "(default: now)\n");
+ fprintf(stderr, " -A date/[+-]offset/none: set key activation date "
+ "(default: now)\n");
+ fprintf(stderr, " -R date/[+-]offset/none: set key "
+ "revocation date\n");
+ fprintf(stderr, " -I date/[+-]offset/none: set key "
+ "inactivation date\n");
+ fprintf(stderr, " -D date/[+-]offset/none: set key deletion date\n");
+ fprintf(stderr, " -G: generate key only; do not set -P or -A\n");
+ fprintf(stderr, " -C: generate a backward-compatible key, omitting "
+ "all dates\n");
+ fprintf(stderr, " -S <key>: generate a successor to an existing "
+ "key\n");
+ fprintf(stderr, " -i <interval>: prepublication interval for "
+ "successor key "
+ "(default: 30 days)\n");
fprintf(stderr, "Output:\n");
fprintf(stderr, " K<name>+<alg>+<id>.key, "
- "K<name>+<alg>+<id>.private\n");
+ "K<name>+<alg>+<id>.private\n");
exit (-1);
}
+static isc_boolean_t
+dsa_size_ok(int size) {
+ return (ISC_TF(size >= 512 && size <= 1024 && size % 64 == 0));
+}
+
+static void
+progress(int p)
+{
+ char c = '*';
+
+ switch (p) {
+ case 0:
+ c = '.';
+ break;
+ case 1:
+ c = '+';
+ break;
+ case 2:
+ c = '*';
+ break;
+ case 3:
+ c = ' ';
+ break;
+ default:
+ break;
+ }
+ (void) putc(c, stderr);
+ (void) fflush(stderr);
+}
+
int
main(int argc, char **argv) {
char *algname = NULL, *nametype = NULL, *type = NULL;
char *classname = NULL;
char *endp;
- dst_key_t *key = NULL, *oldkey;
+ dst_key_t *key = NULL;
dns_fixedname_t fname;
dns_name_t *name;
- isc_uint16_t flags = 0, ksk = 0;
+ isc_uint16_t flags = 0, kskflag = 0, revflag = 0;
dns_secalg_t alg;
isc_boolean_t conflict = ISC_FALSE, null_key = ISC_FALSE;
+ isc_boolean_t oldstyle = ISC_FALSE;
isc_mem_t *mctx = NULL;
int ch, rsa_exp = 0, generator = 0, param = 0;
int protocol = -1, size = -1, signatory = 0;
isc_result_t ret;
isc_textregion_t r;
char filename[255];
+ const char *directory = NULL;
+ const char *predecessor = NULL;
+ dst_key_t *prevkey = NULL;
isc_buffer_t buf;
isc_log_t *log = NULL;
isc_entropy_t *ectx = NULL;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
dns_rdataclass_t rdclass;
int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC;
int dbits = 0;
+ isc_boolean_t use_default = ISC_FALSE, use_nsec3 = ISC_FALSE;
+ isc_stdtime_t publish = 0, activate = 0, revoke = 0;
+ isc_stdtime_t inactive = 0, delete = 0;
+ isc_stdtime_t now;
+ int prepub = -1;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
+ isc_boolean_t genonly = ISC_FALSE;
+ isc_boolean_t quiet = ISC_FALSE;
+ isc_boolean_t show_progress = ISC_FALSE;
+ unsigned char c;
if (argc == 1)
usage();
- RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
-
dns_result_register();
isc_commandline_errprint = ISC_FALSE;
- while ((ch = isc_commandline_parse(argc, argv,
- "a:b:c:d:ef:g:kn:t:p:s:r:v:h")) != -1)
- {
+ /*
+ * Process memory debugging argument first.
+ */
+#define CMDLINE_FLAGS "3A:a:b:Cc:D:d:E:eFf:Gg:hI:i:K:km:n:P:p:qR:r:S:s:T:t:v:"
+ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
+ switch (ch) {
+ case 'm':
+ if (strcasecmp(isc_commandline_argument, "record") == 0)
+ isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
+ if (strcasecmp(isc_commandline_argument, "trace") == 0)
+ isc_mem_debugging |= ISC_MEM_DEBUGTRACE;
+ if (strcasecmp(isc_commandline_argument, "usage") == 0)
+ isc_mem_debugging |= ISC_MEM_DEBUGUSAGE;
+ if (strcasecmp(isc_commandline_argument, "size") == 0)
+ isc_mem_debugging |= ISC_MEM_DEBUGSIZE;
+ if (strcasecmp(isc_commandline_argument, "mctx") == 0)
+ isc_mem_debugging |= ISC_MEM_DEBUGCTX;
+ break;
+ default:
+ break;
+ }
+ }
+ isc_commandline_reset = ISC_TRUE;
+
+ RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
+
+ isc_stdtime_get(&now);
+
+ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (ch) {
+ case '3':
+ use_nsec3 = ISC_TRUE;
+ break;
case 'a':
algname = isc_commandline_argument;
break;
@@ -167,6 +291,9 @@ main(int argc, char **argv) {
if (*endp != '\0' || size < 0)
fatal("-b requires a non-negative number");
break;
+ case 'C':
+ oldstyle = ISC_TRUE;
+ break;
case 'c':
classname = isc_commandline_argument;
break;
@@ -175,12 +302,18 @@ main(int argc, char **argv) {
if (*endp != '\0' || dbits < 0)
fatal("-d requires a non-negative number");
break;
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
case 'e':
rsa_exp = 1;
break;
case 'f':
- if (strcasecmp(isc_commandline_argument, "KSK") == 0)
- ksk = DNS_KEYFLAG_KSK;
+ c = (unsigned char)(isc_commandline_argument[0]);
+ if (toupper(c) == 'K')
+ kskflag = DNS_KEYFLAG_KSK;
+ else if (toupper(c) == 'R')
+ revflag = DNS_KEYFLAG_REVOKE;
else
fatal("unknown flag '%s'",
isc_commandline_argument);
@@ -191,14 +324,22 @@ main(int argc, char **argv) {
if (*endp != '\0' || generator <= 0)
fatal("-g requires a positive number");
break;
+ case 'K':
+ directory = isc_commandline_argument;
+ ret = try_dir(directory);
+ if (ret != ISC_R_SUCCESS)
+ fatal("cannot open directory %s: %s",
+ directory, isc_result_totext(ret));
+ break;
case 'k':
- options |= DST_TYPE_KEY;
+ fatal("The -k option has been deprecated.\n"
+ "To generate a key-signing key, use -f KSK.\n"
+ "To generate a key with TYPE=KEY, use -T KEY.\n");
break;
case 'n':
nametype = isc_commandline_argument;
break;
- case 't':
- type = isc_commandline_argument;
+ case 'm':
break;
case 'p':
protocol = strtol(isc_commandline_argument, &endp, 10);
@@ -206,6 +347,12 @@ main(int argc, char **argv) {
fatal("-p must be followed by a number "
"[0..255]");
break;
+ case 'q':
+ quiet = ISC_TRUE;
+ break;
+ case 'r':
+ setup_entropy(mctx, isc_commandline_argument, &ectx);
+ break;
case 's':
signatory = strtol(isc_commandline_argument,
&endp, 10);
@@ -213,8 +360,19 @@ main(int argc, char **argv) {
fatal("-s must be followed by a number "
"[0..15]");
break;
- case 'r':
- setup_entropy(mctx, isc_commandline_argument, &ectx);
+ case 'T':
+ if (strcasecmp(isc_commandline_argument, "KEY") == 0)
+ options |= DST_TYPE_KEY;
+ else if (strcasecmp(isc_commandline_argument,
+ "DNSKEY") == 0)
+ /* default behavior */
+ ;
+ else
+ fatal("unknown type '%s'",
+ isc_commandline_argument);
+ break;
+ case 't':
+ type = isc_commandline_argument;
break;
case 'v':
endp = NULL;
@@ -222,11 +380,86 @@ main(int argc, char **argv) {
if (*endp != '\0')
fatal("-v must be followed by a number");
break;
-
+ case 'z':
+ /* already the default */
+ break;
+ case 'G':
+ genonly = ISC_TRUE;
+ break;
+ case 'P':
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setpub = ISC_TRUE;
+ publish = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetpub = ISC_TRUE;
+ }
+ break;
+ case 'A':
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setact = ISC_TRUE;
+ activate = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetact = ISC_TRUE;
+ }
+ break;
+ case 'R':
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setrev = ISC_TRUE;
+ revoke = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetrev = ISC_TRUE;
+ }
+ break;
+ case 'I':
+ if (setinact || unsetinact)
+ fatal("-I specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setinact = ISC_TRUE;
+ inactive = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetinact = ISC_TRUE;
+ }
+ break;
+ case 'D':
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ if (strcasecmp(isc_commandline_argument, "none")) {
+ setdel = ISC_TRUE;
+ delete = strtotime(isc_commandline_argument,
+ now, now);
+ } else {
+ unsetdel = ISC_TRUE;
+ }
+ break;
+ case 'S':
+ predecessor = isc_commandline_argument;
+ break;
+ case 'i':
+ prepub = strtottl(isc_commandline_argument);
+ break;
+ case 'F':
+ /* Reserved for FIPS mode */
+ /* FALLTHROUGH */
case '?':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
program, isc_commandline_option);
+ /* FALLTHROUGH */
case 'h':
usage();
@@ -237,73 +470,219 @@ main(int argc, char **argv) {
}
}
+ if (!isatty(0))
+ quiet = ISC_TRUE;
+
if (ectx == NULL)
setup_entropy(mctx, NULL, &ectx);
- ret = dst_lib_init(mctx, ectx,
- ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ ret = dst_lib_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
if (ret != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(ret));
setup_logging(verbose, mctx, &log);
- if (argc < isc_commandline_index + 1)
- fatal("the key name was not specified");
- if (argc > isc_commandline_index + 1)
- fatal("extraneous arguments");
-
- if (algname == NULL)
- fatal("no algorithm was specified");
- if (strcasecmp(algname, "RSA") == 0) {
- fprintf(stderr, "The use of RSA (RSAMD5) is not recommended.\n"
- "If you still wish to use RSA (RSAMD5) please "
- "specify \"-a RSAMD5\"\n");
- return (1);
- } else if (strcasecmp(algname, "HMAC-MD5") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACMD5;
- } else if (strcasecmp(algname, "HMAC-SHA1") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA1;
- } else if (strcasecmp(algname, "HMAC-SHA224") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA224;
- } else if (strcasecmp(algname, "HMAC-SHA256") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA256;
- } else if (strcasecmp(algname, "HMAC-SHA384") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA384;
- } else if (strcasecmp(algname, "HMAC-SHA512") == 0) {
- options |= DST_TYPE_KEY;
- alg = DST_ALG_HMACSHA512;
- } else {
- r.base = algname;
- r.length = strlen(algname);
- ret = dns_secalg_fromtext(&alg, &r);
+ if (predecessor == NULL) {
+ if (prepub == -1)
+ prepub = 0;
+
+ if (argc < isc_commandline_index + 1)
+ fatal("the key name was not specified");
+ if (argc > isc_commandline_index + 1)
+ fatal("extraneous arguments");
+
+ 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, 0, NULL);
if (ret != ISC_R_SUCCESS)
- fatal("unknown algorithm %s", algname);
- if (alg == DST_ALG_DH)
- options |= DST_TYPE_KEY;
- }
+ fatal("invalid key name %s: %s",
+ argv[isc_commandline_index],
+ isc_result_totext(ret));
+
+ if (algname == NULL) {
+ use_default = ISC_TRUE;
+ if (use_nsec3)
+ algname = strdup(DEFAULT_NSEC3_ALGORITHM);
+ else
+ algname = strdup(DEFAULT_ALGORITHM);
+ if (verbose > 0)
+ fprintf(stderr, "no algorithm specified; "
+ "defaulting to %s\n", algname);
+ }
- if (type != NULL && (options & DST_TYPE_KEY) != 0) {
- if (strcasecmp(type, "NOAUTH") == 0)
- flags |= DNS_KEYTYPE_NOAUTH;
- else if (strcasecmp(type, "NOCONF") == 0)
- flags |= DNS_KEYTYPE_NOCONF;
- else if (strcasecmp(type, "NOAUTHCONF") == 0) {
- flags |= (DNS_KEYTYPE_NOAUTH | DNS_KEYTYPE_NOCONF);
- if (size < 0)
- size = 0;
+ if (strcasecmp(algname, "RSA") == 0) {
+ fprintf(stderr, "The use of RSA (RSAMD5) is not "
+ "recommended.\nIf you still wish to "
+ "use RSA (RSAMD5) please specify "
+ "\"-a RSAMD5\"\n");
+ return (1);
+ } else if (strcasecmp(algname, "HMAC-MD5") == 0)
+ alg = DST_ALG_HMACMD5;
+ else if (strcasecmp(algname, "HMAC-SHA1") == 0)
+ alg = DST_ALG_HMACSHA1;
+ else if (strcasecmp(algname, "HMAC-SHA224") == 0)
+ alg = DST_ALG_HMACSHA224;
+ else if (strcasecmp(algname, "HMAC-SHA256") == 0)
+ alg = DST_ALG_HMACSHA256;
+ else if (strcasecmp(algname, "HMAC-SHA384") == 0)
+ alg = DST_ALG_HMACSHA384;
+ else if (strcasecmp(algname, "HMAC-SHA512") == 0)
+ alg = DST_ALG_HMACSHA512;
+ else {
+ r.base = algname;
+ r.length = strlen(algname);
+ ret = dns_secalg_fromtext(&alg, &r);
+ if (ret != ISC_R_SUCCESS)
+ fatal("unknown algorithm %s", algname);
+ if (alg == DST_ALG_DH)
+ options |= DST_TYPE_KEY;
}
- else if (strcasecmp(type, "AUTHCONF") == 0)
- /* nothing */;
- else
- fatal("invalid type %s", type);
- }
- if (size < 0)
- fatal("key size not specified (-b option)");
+ if (use_nsec3 &&
+ alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 &&
+ alg != DST_ALG_RSASHA256 && alg!= DST_ALG_RSASHA512 &&
+ alg != DST_ALG_ECCGOST) {
+ fatal("%s is incompatible with NSEC3; "
+ "do not use the -3 option", algname);
+ }
+
+ if (type != NULL && (options & DST_TYPE_KEY) != 0) {
+ if (strcasecmp(type, "NOAUTH") == 0)
+ flags |= DNS_KEYTYPE_NOAUTH;
+ else if (strcasecmp(type, "NOCONF") == 0)
+ flags |= DNS_KEYTYPE_NOCONF;
+ else if (strcasecmp(type, "NOAUTHCONF") == 0) {
+ flags |= (DNS_KEYTYPE_NOAUTH |
+ DNS_KEYTYPE_NOCONF);
+ if (size < 0)
+ size = 0;
+ }
+ else if (strcasecmp(type, "AUTHCONF") == 0)
+ /* nothing */;
+ else
+ fatal("invalid type %s", type);
+ }
+
+ if (size < 0) {
+ if (use_default) {
+ if ((kskflag & DNS_KEYFLAG_KSK) != 0)
+ size = 2048;
+ else
+ size = 1024;
+ if (verbose > 0)
+ fprintf(stderr, "key size not "
+ "specified; defaulting "
+ "to %d\n", size);
+ } else if (alg != DST_ALG_ECCGOST)
+ fatal("key size not specified (-b option)");
+ }
+
+ if (!oldstyle && prepub > 0) {
+ if (setpub && setact && (activate - prepub) < publish)
+ fatal("Activation and publication dates "
+ "are closer together than the\n\t"
+ "prepublication interval.");
+
+ if (!setpub && !setact) {
+ setpub = setact = ISC_TRUE;
+ publish = now;
+ activate = now + prepub;
+ } else if (setpub && !setact) {
+ setact = ISC_TRUE;
+ activate = publish + prepub;
+ } else if (setact && !setpub) {
+ setpub = ISC_TRUE;
+ publish = activate - prepub;
+ }
+
+ if ((activate - prepub) < now)
+ fatal("Time until activation is shorter "
+ "than the\n\tprepublication interval.");
+ }
+ } else {
+ char keystr[DST_KEY_FORMATSIZE];
+ isc_stdtime_t when;
+ int major, minor;
+
+ if (prepub == -1)
+ prepub = (30 * 86400);
+
+ if (algname != NULL)
+ fatal("-S and -a cannot be used together");
+ if (size >= 0)
+ fatal("-S and -b cannot be used together");
+ if (nametype != NULL)
+ fatal("-S and -n cannot be used together");
+ if (type != NULL)
+ fatal("-S and -t cannot be used together");
+ if (setpub || unsetpub)
+ fatal("-S and -P cannot be used together");
+ if (setact || unsetact)
+ fatal("-S and -A cannot be used together");
+ if (use_nsec3)
+ fatal("-S and -3 cannot be used together");
+ if (oldstyle)
+ fatal("-S and -C cannot be used together");
+ if (genonly)
+ fatal("-S and -G cannot be used together");
+
+ ret = dst_key_fromnamedfile(predecessor, directory,
+ DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
+ mctx, &prevkey);
+ if (ret != ISC_R_SUCCESS)
+ fatal("Invalid keyfile %s: %s",
+ filename, isc_result_totext(ret));
+ if (!dst_key_isprivate(prevkey))
+ fatal("%s is not a private key", filename);
+
+ name = dst_key_name(prevkey);
+ alg = dst_key_alg(prevkey);
+ size = dst_key_size(prevkey);
+ flags = dst_key_flags(prevkey);
+
+ dst_key_format(prevkey, keystr, sizeof(keystr));
+ dst_key_getprivateformat(prevkey, &major, &minor);
+ if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
+ fatal("Key %s has incompatible format version %d.%d\n\t"
+ "It is not possible to generate a successor key.",
+ keystr, major, minor);
+
+ ret = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when);
+ if (ret != ISC_R_SUCCESS)
+ fatal("Key %s has no activation date.\n\t"
+ "You must use dnssec-settime -A to set one "
+ "before generating a successor.", keystr);
+
+ ret = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &activate);
+ if (ret != ISC_R_SUCCESS)
+ fatal("Key %s has no inactivation date.\n\t"
+ "You must use dnssec-settime -I to set one "
+ "before generating a successor.", keystr);
+
+ publish = activate - prepub;
+ if (publish < now)
+ fatal("Key %s becomes inactive\n\t"
+ "sooner than the prepublication period "
+ "for the new key ends.\n\t"
+ "Either change the inactivation date with "
+ "dnssec-settime -I,\n\t"
+ "or use the -i option to set a shorter "
+ "prepublication interval.", keystr);
+
+ ret = dst_key_gettime(prevkey, DST_TIME_DELETE, &when);
+ if (ret != ISC_R_SUCCESS)
+ fprintf(stderr, "%s: WARNING: Key %s has no removal "
+ "date;\n\t it will remain in the zone "
+ "indefinitely after rollover.\n\t "
+ "You can use dnssec-settime -D to "
+ "change this.\n", program, keystr);
+
+ setpub = setact = ISC_TRUE;
+ }
switch (alg) {
case DNS_KEYALG_RSAMD5:
@@ -326,7 +705,10 @@ main(int argc, char **argv) {
if (size != 0 && !dsa_size_ok(size))
fatal("invalid DSS key size: %d", size);
break;
+ case DST_ALG_ECCGOST:
+ break;
case DST_ALG_HMACMD5:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 512)
fatal("HMAC-MD5 key size %d out of range", size);
if (dbits != 0 && (dbits < 80 || dbits > 128))
@@ -336,6 +718,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA1:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 160)
fatal("HMAC-SHA1 key size %d out of range", size);
if (dbits != 0 && (dbits < 80 || dbits > 160))
@@ -345,6 +728,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA224:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 224)
fatal("HMAC-SHA224 key size %d out of range", size);
if (dbits != 0 && (dbits < 112 || dbits > 224))
@@ -354,6 +738,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA256:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 256)
fatal("HMAC-SHA256 key size %d out of range", size);
if (dbits != 0 && (dbits < 128 || dbits > 256))
@@ -363,6 +748,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA384:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 384)
fatal("HMAC-384 key size %d out of range", size);
if (dbits != 0 && (dbits < 192 || dbits > 384))
@@ -372,6 +758,7 @@ main(int argc, char **argv) {
dbits);
break;
case DST_ALG_HMACSHA512:
+ options |= DST_TYPE_KEY;
if (size < 1 || size > 512)
fatal("HMAC-SHA512 key size %d out of range", size);
if (dbits != 0 && (dbits < 256 || dbits > 512))
@@ -384,7 +771,8 @@ main(int argc, char **argv) {
if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1 ||
alg == DNS_KEYALG_NSEC3RSASHA1 || alg == DNS_KEYALG_RSASHA256 ||
- alg == DNS_KEYALG_RSASHA512) && rsa_exp != 0)
+ alg == DNS_KEYALG_RSASHA512 || alg == DST_ALG_ECCGOST) &&
+ rsa_exp != 0)
fatal("specified RSA exponent for a non-RSA key");
if (alg != DNS_KEYALG_DH && generator != 0)
@@ -409,10 +797,15 @@ main(int argc, char **argv) {
rdclass = strtoclass(classname);
+ if (directory == NULL)
+ directory = ".";
+
if ((options & DST_TYPE_KEY) != 0) /* KEY / HMAC */
flags |= signatory;
- else if ((flags & DNS_KEYOWNER_ZONE) != 0) /* DNSKEY */
- flags |= ksk;
+ else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */
+ flags |= kskflag;
+ flags |= revflag;
+ }
if (protocol == -1)
protocol = DNS_KEYPROTO_DNSSEC;
@@ -435,16 +828,6 @@ main(int argc, char **argv) {
fatal("a key with algorithm '%s' cannot be a zone key",
algname);
- dns_fixedname_init(&fname);
- name = dns_fixedname_name(&fname);
- isc_buffer_init(&buf, argv[isc_commandline_index],
- strlen(argv[isc_commandline_index]));
- isc_buffer_add(&buf, strlen(argv[isc_commandline_index]));
- ret = dns_name_fromtext(name, &buf, dns_rootname, ISC_FALSE, NULL);
- if (ret != ISC_R_SUCCESS)
- fatal("invalid key name %s: %s", argv[isc_commandline_index],
- isc_result_totext(ret));
-
switch(alg) {
case DNS_KEYALG_RSAMD5:
case DNS_KEYALG_RSASHA1:
@@ -452,12 +835,19 @@ main(int argc, char **argv) {
case DNS_KEYALG_RSASHA256:
case DNS_KEYALG_RSASHA512:
param = rsa_exp;
+ show_progress = ISC_TRUE;
break;
+
case DNS_KEYALG_DH:
param = generator;
break;
+
case DNS_KEYALG_DSA:
case DNS_KEYALG_NSEC3DSA:
+ case DST_ALG_ECCGOST:
+ show_progress = ISC_TRUE;
+ /* fall through */
+
case DST_ALG_HMACMD5:
case DST_ALG_HMACSHA1:
case DST_ALG_HMACSHA224:
@@ -475,62 +865,136 @@ main(int argc, char **argv) {
do {
conflict = ISC_FALSE;
- oldkey = NULL;
- /* generate the key */
- ret = dst_key_generate(name, alg, size, param, flags, protocol,
- rdclass, mctx, &key);
+ if (!quiet && show_progress) {
+ fprintf(stderr, "Generating key pair.");
+ ret = dst_key_generate2(name, alg, size, param, flags,
+ protocol, rdclass, mctx, &key,
+ &progress);
+ putc('\n', stderr);
+ fflush(stderr);
+ } else {
+ ret = dst_key_generate2(name, alg, size, param, flags,
+ protocol, rdclass, mctx, &key,
+ NULL);
+ }
+
isc_entropy_stopcallbacksources(ectx);
if (ret != ISC_R_SUCCESS) {
char namestr[DNS_NAME_FORMATSIZE];
- char algstr[ALG_FORMATSIZE];
+ char algstr[DNS_SECALG_FORMATSIZE];
dns_name_format(name, namestr, sizeof(namestr));
- alg_format(alg, algstr, sizeof(algstr));
+ dns_secalg_format(alg, algstr, sizeof(algstr));
fatal("failed to generate key %s/%s: %s\n",
namestr, algstr, isc_result_totext(ret));
+ /* NOTREACHED */
exit(-1);
}
dst_key_setbits(key, dbits);
/*
- * Try to read a key with the same name, alg and id from disk.
- * If there is one we must continue generating a new one
- * unless we were asked to generate a null key, in which
- * case we return failure.
+ * Set key timing metadata (unless using -C)
+ *
+ * Creation date is always set to "now".
+ *
+ * For a new key without an explicit predecessor, publish
+ * and activation dates are set to "now" by default, but
+ * can both be overridden.
+ *
+ * For a successor key, activation is set to match the
+ * predecessor's inactivation date. Publish is set to 30
+ * days earlier than that (XXX: this should be configurable).
+ * If either of the resulting dates are in the past, that's
+ * an error; the inactivation date of the predecessor key
+ * must be updated before a successor key can be created.
*/
- 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);
+ if (!oldstyle) {
+ dst_key_settime(key, DST_TIME_CREATED, now);
+
+ if (genonly && (setpub || setact))
+ fatal("cannot use -G together with "
+ "-P or -A options");
+
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, publish);
+ else if (setact)
+ dst_key_settime(key, DST_TIME_PUBLISH,
+ activate);
+ else if (!genonly && !unsetpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, now);
+
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE,
+ activate);
+ else if (!genonly && !unsetact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, now);
+
+ if (setrev) {
+ if (kskflag == 0)
+ fprintf(stderr, "%s: warning: Key is "
+ "not flagged as a KSK, but -R "
+ "was used. Revoking a ZSK is "
+ "legal, but undefined.\n",
+ program);
+ dst_key_settime(key, DST_TIME_REVOKE, revoke);
+ }
+
+ if (setinact)
+ dst_key_settime(key, DST_TIME_INACTIVE,
+ inactive);
+
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, delete);
+ } else {
+ if (setpub || setact || setrev || setinact ||
+ setdel || unsetpub || unsetact ||
+ unsetrev || unsetinact || unsetdel || genonly)
+ fatal("cannot use -C together with "
+ "-P, -A, -R, -I, -D, or -G options");
+ /*
+ * Compatibility mode: Private-key-format
+ * should be set to 1.2.
+ */
+ dst_key_setprivateformat(key, 1, 2);
+ }
+
+ /*
+ * Do not overwrite an existing key, or create a key
+ * if there is a risk of ID collision due to this key
+ * or another key being revoked.
+ */
+ if (key_collision(dst_key_id(key), name, directory,
+ alg, mctx, NULL)) {
conflict = ISC_TRUE;
- if (null_key)
+ if (null_key) {
+ dst_key_free(&key);
break;
- }
- if (conflict == ISC_TRUE) {
+ }
+
if (verbose > 0) {
isc_buffer_clear(&buf);
- ret = dst_key_buildfilename(key, 0, NULL, &buf);
+ dst_key_buildfilename(key, 0, directory, &buf);
fprintf(stderr,
- "%s: %s already exists, "
- "generating a new key\n",
+ "%s: %s already exists, or might "
+ "collide with another key upon "
+ "revokation. 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");
+ fatal("cannot generate a null key due to possible key ID "
+ "collision");
- ret = dst_key_tofile(key, options, NULL);
+ ret = dst_key_tofile(key, options, directory);
if (ret != ISC_R_SUCCESS) {
- char keystr[KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ char keystr[DST_KEY_FORMATSIZE];
+ dst_key_format(key, keystr, sizeof(keystr));
fatal("failed to write key %s: %s\n", keystr,
isc_result_totext(ret));
}
@@ -539,6 +1003,8 @@ main(int argc, char **argv) {
ret = dst_key_buildfilename(key, 0, NULL, &buf);
printf("%s\n", filename);
dst_key_free(&key);
+ if (prevkey != NULL)
+ dst_key_free(&prevkey);
cleanup_logging(&log);
cleanup_entropy(&ectx);
diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook
index 5c7d1649fe67..dc140ebfe386 100644
--- a/bin/dnssec/dnssec-keygen.docbook
+++ b/bin/dnssec/dnssec-keygen.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keygen.docbook,v 1.22.44.4 2010-01-15 23:47:33 tbox Exp $ -->
+<!-- $Id: dnssec-keygen.docbook,v 1.36 2010-12-23 04:07:59 marka Exp $ -->
<refentry id="man.dnssec-keygen">
<refentryinfo>
<date>June 30, 2000</date>
@@ -57,20 +57,34 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>dnssec-keygen</command>
- <arg choice="req">-a <replaceable class="parameter">algorithm</replaceable></arg>
- <arg choice="req">-b <replaceable class="parameter">keysize</replaceable></arg>
- <arg choice="req">-n <replaceable class="parameter">nametype</replaceable></arg>
+ <arg><option>-a <replaceable class="parameter">algorithm</replaceable></option></arg>
+ <arg ><option>-b <replaceable class="parameter">keysize</replaceable></option></arg>
+ <arg><option>-n <replaceable class="parameter">nametype</replaceable></option></arg>
+ <arg><option>-3</option></arg>
+ <arg><option>-A <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-C</option></arg>
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
+ <arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
<arg><option>-e</option></arg>
<arg><option>-f <replaceable class="parameter">flag</replaceable></option></arg>
+ <arg><option>-G</option></arg>
<arg><option>-g <replaceable class="parameter">generator</replaceable></option></arg>
<arg><option>-h</option></arg>
+ <arg><option>-I <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-i <replaceable class="parameter">interval</replaceable></option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
<arg><option>-k</option></arg>
+ <arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-p <replaceable class="parameter">protocol</replaceable></option></arg>
+ <arg><option>-q</option></arg>
+ <arg><option>-R <replaceable class="parameter">date/offset</replaceable></option></arg>
<arg><option>-r <replaceable class="parameter">randomdev</replaceable></option></arg>
+ <arg><option>-S <replaceable class="parameter">key</replaceable></option></arg>
<arg><option>-s <replaceable class="parameter">strength</replaceable></option></arg>
<arg><option>-t <replaceable class="parameter">type</replaceable></option></arg>
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-z</option></arg>
<arg choice="req">name</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -80,7 +94,8 @@
<para><command>dnssec-keygen</command>
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034. It can also generate keys for use with
- TSIG (Transaction Signatures), as defined in RFC 2845.
+ TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY
+ (Transaction Key) as defined in RFC 2930.
</para>
<para>
The <option>name</option> of the key is specified on the command
@@ -99,19 +114,27 @@
<para>
Selects the cryptographic algorithm. For DNSSEC keys, the value
of <option>algorithm</option> must be one of RSAMD5, RSASHA1,
- DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512.
- For TSIG/TKEY, the value must
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
+ For TSIG/TKEY, the value must
be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224,
HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are
case insensitive.
</para>
<para>
+ If no algorithm is specified, then RSASHA1 will be used by
+ default, unless the <option>-3</option> option is specified,
+ in which case NSEC3RSASHA1 will be used instead. (If
+ <option>-3</option> is used and an algorithm is specified,
+ that algorithm will be checked for compatibility with NSEC3.)
+ </para>
+ <para>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is
mandatory.
</para>
<para>
- Note 2: HMAC-MD5 and DH automatically set the -k flag.
+ Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512
+ automatically set the -T KEY option.
</para>
</listitem>
</varlistentry>
@@ -127,6 +150,15 @@
bits and an exact multiple of 64. HMAC keys must be
between 1 and 512 bits.
</para>
+ <para>
+ The key size does not need to be specified if using a default
+ algorithm. The default key size is 1024 bits for zone signing
+ keys (ZSK's) and 2048 bits for key signing keys (KSK's,
+ generated with <option>-f KSK</option>). However, if an
+ algorithm is explicitly specified with the <option>-a</option>,
+ then there is no default key size, and the <option>-b</option>
+ must be used.
+ </para>
</listitem>
</varlistentry>
@@ -146,6 +178,34 @@
</varlistentry>
<varlistentry>
+ <term>-3</term>
+ <listitem>
+ <para>
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms
+ are NSEC3-capable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-C</term>
+ <listitem>
+ <para>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <command>dnssec-keygen</command>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <option>-C</option> option suppresses them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-c <replaceable class="parameter">class</replaceable></term>
<listitem>
<para>
@@ -156,6 +216,18 @@
</varlistentry>
<varlistentry>
+ <term>-E <replaceable class="parameter">engine</replaceable></term>
+ <listitem>
+ <para>
+ Uses a crypto hardware (OpenSSL engine) for random number
+ and, when supported, key generation. When compiled with PKCS#11
+ support it defaults to pkcs11; the empty name resets it to
+ no engine.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-e</term>
<listitem>
<para>
@@ -169,7 +241,17 @@
<listitem>
<para>
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-G</term>
+ <listitem>
+ <para>
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
</para>
</listitem>
</varlistentry>
@@ -197,10 +279,19 @@
</varlistentry>
<varlistentry>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Sets the directory in which the key files are to be written.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-k</term>
<listitem>
<para>
- Generate KEY records rather than DNSKEY records.
+ Deprecated in favor of -T KEY.
</para>
</listitem>
</varlistentry>
@@ -218,6 +309,25 @@
</varlistentry>
<varlistentry>
+ <term>-q</term>
+ <listitem>
+ <para>
+ Quiet mode: Suppresses unnecessary output, including
+ progress indication. Without this option, when
+ <command>dnssec-keygen</command> is run interactively
+ to generate an RSA or DSA key pair, it will print a string
+ of symbols to <filename>stderr</filename> indicating the
+ progress of the key generation. A '.' indicates that a
+ random number has been found which passed an initial
+ sieve test; '+' means a number has passed a single
+ round of the Miller-Rabin primality test; a space
+ means that the number has passed all the tests and is
+ a satisfactory key.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-r <replaceable class="parameter">randomdev</replaceable></term>
<listitem>
<para>
@@ -235,6 +345,21 @@
</varlistentry>
<varlistentry>
+ <term>-S <replaceable class="parameter">key</replaceable></term>
+ <listitem>
+ <para>
+ Create a new key which is an explicit successor to an
+ existing key. The name, algorithm, size, and type of the
+ key will be set to match the existing key. The activation
+ date of the new key will be set to the inactivation date of
+ the existing one. The publication date will be set to the
+ activation date minus the prepublication interval, which
+ defaults to 30 days.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-s <replaceable class="parameter">strength</replaceable></term>
<listitem>
<para>
@@ -246,6 +371,22 @@
</varlistentry>
<varlistentry>
+ <term>-T <replaceable class="parameter">rrtype</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the resource record type to use for the key.
+ <option>rrtype</option> must be either DNSKEY or KEY. The
+ default is DNSKEY when using a DNSSEC algorithm, but it can be
+ overridden to KEY for use with SIG(0).
+ <para>
+ </para>
+ Using any TSIG algorithm (HMAC-* or DH) forces this option
+ to KEY.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-t <replaceable class="parameter">type</replaceable></term>
<listitem>
<para>
@@ -270,6 +411,109 @@
</refsect1>
<refsect1>
+ <title>TIMING OPTIONS</title>
+
+ <para>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-P <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-R <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-I <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-D <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-i <replaceable class="parameter">interval</replaceable></term>
+ <listitem>
+ <para>
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+ </para>
+ <para>
+ If the key is being created as an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+ </para>
+ <para>
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1>
<title>GENERATED KEYS</title>
<para>
When <command>dnssec-keygen</command> completes
diff --git a/bin/dnssec/dnssec-keygen.html b/bin/dnssec/dnssec-keygen.html
index 7ca7d577e8fb..2f3a69b9a2fd 100644
--- a/bin/dnssec/dnssec-keygen.html
+++ b/bin/dnssec/dnssec-keygen.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-keygen.html,v 1.32.44.4 2010-01-16 01:55:32 tbox Exp $ -->
+<!-- $Id: dnssec-keygen.html,v 1.47 2010-12-24 01:14:20 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,14 +29,15 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-keygen</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-b <em class="replaceable"><code>keysize</code></em>} {-n <em class="replaceable"><code>nametype</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-e</code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-g <em class="replaceable"><code>generator</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k</code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>strength</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-keygen</code> [<code class="option">-a <em class="replaceable"><code>algorithm</code></em></code>] [<code class="option">-b <em class="replaceable"><code>keysize</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-3</code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-C</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-e</code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-G</code>] [<code class="option">-g <em class="replaceable"><code>generator</code></em></code>] [<code class="option">-h</code>] [<code class="option">-I <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-k</code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-q</code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-S <em class="replaceable"><code>key</code></em></code>] [<code class="option">-s <em class="replaceable"><code>strength</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543483"></a><h2>DESCRIPTION</h2>
+<a name="id2543578"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keygen</strong></span>
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034. It can also generate keys for use with
- TSIG (Transaction Signatures), as defined in RFC 2845.
+ TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY
+ (Transaction Key) as defined in RFC 2930.
</p>
<p>
The <code class="option">name</code> of the key is specified on the command
@@ -45,37 +46,56 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543501"></a><h2>OPTIONS</h2>
+<a name="id2543596"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
<p>
Selects the cryptographic algorithm. For DNSSEC keys, the value
of <code class="option">algorithm</code> must be one of RSAMD5, RSASHA1,
- DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512.
- For TSIG/TKEY, the value must
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
+ For TSIG/TKEY, the value must
be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224,
HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are
case insensitive.
</p>
<p>
+ If no algorithm is specified, then RSASHA1 will be used by
+ default, unless the <code class="option">-3</code> option is specified,
+ in which case NSEC3RSASHA1 will be used instead. (If
+ <code class="option">-3</code> is used and an algorithm is specified,
+ that algorithm will be checked for compatibility with NSEC3.)
+ </p>
+<p>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is
mandatory.
</p>
<p>
- Note 2: HMAC-MD5 and DH automatically set the -k flag.
+ Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512
+ automatically set the -T KEY option.
</p>
</dd>
<dt><span class="term">-b <em class="replaceable"><code>keysize</code></em></span></dt>
-<dd><p>
+<dd>
+<p>
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 keys must be
between 1 and 512 bits.
- </p></dd>
+ </p>
+<p>
+ The key size does not need to be specified if using a default
+ algorithm. The default key size is 1024 bits for zone signing
+ keys (ZSK's) and 2048 bits for key signing keys (KSK's,
+ generated with <code class="option">-f KSK</code>). However, if an
+ algorithm is explicitly specified with the <code class="option">-a</code>,
+ then there is no default key size, and the <code class="option">-b</code>
+ must be used.
+ </p>
+</dd>
<dt><span class="term">-n <em class="replaceable"><code>nametype</code></em></span></dt>
<dd><p>
Specifies the owner type of the key. The value of
@@ -86,11 +106,36 @@
These values are case insensitive. Defaults to ZONE for DNSKEY
generation.
</p></dd>
+<dt><span class="term">-3</span></dt>
+<dd><p>
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms
+ are NSEC3-capable.
+ </p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <span><strong class="command">dnssec-keygen</strong></span>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <code class="option">-C</code> option suppresses them.
+ </p></dd>
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
<dd><p>
Indicates that the DNS record containing the key should have
the specified class. If not specified, class IN is used.
</p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Uses a crypto hardware (OpenSSL engine) for random number
+ and, when supported, key generation. When compiled with PKCS#11
+ support it defaults to pkcs11; the empty name resets it to
+ no engine.
+ </p></dd>
<dt><span class="term">-e</span></dt>
<dd><p>
If generating an RSAMD5/RSASHA1 key, use a large exponent.
@@ -98,7 +143,12 @@
<dt><span class="term">-f <em class="replaceable"><code>flag</code></em></span></dt>
<dd><p>
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+ </p></dd>
+<dt><span class="term">-G</span></dt>
+<dd><p>
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
</p></dd>
<dt><span class="term">-g <em class="replaceable"><code>generator</code></em></span></dt>
<dd><p>
@@ -112,9 +162,13 @@
Prints a short summary of the options and arguments to
<span><strong class="command">dnssec-keygen</strong></span>.
</p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to be written.
+ </p></dd>
<dt><span class="term">-k</span></dt>
<dd><p>
- Generate KEY records rather than DNSKEY records.
+ Deprecated in favor of -T KEY.
</p></dd>
<dt><span class="term">-p <em class="replaceable"><code>protocol</code></em></span></dt>
<dd><p>
@@ -123,6 +177,20 @@
Other possible values for this argument are listed in
RFC 2535 and its successors.
</p></dd>
+<dt><span class="term">-q</span></dt>
+<dd><p>
+ Quiet mode: Suppresses unnecessary output, including
+ progress indication. Without this option, when
+ <span><strong class="command">dnssec-keygen</strong></span> is run interactively
+ to generate an RSA or DSA key pair, it will print a string
+ of symbols to <code class="filename">stderr</code> indicating the
+ progress of the key generation. A '.' indicates that a
+ random number has been found which passed an initial
+ sieve test; '+' means a number has passed a single
+ round of the Miller-Rabin primality test; a space
+ means that the number has passed all the tests and is
+ a satisfactory key.
+ </p></dd>
<dt><span class="term">-r <em class="replaceable"><code>randomdev</code></em></span></dt>
<dd><p>
Specifies the source of randomness. If the operating
@@ -135,12 +203,37 @@
<code class="filename">keyboard</code> indicates that keyboard
input should be used.
</p></dd>
+<dt><span class="term">-S <em class="replaceable"><code>key</code></em></span></dt>
+<dd><p>
+ Create a new key which is an explicit successor to an
+ existing key. The name, algorithm, size, and type of the
+ key will be set to match the existing key. The activation
+ date of the new key will be set to the inactivation date of
+ the existing one. The publication date will be set to the
+ activation date minus the prepublication interval, which
+ defaults to 30 days.
+ </p></dd>
<dt><span class="term">-s <em class="replaceable"><code>strength</code></em></span></dt>
<dd><p>
Specifies the strength value of the key. The strength is
a number between 0 and 15, and currently has no defined
purpose in DNSSEC.
</p></dd>
+<dt><span class="term">-T <em class="replaceable"><code>rrtype</code></em></span></dt>
+<dd>
+<p>
+ Specifies the resource record type to use for the key.
+ <code class="option">rrtype</code> must be either DNSKEY or KEY. The
+ default is DNSKEY when using a DNSSEC algorithm, but it can be
+ overridden to KEY for use with SIG(0).
+ </p>
+<p>
+ </p>
+<p>
+ Using any TSIG algorithm (HMAC-* or DH) forces this option
+ to KEY.
+ </p>
+</dd>
<dt><span class="term">-t <em class="replaceable"><code>type</code></em></span></dt>
<dd><p>
Indicates the use of the key. <code class="option">type</code> must be
@@ -155,7 +248,78 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543836"></a><h2>GENERATED KEYS</h2>
+<a name="id2544301"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-I <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </p></dd>
+<dt><span class="term">-i <em class="replaceable"><code>interval</code></em></span></dt>
+<dd>
+<p>
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+ </p>
+<p>
+ If the key is being created as an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+ </p>
+<p>
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+ </p>
+</dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2544491"></a><h2>GENERATED KEYS</h2>
<p>
When <span><strong class="command">dnssec-keygen</strong></span> completes
successfully,
@@ -201,7 +365,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543918"></a><h2>EXAMPLE</h2>
+<a name="id2544642"></a><h2>EXAMPLE</h2>
<p>
To generate a 768-bit DSA key for the domain
<strong class="userinput"><code>example.com</code></strong>, the following command would be
@@ -222,7 +386,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544030"></a><h2>SEE ALSO</h2>
+<a name="id2544685"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 2539</em>,
@@ -231,7 +395,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544061"></a><h2>AUTHOR</h2>
+<a name="id2544716"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/dnssec/dnssec-revoke.8 b/bin/dnssec/dnssec-revoke.8
new file mode 100644
index 000000000000..d57b6aa09de2
--- /dev/null
+++ b/bin/dnssec/dnssec-revoke.8
@@ -0,0 +1,83 @@
+.\" Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-revoke.8,v 1.9 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: dnssec\-revoke
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: June 1, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "DNSSEC\-REVOKE" "8" "June 1, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+dnssec\-revoke \- Set the REVOKED bit on a DNSSEC key
+.SH "SYNOPSIS"
+.HP 14
+\fBdnssec\-revoke\fR [\fB\-hr\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\fR] {keyfile}
+.SH "DESCRIPTION"
+.PP
+\fBdnssec\-revoke\fR
+reads a DNSSEC key file, sets the REVOKED bit on the key as defined in RFC 5011, and creates a new pair of key files containing the now\-revoked key.
+.SH "OPTIONS"
+.PP
+\-h
+.RS 4
+Emit usage message and exit.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to reside.
+.RE
+.PP
+\-r
+.RS 4
+After writing the new keyset files remove the original keyset files.
+.RE
+.PP
+\-v \fIlevel\fR
+.RS 4
+Sets the debugging level.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Use the given OpenSSL engine. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
+.RE
+.PP
+\-f
+.RS 4
+Force overwrite: Causes
+\fBdnssec\-revoke\fR
+to write the new key pair even if a file already exists matching the algorithm and key ID of the revoked key.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBdnssec\-keygen\fR(8),
+BIND 9 Administrator Reference Manual,
+RFC 5011.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/dnssec/dnssec-revoke.c b/bin/dnssec/dnssec-revoke.c
new file mode 100644
index 000000000000..90e905c4d0b0
--- /dev/null
+++ b/bin/dnssec/dnssec-revoke.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-revoke.c,v 1.22 2010-05-06 23:50:56 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <libgen.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <isc/buffer.h>
+#include <isc/commandline.h>
+#include <isc/entropy.h>
+#include <isc/file.h>
+#include <isc/hash.h>
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/keyvalues.h>
+#include <dns/result.h>
+
+#include <dst/dst.h>
+
+#include "dnssectool.h"
+
+const char *program = "dnssec-revoke";
+int verbose;
+
+static isc_mem_t *mctx = NULL;
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s [options] keyfile\n\n", program);
+ fprintf(stderr, "Version: %s\n", VERSION);
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E engine: specify OpenSSL engine "
+ "(default \"pkcs11\")\n");
+#else
+ fprintf(stderr, " -E engine: specify OpenSSL engine\n");
+#endif
+ fprintf(stderr, " -f: force overwrite\n");
+ fprintf(stderr, " -K directory: use directory for key files\n");
+ fprintf(stderr, " -h: help\n");
+ fprintf(stderr, " -r: remove old keyfiles after "
+ "creating revoked version\n");
+ fprintf(stderr, " -v level: set level of verbosity\n");
+ fprintf(stderr, "Output:\n");
+ fprintf(stderr, " K<name>+<alg>+<new id>.key, "
+ "K<name>+<alg>+<new id>.private\n");
+
+ exit (-1);
+}
+
+int
+main(int argc, char **argv) {
+ isc_result_t result;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
+ char *filename = NULL, *dir = NULL;
+ char newname[1024], oldname[1024];
+ char keystr[DST_KEY_FORMATSIZE];
+ char *endp;
+ int ch;
+ isc_entropy_t *ectx = NULL;
+ dst_key_t *key = NULL;
+ isc_uint32_t flags;
+ isc_buffer_t buf;
+ isc_boolean_t force = ISC_FALSE;
+ isc_boolean_t remove = ISC_FALSE;
+
+ if (argc == 1)
+ usage();
+
+ result = isc_mem_create(0, 0, &mctx);
+ if (result != ISC_R_SUCCESS)
+ fatal("Out of memory");
+
+ dns_result_register();
+
+ isc_commandline_errprint = ISC_FALSE;
+
+ while ((ch = isc_commandline_parse(argc, argv, "E:fK:rhv:")) != -1) {
+ switch (ch) {
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
+ case 'f':
+ force = ISC_TRUE;
+ break;
+ case 'K':
+ /*
+ * We don't have to copy it here, but do it to
+ * simplify cleanup later
+ */
+ dir = isc_mem_strdup(mctx, isc_commandline_argument);
+ if (dir == NULL) {
+ fatal("Failed to allocate memory for "
+ "directory");
+ }
+ break;
+ case 'r':
+ remove = ISC_TRUE;
+ break;
+ case 'v':
+ verbose = strtol(isc_commandline_argument, &endp, 0);
+ if (*endp != '\0')
+ fatal("-v must be followed by a number");
+ break;
+ case '?':
+ if (isc_commandline_option != '?')
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
+ /* Falls into */
+ case 'h':
+ usage();
+
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
+ }
+ }
+
+ if (argc < isc_commandline_index + 1 ||
+ argv[isc_commandline_index] == NULL)
+ fatal("The key file name was not specified");
+ if (argc > isc_commandline_index + 1)
+ fatal("Extraneous arguments");
+
+ if (dir != NULL) {
+ filename = argv[isc_commandline_index];
+ } else {
+ result = isc_file_splitpath(mctx, argv[isc_commandline_index],
+ &dir, &filename);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot process filename %s: %s",
+ argv[isc_commandline_index],
+ isc_result_totext(result));
+ if (strcmp(dir, ".") == 0) {
+ isc_mem_free(mctx, dir);
+ dir = NULL;
+ }
+ }
+
+ if (ectx == NULL)
+ setup_entropy(mctx, NULL, &ectx);
+ result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
+ if (result != ISC_R_SUCCESS)
+ fatal("Could not initialize hash");
+ result = dst_lib_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ if (result != ISC_R_SUCCESS)
+ fatal("Could not initialize dst: %s",
+ isc_result_totext(result));
+ isc_entropy_stopcallbacksources(ectx);
+
+ result = dst_key_fromnamedfile(filename, dir,
+ DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
+ mctx, &key);
+ if (result != ISC_R_SUCCESS)
+ fatal("Invalid keyfile name %s: %s",
+ filename, isc_result_totext(result));
+
+ dst_key_format(key, keystr, sizeof(keystr));
+
+ if (verbose > 2)
+ fprintf(stderr, "%s: %s\n", program, keystr);
+
+ if (force)
+ set_keyversion(key);
+ else
+ check_keyversion(key, keystr);
+
+
+ flags = dst_key_flags(key);
+ if ((flags & DNS_KEYFLAG_REVOKE) == 0) {
+ isc_stdtime_t now;
+
+ if ((flags & DNS_KEYFLAG_KSK) == 0)
+ fprintf(stderr, "%s: warning: Key is not flagged "
+ "as a KSK. Revoking a ZSK is "
+ "legal, but undefined.\n",
+ program);
+
+ isc_stdtime_get(&now);
+ dst_key_settime(key, DST_TIME_REVOKE, now);
+
+ dst_key_setflags(key, flags | DNS_KEYFLAG_REVOKE);
+
+ isc_buffer_init(&buf, newname, sizeof(newname));
+ dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf);
+
+ if (access(newname, F_OK) == 0 && !force) {
+ fatal("Key file %s already exists; "
+ "use -f to force overwrite", newname);
+ }
+
+ result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
+ dir);
+ if (result != ISC_R_SUCCESS) {
+ dst_key_format(key, keystr, sizeof(keystr));
+ fatal("Failed to write key %s: %s", keystr,
+ isc_result_totext(result));
+ }
+
+ isc_buffer_clear(&buf);
+ dst_key_buildfilename(key, 0, dir, &buf);
+ printf("%s\n", newname);
+
+ /*
+ * Remove old key file, if told to (and if
+ * it isn't the same as the new file)
+ */
+ if (remove && dst_key_alg(key) != DST_ALG_RSAMD5) {
+ isc_buffer_init(&buf, oldname, sizeof(oldname));
+ dst_key_setflags(key, flags & ~DNS_KEYFLAG_REVOKE);
+ dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf);
+ if (strcmp(oldname, newname) == 0)
+ goto cleanup;
+ if (access(oldname, F_OK) == 0)
+ unlink(oldname);
+ isc_buffer_clear(&buf);
+ dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf);
+ if (access(oldname, F_OK) == 0)
+ unlink(oldname);
+ }
+ } else {
+ dst_key_format(key, keystr, sizeof(keystr));
+ fatal("Key %s is already revoked", keystr);
+ }
+
+cleanup:
+ dst_key_free(&key);
+ dst_lib_destroy();
+ isc_hash_destroy();
+ cleanup_entropy(&ectx);
+ if (verbose > 10)
+ isc_mem_stats(mctx, stdout);
+ if (dir != NULL)
+ isc_mem_free(mctx, dir);
+ isc_mem_destroy(&mctx);
+
+ return (0);
+}
diff --git a/bin/dnssec/dnssec-revoke.docbook b/bin/dnssec/dnssec-revoke.docbook
new file mode 100644
index 000000000000..b7b562021308
--- /dev/null
+++ b/bin/dnssec/dnssec-revoke.docbook
@@ -0,0 +1,149 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-revoke.docbook,v 1.7 2009-11-03 21:44:46 each Exp $ -->
+<refentry id="man.dnssec-revoke">
+ <refentryinfo>
+ <date>June 1, 2009</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>dnssec-revoke</application></refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>dnssec-revoke</application></refname>
+ <refpurpose>Set the REVOKED bit on a DNSSEC key</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2009</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>dnssec-revoke</command>
+ <arg><option>-hr</option></arg>
+ <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
+ <arg><option>-f</option></arg>
+ <arg choice="req">keyfile</arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para><command>dnssec-revoke</command>
+ reads a DNSSEC key file, sets the REVOKED bit on the key as defined
+ in RFC 5011, and creates a new pair of key files containing the
+ now-revoked key.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-h</term>
+ <listitem>
+ <para>
+ Emit usage message and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Sets the directory in which the key files are to reside.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-r</term>
+ <listitem>
+ <para>
+ After writing the new keyset files remove the original keyset
+ files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-v <replaceable class="parameter">level</replaceable></term>
+ <listitem>
+ <para>
+ Sets the debugging level.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-E <replaceable class="parameter">engine</replaceable></term>
+ <listitem>
+ <para>
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-f</term>
+ <listitem>
+ <para>
+ Force overwrite: Causes <command>dnssec-revoke</command> to
+ write the new key pair even if a file already exists matching
+ the algorithm and key ID of the revoked key.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para><citerefentry>
+ <refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citetitle>BIND 9 Administrator Reference Manual</citetitle>,
+ <citetitle>RFC 5011</citetitle>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>AUTHOR</title>
+ <para><corpauthor>Internet Systems Consortium</corpauthor>
+ </para>
+ </refsect1>
+
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->
diff --git a/bin/dnssec/dnssec-revoke.html b/bin/dnssec/dnssec-revoke.html
new file mode 100644
index 000000000000..fad9ac520196
--- /dev/null
+++ b/bin/dnssec/dnssec-revoke.html
@@ -0,0 +1,87 @@
+<!--
+ - Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-revoke.html,v 1.9 2010-05-19 01:14:14 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>dnssec-revoke</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
+<a name="man.dnssec-revoke"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">dnssec-revoke</span> &#8212; Set the REVOKED bit on a DNSSEC key</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">dnssec-revoke</code> [<code class="option">-hr</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-f</code>] {keyfile}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543373"></a><h2>DESCRIPTION</h2>
+<p><span><strong class="command">dnssec-revoke</strong></span>
+ reads a DNSSEC key file, sets the REVOKED bit on the key as defined
+ in RFC 5011, and creates a new pair of key files containing the
+ now-revoked key.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543385"></a><h2>OPTIONS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-h</span></dt>
+<dd><p>
+ Emit usage message and exit.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to reside.
+ </p></dd>
+<dt><span class="term">-r</span></dt>
+<dd><p>
+ After writing the new keyset files remove the original keyset
+ files.
+ </p></dd>
+<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
+<dd><p>
+ Sets the debugging level.
+ </p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </p></dd>
+<dt><span class="term">-f</span></dt>
+<dd><p>
+ Force overwrite: Causes <span><strong class="command">dnssec-revoke</strong></span> to
+ write the new key pair even if a file already exists matching
+ the algorithm and key ID of the revoked key.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543491"></a><h2>SEE ALSO</h2>
+<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>,
+ <em class="citetitle">RFC 5011</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543515"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div></body>
+</html>
diff --git a/bin/dnssec/dnssec-settime.8 b/bin/dnssec/dnssec-settime.8
new file mode 100644
index 000000000000..4390494474ce
--- /dev/null
+++ b/bin/dnssec/dnssec-settime.8
@@ -0,0 +1,166 @@
+.\" Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-settime.8,v 1.14 2010-08-17 01:15:26 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: dnssec\-settime
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: July 15, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "DNSSEC\-SETTIME" "8" "July 15, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+dnssec\-settime \- Set the key timing metadata for a DNSSEC key
+.SH "SYNOPSIS"
+.HP 15
+\fBdnssec\-settime\fR [\fB\-f\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-h\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] {keyfile}
+.SH "DESCRIPTION"
+.PP
+\fBdnssec\-settime\fR
+reads a DNSSEC private key file and sets the key timing metadata as specified by the
+\fB\-P\fR,
+\fB\-A\fR,
+\fB\-R\fR,
+\fB\-I\fR, and
+\fB\-D\fR
+options. The metadata can then be used by
+\fBdnssec\-signzone\fR
+or other signing software to determine when a key is to be published, whether it should be used for signing a zone, etc.
+.PP
+If none of these options is set on the command line, then
+\fBdnssec\-settime\fR
+simply prints the key timing metadata already stored in the key.
+.PP
+When key metadata fields are changed, both files of a key pair (\fIKnnnn.+aaa+iiiii.key\fR
+and
+\fIKnnnn.+aaa+iiiii.private\fR) are regenerated. Metadata fields are stored in the private file. A human\-readable description of the metadata is also placed in comments in the key file.
+.SH "OPTIONS"
+.PP
+\-f
+.RS 4
+Force an update of an old\-format key with no metadata fields. Without this option,
+\fBdnssec\-settime\fR
+will fail when attempting to update a legacy key. With this option, the key will be recreated in the new format, but with the original key data retained. The key's creation date will be set to the present time.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Sets the directory in which the key files are to reside.
+.RE
+.PP
+\-h
+.RS 4
+Emit usage message and exit.
+.RE
+.PP
+\-v \fIlevel\fR
+.RS 4
+Sets the debugging level.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Use the given OpenSSL engine. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
+.RE
+.SH "TIMING OPTIONS"
+.PP
+Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '\-', it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the offset is computed in years (defined as 365 24\-hour days, ignoring leap years), months (defined as 30 24\-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To unset a date, use 'none'.
+.PP
+\-P \fIdate/offset\fR
+.RS 4
+Sets the date on which a key is to be published to the zone. After that date, the key will be included in the zone but will not be used to sign it.
+.RE
+.PP
+\-A \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be activated. After that date, the key will be included in the zone and used to sign it.
+.RE
+.PP
+\-R \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be revoked. After that date, the key will be flagged as revoked. It will be included in the zone and will be used to sign it.
+.RE
+.PP
+\-I \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be retired. After that date, the key will still be included in the zone, but it will not be used to sign it.
+.RE
+.PP
+\-D \fIdate/offset\fR
+.RS 4
+Sets the date on which the key is to be deleted. After that date, the key will no longer be included in the zone. (It may remain in the key repository, however.)
+.RE
+.PP
+\-S \fIpredecessor key\fR
+.RS 4
+Select a key for which the key being modified will be an explicit successor. The name, algorithm, size, and type of the predecessor key must exactly match those of the key being modified. The activation date of the successor key will be set to the inactivation date of the predecessor. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.
+.RE
+.PP
+\-i \fIinterval\fR
+.RS 4
+Sets the prepublication interval for a key. If set, then the publication and activation dates must be separated by at least this much time. If the activation date is specified but the publication date isn't, then the publication date will default to this much time before the activation date; conversely, if the publication date is specified but activation date isn't, then activation will be set to this much time after publication.
+.sp
+If the key is being set to be an explicit successor to another key, then the default prepublication interval is 30 days; otherwise it is zero.
+.sp
+As with date offsets, if the argument is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the interval is measured in years, months, weeks, days, hours, or minutes, respectively. Without a suffix, the interval is measured in seconds.
+.RE
+.SH "PRINTING OPTIONS"
+.PP
+\fBdnssec\-settime\fR
+can also be used to print the timing metadata associated with a key.
+.PP
+\-u
+.RS 4
+Print times in UNIX epoch format.
+.RE
+.PP
+\-p \fIC/P/A/R/I/D/all\fR
+.RS 4
+Print a specific metadata value or set of metadata values. The
+\fB\-p\fR
+option may be followed by one or more of the following letters to indicate which value or values to print:
+\fBC\fR
+for the creation date,
+\fBP\fR
+for the publication date,
+\fBA\fR
+for the activation date,
+\fBR\fR
+for the revocation date,
+\fBI\fR
+for the inactivation date, or
+\fBD\fR
+for the deletion date. To print all of the metadata, use
+\fB\-p all\fR.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBdnssec\-keygen\fR(8),
+\fBdnssec\-signzone\fR(8),
+BIND 9 Administrator Reference Manual,
+RFC 5011.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/dnssec/dnssec-settime.c b/bin/dnssec/dnssec-settime.c
new file mode 100644
index 000000000000..364e2ab59268
--- /dev/null
+++ b/bin/dnssec/dnssec-settime.c
@@ -0,0 +1,576 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-settime.c,v 1.28 2010-12-19 07:29:36 each Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <libgen.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+
+#include <isc/buffer.h>
+#include <isc/commandline.h>
+#include <isc/entropy.h>
+#include <isc/file.h>
+#include <isc/hash.h>
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/keyvalues.h>
+#include <dns/result.h>
+
+#include <dst/dst.h>
+
+#include "dnssectool.h"
+
+const char *program = "dnssec-settime";
+int verbose;
+
+static isc_mem_t *mctx = NULL;
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s [options] keyfile\n\n", program);
+ fprintf(stderr, "Version: %s\n", VERSION);
+ fprintf(stderr, "General options:\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, " -E engine: specify OpenSSL engine "
+ "(default \"pkcs11\")\n");
+#else
+ fprintf(stderr, " -E engine: specify OpenSSL engine\n");
+#endif
+ fprintf(stderr, " -f: force update of old-style "
+ "keys\n");
+ fprintf(stderr, " -K directory: set key file location\n");
+ fprintf(stderr, " -v level: set level of verbosity\n");
+ fprintf(stderr, " -h: help\n");
+ fprintf(stderr, "Timing options:\n");
+ fprintf(stderr, " -P date/[+-]offset/none: set/unset key "
+ "publication date\n");
+ fprintf(stderr, " -A date/[+-]offset/none: set/unset key "
+ "activation date\n");
+ fprintf(stderr, " -R date/[+-]offset/none: set/unset key "
+ "revocation date\n");
+ fprintf(stderr, " -I date/[+-]offset/none: set/unset key "
+ "inactivation date\n");
+ fprintf(stderr, " -D date/[+-]offset/none: set/unset key "
+ "deletion date\n");
+ fprintf(stderr, "Printing options:\n");
+ fprintf(stderr, " -p C/P/A/R/I/D/all: print a particular time "
+ "value or values "
+ "[default: all]\n");
+ fprintf(stderr, " -u: print times in unix epoch "
+ "format\n");
+ fprintf(stderr, "Output:\n");
+ fprintf(stderr, " K<name>+<alg>+<new id>.key, "
+ "K<name>+<alg>+<new id>.private\n");
+
+ exit (-1);
+}
+
+static void
+printtime(dst_key_t *key, int type, const char *tag, isc_boolean_t epoch,
+ FILE *stream)
+{
+ isc_result_t result;
+ const char *output = NULL;
+ isc_stdtime_t when;
+
+ if (tag != NULL)
+ fprintf(stream, "%s: ", tag);
+
+ result = dst_key_gettime(key, type, &when);
+ if (result == ISC_R_NOTFOUND) {
+ fprintf(stream, "UNSET\n");
+ } else if (epoch) {
+ fprintf(stream, "%d\n", (int) when);
+ } else {
+ time_t time = when;
+ output = ctime(&time);
+ fprintf(stream, "%s", output);
+ }
+}
+
+int
+main(int argc, char **argv) {
+ isc_result_t result;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
+ char *filename = NULL, *directory = NULL;
+ char newname[1024];
+ char keystr[DST_KEY_FORMATSIZE];
+ char *endp, *p;
+ int ch;
+ isc_entropy_t *ectx = NULL;
+ const char *predecessor = NULL;
+ dst_key_t *prevkey = NULL;
+ dst_key_t *key = NULL;
+ isc_buffer_t buf;
+ dns_name_t *name = NULL;
+ dns_secalg_t alg = 0;
+ unsigned int size = 0;
+ isc_uint16_t flags = 0;
+ int prepub = -1;
+ isc_stdtime_t now;
+ isc_stdtime_t pub = 0, act = 0, rev = 0, inact = 0, del = 0;
+ isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE;
+ isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE;
+ isc_boolean_t setdel = ISC_FALSE;
+ isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE;
+ isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE;
+ isc_boolean_t unsetdel = ISC_FALSE;
+ isc_boolean_t printcreate = ISC_FALSE, printpub = ISC_FALSE;
+ isc_boolean_t printact = ISC_FALSE, printrev = ISC_FALSE;
+ isc_boolean_t printinact = ISC_FALSE, printdel = ISC_FALSE;
+ isc_boolean_t force = ISC_FALSE;
+ isc_boolean_t epoch = ISC_FALSE;
+ isc_boolean_t changed = ISC_FALSE;
+
+ if (argc == 1)
+ usage();
+
+ result = isc_mem_create(0, 0, &mctx);
+ if (result != ISC_R_SUCCESS)
+ fatal("Out of memory");
+
+ dns_result_register();
+
+ isc_commandline_errprint = ISC_FALSE;
+
+ isc_stdtime_get(&now);
+
+#define CMDLINE_FLAGS "A:D:E:fhI:i:K:P:p:R:S:uv:"
+ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
+ switch (ch) {
+ case 'E':
+ engine = isc_commandline_argument;
+ break;
+ case 'f':
+ force = ISC_TRUE;
+ break;
+ case 'p':
+ p = isc_commandline_argument;
+ if (!strcasecmp(p, "all")) {
+ printcreate = ISC_TRUE;
+ printpub = ISC_TRUE;
+ printact = ISC_TRUE;
+ printrev = ISC_TRUE;
+ printinact = ISC_TRUE;
+ printdel = ISC_TRUE;
+ break;
+ }
+
+ do {
+ switch (*p++) {
+ case 'C':
+ printcreate = ISC_TRUE;
+ break;
+ case 'P':
+ printpub = ISC_TRUE;
+ break;
+ case 'A':
+ printact = ISC_TRUE;
+ break;
+ case 'R':
+ printrev = ISC_TRUE;
+ break;
+ case 'I':
+ printinact = ISC_TRUE;
+ break;
+ case 'D':
+ printdel = ISC_TRUE;
+ break;
+ case ' ':
+ break;
+ default:
+ usage();
+ break;
+ }
+ } while (*p != '\0');
+ break;
+ case 'u':
+ epoch = ISC_TRUE;
+ break;
+ case 'K':
+ /*
+ * We don't have to copy it here, but do it to
+ * simplify cleanup later
+ */
+ directory = isc_mem_strdup(mctx,
+ isc_commandline_argument);
+ if (directory == NULL) {
+ fatal("Failed to allocate memory for "
+ "directory");
+ }
+ break;
+ case 'v':
+ verbose = strtol(isc_commandline_argument, &endp, 0);
+ if (*endp != '\0')
+ fatal("-v must be followed by a number");
+ break;
+ case 'P':
+ if (setpub || unsetpub)
+ fatal("-P specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetpub = ISC_TRUE;
+ } else {
+ setpub = ISC_TRUE;
+ pub = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'A':
+ if (setact || unsetact)
+ fatal("-A specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetact = ISC_TRUE;
+ } else {
+ setact = ISC_TRUE;
+ act = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'R':
+ if (setrev || unsetrev)
+ fatal("-R specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetrev = ISC_TRUE;
+ } else {
+ setrev = ISC_TRUE;
+ rev = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'I':
+ if (setinact || unsetinact)
+ fatal("-I specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetinact = ISC_TRUE;
+ } else {
+ setinact = ISC_TRUE;
+ inact = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'D':
+ if (setdel || unsetdel)
+ fatal("-D specified more than once");
+
+ changed = ISC_TRUE;
+ if (!strcasecmp(isc_commandline_argument, "none")) {
+ unsetdel = ISC_TRUE;
+ } else {
+ setdel = ISC_TRUE;
+ del = strtotime(isc_commandline_argument,
+ now, now);
+ }
+ break;
+ case 'S':
+ predecessor = isc_commandline_argument;
+ break;
+ case 'i':
+ prepub = strtottl(isc_commandline_argument);
+ break;
+ case '?':
+ if (isc_commandline_option != '?')
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
+ /* Falls into */
+ case 'h':
+ usage();
+
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
+ }
+ }
+
+ if (argc < isc_commandline_index + 1 ||
+ argv[isc_commandline_index] == NULL)
+ fatal("The key file name was not specified");
+ if (argc > isc_commandline_index + 1)
+ fatal("Extraneous arguments");
+
+ if (ectx == NULL)
+ setup_entropy(mctx, NULL, &ectx);
+ result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
+ if (result != ISC_R_SUCCESS)
+ fatal("Could not initialize hash");
+ result = dst_lib_init2(mctx, ectx, engine,
+ ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
+ if (result != ISC_R_SUCCESS)
+ fatal("Could not initialize dst: %s",
+ isc_result_totext(result));
+ isc_entropy_stopcallbacksources(ectx);
+
+ if (predecessor != NULL) {
+ char keystr[DST_KEY_FORMATSIZE];
+ isc_stdtime_t when;
+ int major, minor;
+
+ if (prepub == -1)
+ prepub = (30 * 86400);
+
+ if (setpub || unsetpub)
+ fatal("-S and -P cannot be used together");
+ if (setact || unsetact)
+ fatal("-S and -A cannot be used together");
+
+ result = dst_key_fromnamedfile(predecessor, directory,
+ DST_TYPE_PUBLIC |
+ DST_TYPE_PRIVATE,
+ mctx, &prevkey);
+ if (result != ISC_R_SUCCESS)
+ fatal("Invalid keyfile %s: %s",
+ filename, isc_result_totext(result));
+ if (!dst_key_isprivate(prevkey))
+ fatal("%s is not a private key", filename);
+
+ name = dst_key_name(prevkey);
+ alg = dst_key_alg(prevkey);
+ size = dst_key_size(prevkey);
+ flags = dst_key_flags(prevkey);
+
+ dst_key_format(prevkey, keystr, sizeof(keystr));
+ dst_key_getprivateformat(prevkey, &major, &minor);
+ if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
+ fatal("Predecessor has incompatible format "
+ "version %d.%d\n\t", major, minor);
+
+ result = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when);
+ if (result != ISC_R_SUCCESS)
+ fatal("Predecessor has no activation date. "
+ "You must set one before\n\t"
+ "generating a successor.");
+
+ result = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &act);
+ if (result != ISC_R_SUCCESS)
+ fatal("Predecessor has no inactivation date. "
+ "You must set one before\n\t"
+ "generating a successor.");
+
+ pub = act - prepub;
+ if (pub < now && prepub != 0)
+ fatal("Predecessor will become inactive before the\n\t"
+ "prepublication period ends. Either change "
+ "its inactivation date,\n\t"
+ "or use the -i option to set a shorter "
+ "prepublication interval.");
+
+ result = dst_key_gettime(prevkey, DST_TIME_DELETE, &when);
+ if (result != ISC_R_SUCCESS)
+ fprintf(stderr, "%s: WARNING: Predecessor has no "
+ "removal date;\n\t"
+ "it will remain in the zone "
+ "indefinitely after rollover.\n",
+ program);
+
+ changed = setpub = setact = ISC_TRUE;
+ dst_key_free(&prevkey);
+ } else {
+ if (prepub < 0)
+ prepub = 0;
+
+ if (prepub > 0) {
+ if (setpub && setact && (act - prepub) < pub)
+ fatal("Activation and publication dates "
+ "are closer together than the\n\t"
+ "prepublication interval.");
+
+ if (setpub && !setact) {
+ setact = ISC_TRUE;
+ act = pub + prepub;
+ } else if (setact && !setpub) {
+ setpub = ISC_TRUE;
+ pub = act - prepub;
+ }
+
+ if ((act - prepub) < now)
+ fatal("Time until activation is shorter "
+ "than the\n\tprepublication interval.");
+ }
+ }
+
+ if (directory != NULL) {
+ filename = argv[isc_commandline_index];
+ } else {
+ result = isc_file_splitpath(mctx, argv[isc_commandline_index],
+ &directory, &filename);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot process filename %s: %s",
+ argv[isc_commandline_index],
+ isc_result_totext(result));
+ }
+
+ result = dst_key_fromnamedfile(filename, directory,
+ DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
+ mctx, &key);
+ if (result != ISC_R_SUCCESS)
+ fatal("Invalid keyfile %s: %s",
+ filename, isc_result_totext(result));
+
+ if (!dst_key_isprivate(key))
+ fatal("%s is not a private key", filename);
+
+ dst_key_format(key, keystr, sizeof(keystr));
+
+ if (predecessor != NULL) {
+ if (!dns_name_equal(name, dst_key_name(key)))
+ fatal("Key name mismatch");
+ if (alg != dst_key_alg(key))
+ fatal("Key algorithm mismatch");
+ if (size != dst_key_size(key))
+ fatal("Key size mismatch");
+ if (flags != dst_key_flags(key))
+ fatal("Key flags mismatch");
+ }
+
+ if (force)
+ set_keyversion(key);
+ else
+ check_keyversion(key, keystr);
+
+ if (verbose > 2)
+ fprintf(stderr, "%s: %s\n", program, keystr);
+
+ /*
+ * Set time values.
+ */
+ if (setpub)
+ dst_key_settime(key, DST_TIME_PUBLISH, pub);
+ else if (unsetpub)
+ dst_key_unsettime(key, DST_TIME_PUBLISH);
+
+ if (setact)
+ dst_key_settime(key, DST_TIME_ACTIVATE, act);
+ else if (unsetact)
+ dst_key_unsettime(key, DST_TIME_ACTIVATE);
+
+ if (setrev) {
+ if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0)
+ fprintf(stderr, "%s: warning: Key %s is already "
+ "revoked; changing the revocation date "
+ "will not affect this.\n",
+ program, keystr);
+ if ((dst_key_flags(key) & DNS_KEYFLAG_KSK) == 0)
+ fprintf(stderr, "%s: warning: Key %s is not flagged as "
+ "a KSK, but -R was used. Revoking a "
+ "ZSK is legal, but undefined.\n",
+ program, keystr);
+ dst_key_settime(key, DST_TIME_REVOKE, rev);
+ } else if (unsetrev) {
+ if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0)
+ fprintf(stderr, "%s: warning: Key %s is already "
+ "revoked; removing the revocation date "
+ "will not affect this.\n",
+ program, keystr);
+ dst_key_unsettime(key, DST_TIME_REVOKE);
+ }
+
+ if (setinact)
+ dst_key_settime(key, DST_TIME_INACTIVE, inact);
+ else if (unsetinact)
+ dst_key_unsettime(key, DST_TIME_INACTIVE);
+
+ if (setdel)
+ dst_key_settime(key, DST_TIME_DELETE, del);
+ else if (unsetdel)
+ dst_key_unsettime(key, DST_TIME_DELETE);
+
+ /*
+ * Print out time values, if -p was used.
+ */
+ if (printcreate)
+ printtime(key, DST_TIME_CREATED, "Created", epoch, stdout);
+
+ if (printpub)
+ printtime(key, DST_TIME_PUBLISH, "Publish", epoch, stdout);
+
+ if (printact)
+ printtime(key, DST_TIME_ACTIVATE, "Activate", epoch, stdout);
+
+ if (printrev)
+ printtime(key, DST_TIME_REVOKE, "Revoke", epoch, stdout);
+
+ if (printinact)
+ printtime(key, DST_TIME_INACTIVE, "Inactive", epoch, stdout);
+
+ if (printdel)
+ printtime(key, DST_TIME_DELETE, "Delete", epoch, stdout);
+
+ if (changed) {
+ isc_buffer_init(&buf, newname, sizeof(newname));
+ result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory,
+ &buf);
+ if (result != ISC_R_SUCCESS) {
+ fatal("Failed to build public key filename: %s",
+ isc_result_totext(result));
+ }
+
+ result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
+ directory);
+ if (result != ISC_R_SUCCESS) {
+ dst_key_format(key, keystr, sizeof(keystr));
+ fatal("Failed to write key %s: %s", keystr,
+ isc_result_totext(result));
+ }
+
+ printf("%s\n", newname);
+
+ isc_buffer_clear(&buf);
+ result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory,
+ &buf);
+ if (result != ISC_R_SUCCESS) {
+ fatal("Failed to build private key filename: %s",
+ isc_result_totext(result));
+ }
+ printf("%s\n", newname);
+ }
+
+ dst_key_free(&key);
+ dst_lib_destroy();
+ isc_hash_destroy();
+ cleanup_entropy(&ectx);
+ if (verbose > 10)
+ isc_mem_stats(mctx, stdout);
+ isc_mem_free(mctx, directory);
+ isc_mem_destroy(&mctx);
+
+ return (0);
+}
diff --git a/bin/dnssec/dnssec-settime.docbook b/bin/dnssec/dnssec-settime.docbook
new file mode 100644
index 000000000000..1096cb7ec5ae
--- /dev/null
+++ b/bin/dnssec/dnssec-settime.docbook
@@ -0,0 +1,319 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-settime.docbook,v 1.11 2010-08-16 22:21:06 marka Exp $ -->
+<refentry id="man.dnssec-settime">
+ <refentryinfo>
+ <date>July 15, 2009</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>dnssec-settime</application></refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>dnssec-settime</application></refname>
+ <refpurpose>Set the key timing metadata for a DNSSEC key</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2009</year>
+ <year>2010</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>dnssec-settime</command>
+ <arg><option>-f</option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
+ <arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-A <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-R <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-I <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
+ <arg><option>-h</option></arg>
+ <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
+ <arg choice="req">keyfile</arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para><command>dnssec-settime</command>
+ reads a DNSSEC private key file and sets the key timing metadata
+ as specified by the <option>-P</option>, <option>-A</option>,
+ <option>-R</option>, <option>-I</option>, and <option>-D</option>
+ options. The metadata can then be used by
+ <command>dnssec-signzone</command> or other signing software to
+ determine when a key is to be published, whether it should be
+ used for signing a zone, etc.
+ </para>
+ <para>
+ If none of these options is set on the command line,
+ then <command>dnssec-settime</command> simply prints the key timing
+ metadata already stored in the key.
+ </para>
+ <para>
+ When key metadata fields are changed, both files of a key
+ pair (<filename>Knnnn.+aaa+iiiii.key</filename> and
+ <filename>Knnnn.+aaa+iiiii.private</filename>) are regenerated.
+ Metadata fields are stored in the private file. A human-readable
+ description of the metadata is also placed in comments in the key
+ file.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>-f</term>
+ <listitem>
+ <para>
+ Force an update of an old-format key with no metadata fields.
+ Without this option, <command>dnssec-settime</command> will
+ fail when attempting to update a legacy key. With this option,
+ the key will be recreated in the new format, but with the
+ original key data retained. The key's creation date will be
+ set to the present time.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Sets the directory in which the key files are to reside.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-h</term>
+ <listitem>
+ <para>
+ Emit usage message and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-v <replaceable class="parameter">level</replaceable></term>
+ <listitem>
+ <para>
+ Sets the debugging level.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-E <replaceable class="parameter">engine</replaceable></term>
+ <listitem>
+ <para>
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>TIMING OPTIONS</title>
+ <para>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds. To unset a date, use 'none'.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-P <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-A <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-R <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-I <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-D <replaceable class="parameter">date/offset</replaceable></term>
+ <listitem>
+ <para>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-S <replaceable class="parameter">predecessor key</replaceable></term>
+ <listitem>
+ <para>
+ Select a key for which the key being modified will be an
+ explicit successor. The name, algorithm, size, and type of the
+ predecessor key must exactly match those of the key being
+ modified. The activation date of the successor key will be set
+ to the inactivation date of the predecessor. The publication
+ date will be set to the activation date minus the prepublication
+ interval, which defaults to 30 days.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-i <replaceable class="parameter">interval</replaceable></term>
+ <listitem>
+ <para>
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+ </para>
+ <para>
+ If the key is being set to be an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+ </para>
+ <para>
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>PRINTING OPTIONS</title>
+ <para>
+ <command>dnssec-settime</command> can also be used to print the
+ timing metadata associated with a key.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-u</term>
+ <listitem>
+ <para>
+ Print times in UNIX epoch format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-p <replaceable class="parameter">C/P/A/R/I/D/all</replaceable></term>
+ <listitem>
+ <para>
+ Print a specific metadata value or set of metadata values.
+ The <option>-p</option> option may be followed by one or more
+ of the following letters to indicate which value or values to print:
+ <option>C</option> for the creation date,
+ <option>P</option> for the publication date,
+ <option>A</option> for the activation date,
+ <option>R</option> for the revocation date,
+ <option>I</option> for the inactivation date, or
+ <option>D</option> for the deletion date.
+ To print all of the metadata, use <option>-p all</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para><citerefentry>
+ <refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>dnssec-signzone</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citetitle>BIND 9 Administrator Reference Manual</citetitle>,
+ <citetitle>RFC 5011</citetitle>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>AUTHOR</title>
+ <para><corpauthor>Internet Systems Consortium</corpauthor>
+ </para>
+ </refsect1>
+
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->
diff --git a/bin/dnssec/dnssec-settime.html b/bin/dnssec/dnssec-settime.html
new file mode 100644
index 000000000000..84c8dde49a1d
--- /dev/null
+++ b/bin/dnssec/dnssec-settime.html
@@ -0,0 +1,208 @@
+<!--
+ - Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-settime.html,v 1.14 2010-08-17 01:15:26 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>dnssec-settime</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
+<a name="man.dnssec-settime"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">dnssec-settime</span> &#8212; Set the key timing metadata for a DNSSEC key</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">dnssec-settime</code> [<code class="option">-f</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-I <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-h</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] {keyfile}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543419"></a><h2>DESCRIPTION</h2>
+<p><span><strong class="command">dnssec-settime</strong></span>
+ reads a DNSSEC private key file and sets the key timing metadata
+ as specified by the <code class="option">-P</code>, <code class="option">-A</code>,
+ <code class="option">-R</code>, <code class="option">-I</code>, and <code class="option">-D</code>
+ options. The metadata can then be used by
+ <span><strong class="command">dnssec-signzone</strong></span> or other signing software to
+ determine when a key is to be published, whether it should be
+ used for signing a zone, etc.
+ </p>
+<p>
+ If none of these options is set on the command line,
+ then <span><strong class="command">dnssec-settime</strong></span> simply prints the key timing
+ metadata already stored in the key.
+ </p>
+<p>
+ When key metadata fields are changed, both files of a key
+ pair (<code class="filename">Knnnn.+aaa+iiiii.key</code> and
+ <code class="filename">Knnnn.+aaa+iiiii.private</code>) are regenerated.
+ Metadata fields are stored in the private file. A human-readable
+ description of the metadata is also placed in comments in the key
+ file.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543467"></a><h2>OPTIONS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-f</span></dt>
+<dd><p>
+ Force an update of an old-format key with no metadata fields.
+ Without this option, <span><strong class="command">dnssec-settime</strong></span> will
+ fail when attempting to update a legacy key. With this option,
+ the key will be recreated in the new format, but with the
+ original key data retained. The key's creation date will be
+ set to the present time.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to reside.
+ </p></dd>
+<dt><span class="term">-h</span></dt>
+<dd><p>
+ Emit usage message and exit.
+ </p></dd>
+<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
+<dd><p>
+ Sets the debugging level.
+ </p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543559"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds. To unset a date, use 'none'.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it.
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it.
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-I <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </p></dd>
+<dt><span class="term">-S <em class="replaceable"><code>predecessor key</code></em></span></dt>
+<dd><p>
+ Select a key for which the key being modified will be an
+ explicit successor. The name, algorithm, size, and type of the
+ predecessor key must exactly match those of the key being
+ modified. The activation date of the successor key will be set
+ to the inactivation date of the predecessor. The publication
+ date will be set to the activation date minus the prepublication
+ interval, which defaults to 30 days.
+ </p></dd>
+<dt><span class="term">-i <em class="replaceable"><code>interval</code></em></span></dt>
+<dd>
+<p>
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+ </p>
+<p>
+ If the key is being set to be an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+ </p>
+<p>
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+ </p>
+</dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543698"></a><h2>PRINTING OPTIONS</h2>
+<p>
+ <span><strong class="command">dnssec-settime</strong></span> can also be used to print the
+ timing metadata associated with a key.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-u</span></dt>
+<dd><p>
+ Print times in UNIX epoch format.
+ </p></dd>
+<dt><span class="term">-p <em class="replaceable"><code>C/P/A/R/I/D/all</code></em></span></dt>
+<dd><p>
+ Print a specific metadata value or set of metadata values.
+ The <code class="option">-p</code> option may be followed by one or more
+ of the following letters to indicate which value or values to print:
+ <code class="option">C</code> for the creation date,
+ <code class="option">P</code> for the publication date,
+ <code class="option">A</code> for the activation date,
+ <code class="option">R</code> for the revocation date,
+ <code class="option">I</code> for the inactivation date, or
+ <code class="option">D</code> for the deletion date.
+ To print all of the metadata, use <code class="option">-p all</code>.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543912"></a><h2>SEE ALSO</h2>
+<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
+ <span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>,
+ <em class="citetitle">RFC 5011</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543945"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div></body>
+</html>
diff --git a/bin/dnssec/dnssec-signzone.8 b/bin/dnssec/dnssec-signzone.8
index bfe7a2013b18..9822883747b8 100644
--- a/bin/dnssec/dnssec-signzone.8
+++ b/bin/dnssec/dnssec-signzone.8
@@ -13,18 +13,18 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: dnssec-signzone.8,v 1.47.44.8 2009-11-07 01:56:11 tbox Exp $
+.\" $Id: dnssec-signzone.8,v 1.59 2009-12-04 01:13:44 tbox Exp $
.\"
.hy 0
.ad l
.\" Title: dnssec\-signzone
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
-.\" Date: June 08, 2009
+.\" Date: June 05, 2009
.\" Manual: BIND9
.\" Source: BIND9
.\"
-.TH "DNSSEC\-SIGNZONE" "8" "June 08, 2009" "BIND9" "BIND9"
+.TH "DNSSEC\-SIGNZONE" "8" "June 05, 2009" "BIND9" "BIND9"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -33,15 +33,13 @@
dnssec\-signzone \- DNSSEC zone signing tool
.SH "SYNOPSIS"
.HP 16
-\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-P\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-t\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...]
+\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-P\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-T\ \fR\fB\fIttl\fR\fR] [\fB\-t\fR] [\fB\-u\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-x\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...]
.SH "DESCRIPTION"
.PP
\fBdnssec\-signzone\fR
-signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. It also generates a
-\fIkeyset\-\fR
-file containing the key\-signing keys for the zone, and if signing a zone which contains delegations, it can optionally generate DS records for the child zones from their
-\fIkeyset\-\fR
-files.
+signs a zone. It generates NSEC and RRSIG records and produces a signed version of the zone. The security status of delegations from the signed zone (that is, whether the child zones are secure or not) is determined by the presence or absence of a
+\fIkeyset\fR
+file for each child zone.
.SH "OPTIONS"
.PP
\-a
@@ -54,30 +52,53 @@ Verify all generated signatures.
Specifies the DNS class of the zone.
.RE
.PP
-\-k \fIkey\fR
-.RS 4
-Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times.
-.RE
-.PP
-\-l \fIdomain\fR
+\-C
.RS 4
-Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records.
+Compatibility mode: Generate a
+\fIkeyset\-\fR\fI\fIzonename\fR\fR
+file in addition to
+\fIdsset\-\fR\fI\fIzonename\fR\fR
+when signing a zone, for use by older versions of
+\fBdnssec\-signzone\fR.
.RE
.PP
\-d \fIdirectory\fR
.RS 4
Look for
-\fIkeyset\fR
+\fIdsset\-\fR
+or
+\fIkeyset\-\fR
files in
-\fBdirectory\fR
-as the directory
+\fBdirectory\fR.
+.RE
+.PP
+\-E \fIengine\fR
+.RS 4
+Uses a crypto hardware (OpenSSL engine) for the crypto operations it supports, for instance signing with private keys from a secure key store. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine.
.RE
.PP
\-g
.RS 4
-If the zone contains any delegations, and there are
+Generate DS records for child zones from
+\fIdsset\-\fR
+or
\fIkeyset\-\fR
-files for any of the child zones, then DS records for the child zones will be generated from the keys in those files. Existing DS records will be removed.
+file. Existing DS records will be removed.
+.RE
+.PP
+\-K \fIdirectory\fR
+.RS 4
+Key repository: Specify a directory to search for DNSSEC keys. If not specified, defaults to the current directory.
+.RE
+.PP
+\-k \fIkey\fR
+.RS 4
+Treat specified key as a key signing key ignoring any key flags. This option may be specified multiple times.
+.RE
+.PP
+\-l \fIdomain\fR
+.RS 4
+Generate a DLV set in addition to the key (DNSKEY) and DS sets. The domain is appended to the name of the records.
.RE
.PP
\-s \fIstart\-time\fR
@@ -93,6 +114,9 @@ Specify the date and time when the generated RRSIG records expire. As with
\fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no
\fBend\-time\fR
is specified, 30 days from the start time is used as a default.
+\fBend\-time\fR
+must be later than
+\fBstart\-time\fR.
.RE
.PP
\-f \fIoutput\-file\fR
@@ -208,34 +232,94 @@ specifies the name of a character device or file containing random data to be us
indicates that keyboard input should be used.
.RE
.PP
+\-S
+.RS 4
+Smart signing: Instructs
+\fBdnssec\-signzone\fR
+to search the key repository for keys that match the zone being signed, and to include them in the zone if appropriate.
+.sp
+When a key is found, its timing metadata is examined to determine how it should be used, according to the following rules. Each successive rule takes priority over the prior ones:
+.RS 4
+.PP
+.RS 4
+If no timing metadata has been set for the key, the key is published in the zone and used to sign the zone.
+.RE
+.PP
+.RS 4
+If the key's publication date is set and is in the past, the key is published in the zone.
+.RE
+.PP
+.RS 4
+If the key's activation date is set and in the past, the key is published (regardless of publication date) and used to sign the zone.
+.RE
+.PP
+.RS 4
+If the key's revocation date is set and in the past, and the key is published, then the key is revoked, and the revoked key is used to sign the zone.
+.RE
+.PP
+.RS 4
+If either of the key's unpublication or deletion dates are set and in the past, the key is NOT published or used to sign the zone, regardless of any other metadata.
+.RE
+.RE
+.RE
+.PP
+\-T \fIttl\fR
+.RS 4
+Specifies the TTL to be used for new DNSKEY records imported into the zone from the key repository. If not specified, the default is the minimum TTL value from the zone's SOA record. This option is ignored when signing without
+\fB\-S\fR, since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre\-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match them.
+.RE
+.PP
\-t
.RS 4
Print statistics at completion.
.RE
.PP
+\-u
+.RS 4
+Update NSEC/NSEC3 chain when re\-signing a previously signed zone. With this option, a zone signed with NSEC can be switched to NSEC3, or a zone signed with NSEC3 can be switch to NSEC or to NSEC3 with different parameters. Without this option,
+\fBdnssec\-signzone\fR
+will retain the existing chain when re\-signing.
+.RE
+.PP
\-v \fIlevel\fR
.RS 4
Sets the debugging level.
.RE
.PP
+\-x
+.RS 4
+Only sign the DNSKEY RRset with key\-signing keys, and omit signatures from zone\-signing keys. (This is similar to the
+\fBdnssec\-dnskey\-kskonly yes;\fR
+zone option in
+\fBnamed\fR.)
+.RE
+.PP
\-z
.RS 4
-Ignore KSK flag on key when determining what to sign.
+Ignore KSK flag on key when determining what to sign. This causes KSK\-flagged keys to sign all records, not just the DNSKEY RRset. (This is similar to the
+\fBupdate\-check\-ksk no;\fR
+zone option in
+\fBnamed\fR.)
.RE
.PP
\-3 \fIsalt\fR
.RS 4
-Generate a NSEC3 chain with the given hex encoded salt. A dash (\fIsalt\fR) can be used to indicate that no salt is to be used when generating the NSEC3 chain.
+Generate an NSEC3 chain with the given hex encoded salt. A dash (\fIsalt\fR) can be used to indicate that no salt is to be used when generating the NSEC3 chain.
.RE
.PP
\-H \fIiterations\fR
.RS 4
-When generating a NSEC3 chain use this many interations. The default is 100.
+When generating an NSEC3 chain, use this many interations. The default is 10.
.RE
.PP
\-A
.RS 4
-When generating a NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations.
+When generating an NSEC3 chain set the OPTOUT flag on all NSEC3 records and do not generate NSEC3 records for insecure delegations.
+.sp
+Using this option twice (i.e.,
+\fB\-AA\fR) turns the OPTOUT flag off for all records. This is useful when using the
+\fB\-u\fR
+option to modify an NSEC3 chain which previously had OPTOUT set.
.RE
.PP
zonefile
@@ -253,9 +337,11 @@ The following command signs the
\fBexample.com\fR
zone with the DSA key generated by
\fBdnssec\-keygen\fR
-(Kexample.com.+003+17247). The zone's keys must be in the master file (\fIdb.example.com\fR). This invocation looks for
-\fIkeyset\fR
-files, in the current directory, so that DS records can be generated from them (\fB\-g\fR).
+(Kexample.com.+003+17247). Because the
+\fB\-S\fR
+option is not being used, the zone's keys must be in the master file (\fIdb.example.com\fR). This invocation looks for
+\fIdsset\fR
+files, in the current directory, so that DS records can be imported from them (\fB\-g\fR).
.sp
.RS 4
.nf
@@ -283,18 +369,6 @@ db.example.com.signed
%
.fi
.RE
-.SH "KNOWN BUGS"
-.PP
-\fBdnssec\-signzone\fR
-was designed so that it could sign a zone partially, using only a subset of the DNSSEC keys needed to produce a fully\-signed zone. This permits a zone administrator, for example, to sign a zone with one key on one machine, move the resulting partially\-signed zone to a second machine, and sign it again with a second key.
-.PP
-An unfortunate side\-effect of this flexibility is that
-\fBdnssec\-signzone\fR
-does not check to make sure it's signing a zone with any valid keys at all. An attempt to sign a zone without any keys will appear to succeed, producing a "signed" zone with no signatures. There is no warning issued when a zone is not fully signed.
-.PP
-This will be corrected in a future release. In the meantime, ISC recommends examining the output of
-\fBdnssec\-signzone\fR
-to confirm that the zone is properly signed by all keys before using it.
.SH "SEE ALSO"
.PP
\fBdnssec\-keygen\fR(8),
diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c
index b8f4d664b6da..3997a135b465 100644
--- a/bin/dnssec/dnssec-signzone.c
+++ b/bin/dnssec/dnssec-signzone.c
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.209.12.20 2010-06-03 23:47:48 tbox Exp $ */
+/* $Id: dnssec-signzone.c,v 1.262 2010-06-03 23:51:04 tbox Exp $ */
/*! \file */
@@ -87,6 +87,10 @@
#include "dnssectool.h"
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */
+#endif
+
const char *program = "dnssec-signzone";
int verbose;
@@ -97,22 +101,11 @@ static int nsec_datatype = dns_rdatatype_nsec;
#define IS_NSEC3 (nsec_datatype == dns_rdatatype_nsec3)
#define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
+#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
+
#define BUFSIZE 2048
#define MAXDSKEYS 8
-typedef struct signer_key_struct signer_key_t;
-
-struct signer_key_struct {
- dst_key_t *key;
- isc_boolean_t issigningkey;
- isc_boolean_t isdsk;
- isc_boolean_t isksk;
- isc_boolean_t wasused;
- isc_boolean_t commandline;
- 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)
@@ -128,7 +121,7 @@ struct signer_event {
dns_dbnode_t *node;
};
-static ISC_LIST(signer_key_t) keylist;
+static dns_dnsseckeylist_t keylist;
static unsigned int keycount = 0;
isc_rwlock_t keylist_lock;
static isc_stdtime_t starttime = 0, endtime = 0, now;
@@ -138,7 +131,8 @@ 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 dns_ttl_t zone_soa_min_ttl;
+static dns_ttl_t soa_ttl;
static FILE *fp;
static char *tempfile = NULL;
static const dns_master_style_t *masterstyle;
@@ -146,7 +140,7 @@ static dns_masterformat_t inputformat = dns_masterformat_text;
static dns_masterformat_t outputformat = dns_masterformat_text;
static unsigned int nsigned = 0, nretained = 0, ndropped = 0;
static unsigned int nverified = 0, nverifyfailed = 0;
-static const char *directory;
+static const char *directory = NULL, *dsdir = NULL;
static isc_mutex_t namelock, statslock;
static isc_taskmgr_t *taskmgr = NULL;
static dns_db_t *gdb; /* The database */
@@ -155,13 +149,18 @@ static dns_dbiterator_t *gdbiter; /* The database iterator */
static dns_rdataclass_t gclass; /* The class */
static dns_name_t *gorigin; /* The database origin */
static int nsec3flags = 0;
+static dns_iterations_t nsec3iter = 10U;
+static unsigned char saltbuf[255];
+static unsigned char *salt = saltbuf;
+static size_t salt_length = 0;
static isc_task_t *master = NULL;
static unsigned int ntasks = 0;
static isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE;
static isc_boolean_t nokeys = ISC_FALSE;
static isc_boolean_t removefile = ISC_FALSE;
static isc_boolean_t generateds = ISC_FALSE;
-static isc_boolean_t ignoreksk = ISC_FALSE;
+static isc_boolean_t ignore_kskflag = ISC_FALSE;
+static isc_boolean_t keyset_kskonly = ISC_FALSE;
static dns_name_t *dlv = NULL;
static dns_fixedname_t dlv_fixed;
static dns_master_style_t *dsstyle = NULL;
@@ -169,6 +168,9 @@ static unsigned int serialformat = SOA_SERIAL_KEEP;
static unsigned int hash_length = 0;
static isc_boolean_t unknownalg = ISC_FALSE;
static isc_boolean_t disable_zone_check = ISC_FALSE;
+static isc_boolean_t update_chain = ISC_FALSE;
+static isc_boolean_t set_keyttl = ISC_FALSE;
+static dns_ttl_t keyttl;
#define INCSTAT(counter) \
if (printstats) { \
@@ -195,48 +197,23 @@ dumpnode(dns_name_t *name, dns_dbnode_t *node) {
check_result(result, "dns_master_dumpnodetostream");
}
-static signer_key_t *
-newkeystruct(dst_key_t *dstkey, isc_boolean_t signwithkey) {
- signer_key_t *key;
-
- key = isc_mem_get(mctx, sizeof(signer_key_t));
- if (key == NULL)
- fatal("out of memory");
- key->key = dstkey;
- if ((dst_key_flags(dstkey) & DNS_KEYFLAG_KSK) != 0) {
- key->issigningkey = signwithkey;
- key->isksk = ISC_TRUE;
- key->isdsk = ISC_FALSE;
- } else {
- key->issigningkey = signwithkey;
- key->isksk = ISC_FALSE;
- key->isdsk = ISC_TRUE;
- }
- key->wasused = ISC_FALSE;
- key->commandline = ISC_FALSE;
- key->position = keycount++;
- ISC_LINK_INIT(key, link);
- return (key);
-}
-
/*%
* Sign the given RRset with given key, and add the signature record to the
* given tuple.
*/
-
static void
signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
dns_ttl_t ttl, dns_diff_t *add, const char *logmsg)
{
isc_result_t result;
isc_stdtime_t jendtime;
- char keystr[KEY_FORMATSIZE];
+ char keystr[DST_KEY_FORMATSIZE];
dns_rdata_t trdata = DNS_RDATA_INIT;
unsigned char array[BUFSIZE];
isc_buffer_t b;
dns_difftuple_t *tuple;
- key_format(key, keystr, sizeof(keystr));
+ dst_key_format(key, keystr, sizeof(keystr));
vbprintf(1, "\t%s %s\n", logmsg, keystr);
jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime;
@@ -245,8 +222,8 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
mctx, &b, &trdata);
isc_entropy_stopcallbacksources(ectx);
if (result != ISC_R_SUCCESS) {
- char keystr[KEY_FORMATSIZE];
- key_format(key, keystr, sizeof(keystr));
+ char keystr[DST_KEY_FORMATSIZE];
+ dst_key_format(key, keystr, sizeof(keystr));
fatal("dnskey '%s' failed to sign data: %s",
keystr, isc_result_totext(result));
}
@@ -272,31 +249,43 @@ signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
}
static inline isc_boolean_t
-issigningkey(signer_key_t *key) {
- return (key->issigningkey);
+issigningkey(dns_dnsseckey_t *key) {
+ return (key->force_sign || key->hint_sign);
}
static inline isc_boolean_t
-iszonekey(signer_key_t *key) {
+iszonekey(dns_dnsseckey_t *key) {
return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) &&
dst_key_iszonekey(key->key)));
}
+static inline isc_boolean_t
+isksk(dns_dnsseckey_t *key) {
+ return (key->ksk);
+}
+
+static inline isc_boolean_t
+iszsk(dns_dnsseckey_t *key) {
+ return (ignore_kskflag || !key->ksk);
+}
+
/*%
- * Find the key if it is in our list. If it is, return it, otherwise null.
+ * Find the key that generated an RRSIG, if it is in the key list. If
+ * so, return a pointer to it, otherwise return NULL.
+ *
* No locking is performed here, this must be done by the caller.
*/
-static signer_key_t *
+static dns_dnsseckey_t *
keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
- signer_key_t *key;
+ dns_dnsseckey_t *key;
- key = ISC_LIST_HEAD(keylist);
- while (key != NULL) {
+ for (key = ISC_LIST_HEAD(keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
if (rrsig->keyid == dst_key_id(key->key) &&
rrsig->algorithm == dst_key_alg(key->key) &&
dns_name_equal(&rrsig->signer, dst_key_name(key->key)))
return (key);
- key = ISC_LIST_NEXT(key, link);
}
return (NULL);
}
@@ -305,11 +294,11 @@ keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
* Finds the key that generated a RRSIG, if possible. First look at the keys
* that we've loaded already, and then see if there's a key on disk.
*/
-static signer_key_t *
+static dns_dnsseckey_t *
keythatsigned(dns_rdata_rrsig_t *rrsig) {
isc_result_t result;
dst_key_t *pubkey = NULL, *privkey = NULL;
- signer_key_t *key;
+ dns_dnsseckey_t *key = NULL;
isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read);
key = keythatsigned_unlocked(rrsig);
@@ -325,7 +314,6 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
* after all.
*/
isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write);
-
key = keythatsigned_unlocked(rrsig);
if (key != NULL) {
isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
@@ -334,7 +322,7 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
rrsig->algorithm, DST_TYPE_PUBLIC,
- NULL, mctx, &pubkey);
+ directory, mctx, &pubkey);
if (result != ISC_R_SUCCESS) {
isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
return (NULL);
@@ -343,12 +331,15 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
rrsig->algorithm,
DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
- NULL, mctx, &privkey);
+ directory, mctx, &privkey);
if (result == ISC_R_SUCCESS) {
dst_key_free(&pubkey);
- key = newkeystruct(privkey, ISC_FALSE);
- } else
- key = newkeystruct(pubkey, ISC_FALSE);
+ dns_dnsseckey_create(mctx, &privkey, &key);
+ } else {
+ dns_dnsseckey_create(mctx, &pubkey, &key);
+ }
+ key->force_publish = ISC_TRUE;
+ key->force_sign = ISC_FALSE;
ISC_LIST_APPEND(keylist, key, link);
isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
@@ -383,15 +374,16 @@ expecttofindkey(dns_name_t *name) {
dns_name_format(name, namestr, sizeof(namestr));
fatal("failure looking for '%s DNSKEY' in database: %s",
namestr, isc_result_totext(result));
+ /* NOTREACHED */
return (ISC_FALSE); /* removes a warning */
}
static inline isc_boolean_t
-setverifies(dns_name_t *name, dns_rdataset_t *set, signer_key_t *key,
+setverifies(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
dns_rdata_t *rrsig)
{
isc_result_t result;
- result = dns_dnssec_verify(name, set, key->key, ISC_FALSE, mctx, rrsig);
+ result = dns_dnssec_verify(name, set, key, ISC_FALSE, mctx, rrsig);
if (result == ISC_R_SUCCESS) {
INCSTAT(nverified);
return (ISC_TRUE);
@@ -413,7 +405,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
dns_rdataset_t sigset;
dns_rdata_t sigrdata = DNS_RDATA_INIT;
dns_rdata_rrsig_t rrsig;
- signer_key_t *key;
+ dns_dnsseckey_t *key;
isc_result_t result;
isc_boolean_t nosigs = ISC_FALSE;
isc_boolean_t *wassignedby, *nowsignedby;
@@ -483,8 +475,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
"invalid validity period\n",
sigstr);
} else if (key == NULL && !future &&
- expecttofindkey(&rrsig.signer))
- {
+ expecttofindkey(&rrsig.signer)) {
/* rrsig is dropped and not replaced */
vbprintf(2, "\trrsig by %s dropped - "
"private dnskey not found\n",
@@ -495,35 +486,33 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
if (!expired)
keep = ISC_TRUE;
} else if (issigningkey(key)) {
- if (!expired && setverifies(name, set, key, &sigrdata))
- {
+ if (!expired && setverifies(name, set, key->key,
+ &sigrdata)) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
keep = ISC_TRUE;
- wassignedby[key->position] = ISC_TRUE;
- nowsignedby[key->position] = ISC_TRUE;
- key->wasused = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr,
expired ? "expired" :
"failed to verify");
- wassignedby[key->position] = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
resign = ISC_TRUE;
}
} else if (iszonekey(key)) {
- if (!expired && setverifies(name, set, key, &sigrdata))
- {
+ if (!expired && setverifies(name, set, key->key,
+ &sigrdata)) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
keep = ISC_TRUE;
- wassignedby[key->position] = ISC_TRUE;
- nowsignedby[key->position] = ISC_TRUE;
- key->wasused = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr,
expired ? "expired" :
"failed to verify");
- wassignedby[key->position] = ISC_TRUE;
+ wassignedby[key->index] = ISC_TRUE;
}
} else if (!expired) {
vbprintf(2, "\trrsig by %s retained\n", sigstr);
@@ -533,7 +522,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
}
if (keep) {
- nowsignedby[key->position] = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
INCSTAT(nretained);
if (sigset.ttl != ttl) {
vbprintf(2, "\tfixing ttl %s\n", sigstr);
@@ -568,8 +557,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
signwithkey(name, set, key->key, ttl, add,
"resigning with dnskey");
- nowsignedby[key->position] = ISC_TRUE;
- key->wasused = ISC_TRUE;
+ nowsignedby[key->index] = ISC_TRUE;
}
dns_rdata_reset(&sigrdata);
@@ -587,20 +575,37 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
key != NULL;
key = ISC_LIST_NEXT(key, link))
{
- if (nowsignedby[key->position])
+ if (nowsignedby[key->index])
continue;
- if (!key->issigningkey)
- continue;
- if (!(ignoreksk || key->isdsk ||
- (key->isksk &&
- set->type == dns_rdatatype_dnskey &&
- dns_name_equal(name, gorigin))))
+ if (!issigningkey(key))
continue;
- signwithkey(name, set, key->key, ttl, add,
- "signing with dnskey");
- key->wasused = ISC_TRUE;
+ if (set->type == dns_rdatatype_dnskey &&
+ dns_name_equal(name, gorigin)) {
+ isc_boolean_t have_ksk;
+ dns_dnsseckey_t *tmpkey;
+
+ have_ksk = isksk(key);
+ for (tmpkey = ISC_LIST_HEAD(keylist);
+ tmpkey != NULL;
+ tmpkey = ISC_LIST_NEXT(tmpkey, link)) {
+ if (dst_key_alg(key->key) !=
+ dst_key_alg(tmpkey->key))
+ continue;
+ if (REVOKE(tmpkey->key))
+ continue;
+ if (isksk(tmpkey))
+ have_ksk = ISC_TRUE;
+ }
+ if (isksk(key) || !have_ksk ||
+ (iszsk(key) && !keyset_kskonly))
+ signwithkey(name, set, key->key, ttl, add,
+ "signing with dnskey");
+ } else if (iszsk(key)) {
+ signwithkey(name, set, key->key, ttl, add,
+ "signing with dnskey");
+ }
}
isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t));
@@ -774,16 +779,21 @@ static void
opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
dns_db_t **dbp)
{
- char filename[256];
+ char filename[PATH_MAX];
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] != '/')
+ if (dsdir != NULL) {
+ /* allow room for a trailing slash */
+ if (strlen(dsdir) >= isc_buffer_availablelength(&b))
+ fatal("path '%s' is too long", dsdir);
+ isc_buffer_putstr(&b, dsdir);
+ if (dsdir[strlen(dsdir) - 1] != '/')
isc_buffer_putstr(&b, "/");
}
+ if (strlen(prefix) > isc_buffer_availablelength(&b))
+ fatal("path '%s' is too long", dsdir);
isc_buffer_putstr(&b, prefix);
result = dns_name_tofilenametext(name, ISC_FALSE, &b);
check_result(result, "dns_name_tofilenametext()");
@@ -798,13 +808,15 @@ opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
rdclass, 0, NULL, dbp);
check_result(result, "dns_db_create()");
- result = dns_db_load(*dbp, filename);
+ result = dns_db_load3(*dbp, filename, inputformat, DNS_MASTER_HINT);
if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
dns_db_detach(dbp);
}
/*%
- * Loads the key set for a child zone, if there is one, and builds DS records.
+ * Load the DS set for a child zone, if a dsset-* file can be found.
+ * If not, try to find a keyset-* file from an earlier version of
+ * dnssec-signzone, and build DS records from that.
*/
static isc_result_t
loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
@@ -818,29 +830,49 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
dns_diff_t diff;
dns_difftuple_t *tuple = NULL;
+ opendb("dsset-", name, gclass, &db);
+ if (db != NULL) {
+ result = dns_db_findnode(db, name, ISC_FALSE, &node);
+ if (result == ISC_R_SUCCESS) {
+ dns_rdataset_init(dsset);
+ result = dns_db_findrdataset(db, node, NULL,
+ dns_rdatatype_ds, 0, 0,
+ dsset, NULL);
+ dns_db_detachnode(db, &node);
+ if (result == ISC_R_SUCCESS) {
+ vbprintf(2, "found DS records\n");
+ dsset->ttl = ttl;
+ dns_db_detach(&db);
+ return (result);
+ }
+ }
+ dns_db_detach(&db);
+ }
+
+ /* No DS records found; try again, looking for DNSKEY records */
opendb("keyset-", name, gclass, &db);
- if (db == NULL)
+ if (db == NULL) {
return (ISC_R_NOTFOUND);
+ }
result = dns_db_findnode(db, name, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS) {
dns_db_detach(&db);
- return (DNS_R_BADDB);
+ return (result);
}
+
dns_rdataset_init(&keyset);
- result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0,
- 0, &keyset, NULL);
+ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0,
+ &keyset, NULL);
if (result != ISC_R_SUCCESS) {
dns_db_detachnode(db, &node);
dns_db_detach(&db);
return (result);
}
-
vbprintf(2, "found DNSKEY records\n");
result = dns_db_newversion(db, &ver);
check_result(result, "dns_db_newversion");
-
dns_diff_init(mctx, &diff);
for (result = dns_rdataset_first(&keyset);
@@ -869,6 +901,7 @@ loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
check_result(result, "dns_difftuple_create");
dns_diff_append(&diff, &tuple);
}
+
result = dns_diff_apply(&diff, db, ver);
check_result(result, "dns_diff_apply");
dns_diff_clear(&diff);
@@ -1112,17 +1145,15 @@ active_node(dns_dbnode_t *node) {
}
/*%
- * Extracts the TTL from the SOA.
+ * Extracts the minimum TTL from the SOA record, and the SOA record's TTL.
*/
-static dns_ttl_t
-soattl(void) {
+static void
+get_soa_ttls(void) {
dns_rdataset_t soaset;
dns_fixedname_t fname;
dns_name_t *name;
isc_result_t result;
- dns_ttl_t ttl;
dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_soa_t soa;
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
@@ -1136,11 +1167,9 @@ soattl(void) {
result = dns_rdataset_first(&soaset);
check_result(result, "dns_rdataset_first");
dns_rdataset_current(&soaset, &rdata);
- result = dns_rdata_tostruct(&rdata, &soa, NULL);
- check_result(result, "dns_rdata_tostruct");
- ttl = soa.minimum;
+ zone_soa_min_ttl = dns_soa_getminimum(&rdata);
+ soa_ttl = soaset.ttl;
dns_rdataset_disassociate(&soaset);
- return (ttl);
}
/*%
@@ -1371,7 +1400,7 @@ verifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node,
for (i = 0; i < 256; i++)
if ((ksk_algorithms[i] != 0) &&
(set_algorithms[i] == 0)) {
- alg_format(i, algbuf, sizeof(algbuf));
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
fprintf(stderr, "Missing %s signature for "
"%s %s\n", algbuf, namebuf, typebuf);
bad_algorithms[i] = 1;
@@ -1414,8 +1443,8 @@ verifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation,
/*%
* Verify that certain things are sane:
*
- * The apex has a DNSKEY record with at least one KSK and at least
- * one ZSK.
+ * The apex has a DNSKEY record with at least one KSK, and at least
+ * one ZSK if the -x flag was not used.
*
* The DNSKEY record was signed with at least one of the KSKs in this
* set.
@@ -1440,8 +1469,10 @@ verifyzone(void) {
isc_boolean_t goodksk = ISC_FALSE;
isc_boolean_t goodzsk = ISC_FALSE;
isc_result_t result;
- unsigned char revoked[256];
- unsigned char standby[256];
+ unsigned char revoked_ksk[256];
+ unsigned char revoked_zsk[256];
+ unsigned char standby_ksk[256];
+ unsigned char standby_zsk[256];
unsigned char ksk_algorithms[256];
unsigned char zsk_algorithms[256];
unsigned char bad_algorithms[256];
@@ -1470,8 +1501,10 @@ verifyzone(void) {
if (!dns_rdataset_isassociated(&sigrdataset))
fatal("cannot find DNSKEY RRSIGs\n");
- memset(revoked, 0, sizeof(revoked));
- memset(standby, 0, sizeof(revoked));
+ memset(revoked_ksk, 0, sizeof(revoked_ksk));
+ memset(revoked_zsk, 0, sizeof(revoked_zsk));
+ memset(standby_ksk, 0, sizeof(standby_ksk));
+ memset(standby_zsk, 0, sizeof(standby_zsk));
memset(ksk_algorithms, 0, sizeof(ksk_algorithms));
memset(zsk_algorithms, 0, sizeof(zsk_algorithms));
memset(bad_algorithms, 0, sizeof(bad_algorithms));
@@ -1480,8 +1513,9 @@ verifyzone(void) {
#endif
/*
- * Check that the DNSKEY RR has at least one self signing KSK and
- * one ZSK per algorithm in it.
+ * Check that the DNSKEY RR has at least one self signing KSK
+ * and one ZSK per algorithm in it (or, if -x was used, one
+ * self-signing KSK).
*/
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
@@ -1511,8 +1545,11 @@ verifyzone(void) {
(int)isc_buffer_usedlength(&buf), buffer);
}
if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
- revoked[dnskey.algorithm] != 255)
- revoked[dnskey.algorithm]++;
+ revoked_ksk[dnskey.algorithm] != 255)
+ revoked_ksk[dnskey.algorithm]++;
+ else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 &&
+ revoked_zsk[dnskey.algorithm] != 255)
+ revoked_zsk[dnskey.algorithm]++;
} else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
&sigrdataset, ISC_FALSE, mctx)) {
@@ -1520,8 +1557,8 @@ verifyzone(void) {
ksk_algorithms[dnskey.algorithm]++;
goodksk = ISC_TRUE;
} else {
- if (standby[dnskey.algorithm] != 255)
- standby[dnskey.algorithm]++;
+ if (standby_ksk[dnskey.algorithm] != 255)
+ standby_ksk[dnskey.algorithm]++;
}
} else if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
&sigrdataset, ISC_FALSE,
@@ -1534,8 +1571,8 @@ verifyzone(void) {
zsk_algorithms[dnskey.algorithm]++;
goodzsk = ISC_TRUE;
} else {
- if (zsk_algorithms[dnskey.algorithm] != 255)
- zsk_algorithms[dnskey.algorithm]++;
+ if (standby_zsk[dnskey.algorithm] != 255)
+ standby_zsk[dnskey.algorithm]++;
#ifdef ALLOW_KSKLESS_ZONES
allzsksigned = ISC_FALSE;
#endif
@@ -1545,42 +1582,54 @@ verifyzone(void) {
}
dns_rdataset_disassociate(&sigrdataset);
- if (!goodksk) {
#ifdef ALLOW_KSKLESS_ZONES
- if (!goodzsk)
- fatal("no self signing keys found");
- fprintf(stderr, "No self signing KSK found. Using self signed "
- "ZSK's for active algorithm list.\n");
+ if (!goodksk) {
+ if (!ignore_kskflag)
+ fprintf(stderr, "No self signing KSK found. Using "
+ "self signed ZSK's for active "
+ "algorithm list.\n");
memcpy(ksk_algorithms, self_algorithms, sizeof(ksk_algorithms));
if (!allzsksigned)
fprintf(stderr, "warning: not all ZSK's are self "
"signed.\n");
+ }
#else
+ if (!goodksk) {
fatal("no self signed KSK's found");
-#endif
}
+#endif
fprintf(stderr, "Verifying the zone using the following algorithms:");
for (i = 0; i < 256; i++) {
- if (ksk_algorithms[i] != 0) {
- alg_format(i, algbuf, sizeof(algbuf));
+#ifdef ALLOW_KSKLESS_ZONES
+ if (ksk_algorithms[i] != 0 || zsk_algorithms[i] != 0)
+#else
+ if (ksk_algorithms[i] != 0)
+#endif
+ {
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
fprintf(stderr, " %s", algbuf);
}
}
fprintf(stderr, ".\n");
- for (i = 0; i < 256; i++) {
- /*
- * The counts should both be zero or both be non-zero.
- * Mark the algorithm as bad if this is not met.
- */
- if ((ksk_algorithms[i] != 0) == (zsk_algorithms[i] != 0))
- continue;
- alg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, "Missing %s for algorithm %s\n",
- (ksk_algorithms[i] != 0) ? "ZSK" : "self signing KSK",
- algbuf);
- bad_algorithms[i] = 1;
+ if (!ignore_kskflag && !keyset_kskonly) {
+ for (i = 0; i < 256; i++) {
+ /*
+ * The counts should both be zero or both be non-zero.
+ * Mark the algorithm as bad if this is not met.
+ */
+ if ((ksk_algorithms[i] != 0) ==
+ (zsk_algorithms[i] != 0))
+ continue;
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Missing %s for algorithm %s\n",
+ (ksk_algorithms[i] != 0)
+ ? "ZSK"
+ : "self signing KSK",
+ algbuf);
+ bad_algorithms[i] = 1;
+ }
}
/*
@@ -1674,7 +1723,7 @@ verifyzone(void) {
if (first)
fprintf(stderr, "The zone is not fully signed "
"for the following algorithms:");
- alg_format(i, algbuf, sizeof(algbuf));
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
fprintf(stderr, " %s", algbuf);
first = ISC_FALSE;
}
@@ -1684,21 +1733,30 @@ verifyzone(void) {
fatal("DNSSEC completeness test failed.");
}
- if (goodksk) {
+ if (goodksk || ignore_kskflag) {
/*
* Print the success summary.
*/
fprintf(stderr, "Zone signing complete:\n");
for (i = 0; i < 256; i++) {
- if ((zsk_algorithms[i] != 0) ||
- (ksk_algorithms[i] != 0) ||
- (revoked[i] != 0) || (standby[i] != 0)) {
- alg_format(i, algbuf, sizeof(algbuf));
- fprintf(stderr, "Algorithm: %s: ZSKs: %u, "
- "KSKs: %u active, %u revoked, %u "
- "stand-by\n", algbuf,
- zsk_algorithms[i], ksk_algorithms[i],
- revoked[i], standby[i]);
+ if ((ksk_algorithms[i] != 0) ||
+ (standby_ksk[i] != 0) ||
+ (revoked_zsk[i] != 0) ||
+ (zsk_algorithms[i] != 0) ||
+ (standby_zsk[i] != 0) ||
+ (revoked_zsk[i] != 0)) {
+ dns_secalg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Algorithm: %s: KSKs: "
+ "%u active, %u stand-by, %u revoked\n",
+ algbuf, ksk_algorithms[i],
+ standby_ksk[i], revoked_ksk[i]);
+ fprintf(stderr, "%*sZSKs: "
+ "%u active, %u %s, %u revoked\n",
+ (int) strlen(algbuf) + 13, "",
+ zsk_algorithms[i],
+ standby_zsk[i],
+ keyset_kskonly ? "present" : "stand-by",
+ revoked_zsk[i]);
}
}
}
@@ -1923,6 +1981,7 @@ add_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) {
dns_rdatatype_ds, 0);
check_result(result, "dns_db_deleterdataset");
}
+
result = loadds(name, nsttl, &dsset);
if (result == ISC_R_SUCCESS) {
result = dns_db_addrdataset(gdb, node, gversion, 0,
@@ -1953,7 +2012,7 @@ remove_records(dns_dbnode_t *node, dns_rdatatype_t which) {
dns_rdataset_init(&rdataset);
/*
- * Delete any NSEC records at the apex.
+ * Delete any records of the given type at the apex.
*/
result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
check_result(result, "dns_db_allrdatasets()");
@@ -1965,6 +2024,12 @@ remove_records(dns_dbnode_t *node, dns_rdatatype_t which) {
covers = rdataset.covers;
dns_rdataset_disassociate(&rdataset);
if (type == which || covers == which) {
+ if (which == dns_rdatatype_nsec && !update_chain)
+ fatal("Zone contains NSEC records. Use -u "
+ "to update to NSEC3.");
+ if (which == dns_rdatatype_nsec3param && !update_chain)
+ fatal("Zone contains NSEC3 chains. Use -u "
+ "to update to NSEC.");
result = dns_db_deleterdataset(gdb, node, gversion,
type, covers);
check_result(result, "dns_db_deleterdataset()");
@@ -2088,8 +2153,9 @@ nsecify(void) {
} else if (result != ISC_R_SUCCESS)
fatal("iterating through the database failed: %s",
isc_result_totext(result));
+ dns_dbiterator_pause(dbiter);
result = dns_nsec_build(gdb, gversion, node, nextname,
- zonettl);
+ zone_soa_min_ttl);
check_result(result, "dns_nsec_build()");
dns_db_detachnode(gdb, &node);
}
@@ -2320,6 +2386,97 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node,
check_result(result, "dns_db_deleterdataset(RRSIG(NSEC3))");
}
+static void
+rrset_remove_duplicates(dns_name_t *name, dns_rdataset_t *rdataset,
+ dns_diff_t *diff)
+{
+ dns_difftuple_t *tuple = NULL;
+ isc_result_t result;
+ unsigned int count1 = 0;
+ dns_rdataset_t tmprdataset;
+
+ dns_rdataset_init(&tmprdataset);
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_t rdata1 = DNS_RDATA_INIT;
+ unsigned int count2 = 0;
+
+ count1++;
+ dns_rdataset_current(rdataset, &rdata1);
+ dns_rdataset_clone(rdataset, &tmprdataset);
+ for (result = dns_rdataset_first(&tmprdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&tmprdataset)) {
+ dns_rdata_t rdata2 = DNS_RDATA_INIT;
+ count2++;
+ if (count1 >= count2)
+ continue;
+ dns_rdataset_current(&tmprdataset, &rdata2);
+ if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
+ result = dns_difftuple_create(mctx,
+ DNS_DIFFOP_DEL,
+ name,
+ rdataset->ttl,
+ &rdata2, &tuple);
+ check_result(result, "dns_difftuple_create");
+ dns_diff_append(diff, &tuple);
+ }
+ }
+ dns_rdataset_disassociate(&tmprdataset);
+ }
+}
+
+static void
+remove_duplicates(void) {
+ isc_result_t result;
+ dns_dbiterator_t *dbiter = NULL;
+ dns_rdatasetiter_t *rdsiter = NULL;
+ dns_diff_t diff;
+ dns_dbnode_t *node = NULL;
+ dns_rdataset_t rdataset;
+ dns_fixedname_t fname;
+ dns_name_t *name;
+
+ dns_diff_init(mctx, &diff);
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_rdataset_init(&rdataset);
+
+ result = dns_db_createiterator(gdb, 0, &dbiter);
+ check_result(result, "dns_db_createiterator()");
+
+ for (result = dns_dbiterator_first(dbiter);
+ result == ISC_R_SUCCESS;
+ result = dns_dbiterator_next(dbiter)) {
+
+ result = dns_dbiterator_current(dbiter, &node, name);
+ check_dns_dbiterator_current(result);
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, &rdataset);
+ rrset_remove_duplicates(name, &rdataset, &diff);
+ dns_rdataset_disassociate(&rdataset);
+ }
+ if (result != ISC_R_NOMORE)
+ fatal("rdatasets iteration failed.");
+ dns_rdatasetiter_destroy(&rdsiter);
+ dns_db_detachnode(gdb, &node);
+ }
+ if (result != ISC_R_NOMORE)
+ fatal("zone iteration failed.");
+
+ if (!ISC_LIST_EMPTY(diff.tuples)) {
+ result = dns_diff_applysilently(&diff, gdb, gversion);
+ check_result(result, "dns_diff_applysilently");
+ }
+ dns_diff_clear(&diff);
+ dns_dbiterator_destroy(&dbiter);
+}
+
/*
* Generate NSEC3 records for the zone.
*/
@@ -2546,7 +2703,7 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
*/
dns_dbiterator_pause(dbiter);
addnsec3(name, node, salt, salt_length, iterations,
- hashlist, zonettl);
+ hashlist, zone_soa_min_ttl);
dns_db_detachnode(gdb, &node);
/*
* Add NSEC3's for empty nodes. Use closest encloser logic.
@@ -2557,7 +2714,7 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
count--;
dns_name_split(nextname, count, NULL, nextname);
addnsec3(nextname, NULL, salt, salt_length,
- iterations, hashlist, zonettl);
+ iterations, hashlist, zone_soa_min_ttl);
}
}
dns_dbiterator_destroy(&dbiter);
@@ -2580,7 +2737,7 @@ loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
fatal("failed converting name '%s' to dns format: %s",
origin, isc_result_totext(result));
@@ -2600,90 +2757,169 @@ loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
* private keys from disk.
*/
static void
-loadzonekeys(dns_db_t *db) {
+loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
dns_dbnode_t *node;
- dns_dbversion_t *currentversion;
+ dns_dbversion_t *currentversion = NULL;
isc_result_t result;
- dst_key_t *keys[20];
- unsigned int nkeys, i;
-
- currentversion = NULL;
- dns_db_currentversion(db, &currentversion);
+ dns_rdataset_t rdataset, keysigs, soasigs;
node = NULL;
- result = dns_db_findnode(db, gorigin, ISC_FALSE, &node);
+ result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS)
fatal("failed to find the zone's origin: %s",
isc_result_totext(result));
- result = dns_dnssec_findzonekeys(db, currentversion, node, gorigin,
- mctx, 20, keys, &nkeys);
- if (result == ISC_R_NOTFOUND)
- result = ISC_R_SUCCESS;
+ dns_db_currentversion(gdb, &currentversion);
+
+ dns_rdataset_init(&rdataset);
+ dns_rdataset_init(&soasigs);
+ dns_rdataset_init(&keysigs);
+
+ /* Make note of the keys which signed the SOA, if any */
+ result = dns_db_findrdataset(gdb, node, currentversion,
+ dns_rdatatype_soa, 0, 0,
+ &rdataset, &soasigs);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Preserve the TTL of the DNSKEY RRset, if any */
+ dns_rdataset_disassociate(&rdataset);
+ result = dns_db_findrdataset(gdb, node, currentversion,
+ dns_rdatatype_dnskey, 0, 0,
+ &rdataset, &keysigs);
+
if (result != ISC_R_SUCCESS)
- fatal("failed to find the zone keys: %s",
+ goto cleanup;
+
+ if (set_keyttl && keyttl != rdataset.ttl) {
+ fprintf(stderr, "User-specified TTL (%d) conflicts "
+ "with existing DNSKEY RRset TTL.\n",
+ keyttl);
+ fprintf(stderr, "Imported keys will use the RRSet "
+ "TTL (%d) instead.\n",
+ rdataset.ttl);
+ }
+ keyttl = rdataset.ttl;
+
+ /* Load keys corresponding to the existing DNSKEY RRset */
+ result = dns_dnssec_keylistfromrdataset(gorigin, directory, mctx,
+ &rdataset, &keysigs, &soasigs,
+ preserve_keys, load_public,
+ &keylist);
+ if (result != ISC_R_SUCCESS)
+ fatal("failed to load the zone keys: %s",
isc_result_totext(result));
- for (i = 0; i < nkeys; i++) {
- signer_key_t *key;
+ cleanup:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (dns_rdataset_isassociated(&keysigs))
+ dns_rdataset_disassociate(&keysigs);
+ if (dns_rdataset_isassociated(&soasigs))
+ dns_rdataset_disassociate(&soasigs);
+ dns_db_detachnode(gdb, &node);
+ dns_db_closeversion(gdb, &currentversion, ISC_FALSE);
+}
+
+static void
+loadexplicitkeys(char *keyfiles[], int n, isc_boolean_t setksk) {
+ isc_result_t result;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ dns_dnsseckey_t *key = NULL;
+ dst_key_t *newkey = NULL;
+
+ result = dst_key_fromnamedfile(keyfiles[i], directory,
+ DST_TYPE_PUBLIC |
+ DST_TYPE_PRIVATE,
+ mctx, &newkey);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot load dnskey %s: %s", keyfiles[i],
+ isc_result_totext(result));
+
+ if (!dns_name_equal(gorigin, dst_key_name(newkey)))
+ fatal("key %s not at origin\n", keyfiles[i]);
+
+ if (!dst_key_isprivate(newkey))
+ fatal("cannot sign zone with non-private dnskey %s",
+ keyfiles[i]);
+
+ /* Skip any duplicates */
+ for (key = ISC_LIST_HEAD(keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ if (dst_key_id(key->key) == dst_key_id(newkey) &&
+ dst_key_alg(key->key) == dst_key_alg(newkey))
+ break;
+ }
+
+ if (key == NULL) {
+ /* We haven't seen this key before */
+ dns_dnsseckey_create(mctx, &newkey, &key);
+ ISC_LIST_APPEND(keylist, key, link);
+ key->source = dns_keysource_user;
+ } else {
+ dst_key_free(&key->key);
+ key->key = newkey;
+ }
+
+ key->force_publish = ISC_TRUE;
+ key->force_sign = ISC_TRUE;
- key = newkeystruct(keys[i], dst_key_isprivate(keys[i]));
- ISC_LIST_APPEND(keylist, key, link);
+ if (setksk)
+ key->ksk = ISC_TRUE;
}
- dns_db_detachnode(db, &node);
- dns_db_closeversion(db, &currentversion, 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;
+report(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ putc('\n', stderr);
+}
+
+static void
+build_final_keylist() {
isc_result_t result;
+ dns_dbversion_t *ver = NULL;
+ dns_diff_t diff;
+ dns_dnsseckeylist_t matchkeys;
+ char name[DNS_NAME_FORMATSIZE];
- dns_db_currentversion(db, &currentversion);
+ /*
+ * Find keys that match this zone in the key repository.
+ */
+ ISC_LIST_INIT(matchkeys);
+ result = dns_dnssec_findmatchingkeys(gorigin, directory,
+ mctx, &matchkeys);
+ if (result == ISC_R_NOTFOUND)
+ result = ISC_R_SUCCESS;
+ check_result(result, "dns_dnssec_findmatchingkeys");
- 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_db_newversion(gdb, &ver);
+ check_result(result, "dns_db_newversion");
- dns_rdataset_init(&rdataset);
- result = dns_db_findrdataset(db, node, currentversion,
- dns_rdatatype_dnskey, 0, 0, &rdataset,
- NULL);
+ dns_diff_init(mctx, &diff);
+
+ /*
+ * Update keylist with information from from the key repository.
+ */
+ dns_dnssec_updatekeys(&keylist, &matchkeys, NULL, gorigin, keyttl,
+ &diff, ignore_kskflag, mctx, report);
+
+ dns_name_format(gorigin, name, sizeof(name));
+
+ result = dns_diff_applysilently(&diff, gdb, ver);
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;
- }
+ fatal("failed to update DNSKEY RRset at node '%s': %s",
+ name, isc_result_totext(result));
- 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, &currentversion, ISC_FALSE);
+ dns_db_closeversion(gdb, &ver, ISC_TRUE);
+
+ dns_diff_clear(&diff);
}
static void
@@ -2727,18 +2963,112 @@ warnifallksk(dns_db_t *db) {
dns_rdataset_disassociate(&rdataset);
dns_db_detachnode(db, &node);
dns_db_closeversion(db, &currentversion, ISC_FALSE);
- if (!have_non_ksk && !ignoreksk) {
+ if (!have_non_ksk && !ignore_kskflag) {
if (disable_zone_check)
- fprintf(stderr, "%s: warning: No non-KSK dnskey found. "
- "Supply non-KSK dnskey or use '-z'.\n",
+ fprintf(stderr, "%s: warning: No non-KSK DNSKEY found; "
+ "supply a ZSK or use '-z'.\n",
program);
else
- fatal("No non-KSK dnskey found. "
- "Supply non-KSK dnskey or use '-z'.");
+ fatal("No non-KSK DNSKEY found; "
+ "supply a ZSK or use '-z'.");
}
}
static void
+set_nsec3params(isc_boolean_t update_chain, isc_boolean_t set_salt,
+ isc_boolean_t set_optout, isc_boolean_t set_iter)
+{
+ isc_result_t result;
+ dns_dbversion_t *ver = NULL;
+ dns_dbnode_t *node = NULL;
+ dns_rdataset_t rdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_nsec3_t nsec3;
+ dns_fixedname_t fname;
+ dns_name_t *hashname;
+ unsigned char orig_salt[256];
+ size_t orig_saltlen;
+ dns_hash_t orig_hash;
+ isc_uint16_t orig_iter;
+
+ dns_db_currentversion(gdb, &ver);
+ dns_rdataset_init(&rdataset);
+
+ orig_saltlen = sizeof(orig_salt);
+ result = dns_db_getnsec3parameters(gdb, ver, &orig_hash, NULL,
+ &orig_iter, orig_salt,
+ &orig_saltlen);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ nsec_datatype = dns_rdatatype_nsec3;
+
+ if (!update_chain && set_salt) {
+ if (salt_length != orig_saltlen ||
+ memcmp(saltbuf, orig_salt, salt_length) != 0)
+ fatal("An NSEC3 chain exists with a different salt. "
+ "Use -u to update it.");
+ } else if (!set_salt) {
+ salt_length = orig_saltlen;
+ memcpy(saltbuf, orig_salt, orig_saltlen);
+ salt = saltbuf;
+ }
+
+ if (!update_chain && set_iter) {
+ if (nsec3iter != orig_iter)
+ fatal("An NSEC3 chain exists with different "
+ "iterations. Use -u to update it.");
+ } else if (!set_iter)
+ nsec3iter = orig_iter;
+
+ /*
+ * Find an NSEC3 record to get the current OPTOUT value.
+ * (This assumes all NSEC3 records agree.)
+ */
+
+ dns_fixedname_init(&fname);
+ hashname = dns_fixedname_name(&fname);
+ result = dns_nsec3_hashname(&fname, NULL, NULL,
+ gorigin, gorigin, dns_hash_sha1,
+ orig_iter, orig_salt, orig_saltlen);
+ check_result(result, "dns_nsec3_hashname");
+
+ result = dns_db_findnsec3node(gdb, hashname, ISC_FALSE, &node);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_nsec3,
+ 0, 0, &rdataset, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_rdataset_first(&rdataset);
+ check_result(result, "dns_rdataset_first");
+ dns_rdataset_current(&rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
+ check_result(result, "dns_rdata_tostruct");
+
+ if (!update_chain && set_optout) {
+ if (nsec3flags != nsec3.flags)
+ fatal("An NSEC3 chain exists with%s OPTOUT. "
+ "Use -u -%s to %s it.",
+ OPTOUT(nsec3.flags) ? "" : "out",
+ OPTOUT(nsec3.flags) ? "AA" : "A",
+ OPTOUT(nsec3.flags) ? "clear" : "set");
+ } else if (!set_optout)
+ nsec3flags = nsec3.flags;
+
+ dns_rdata_freestruct(&nsec3);
+
+ cleanup:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (node != NULL)
+ dns_db_detachnode(gdb, &node);
+ dns_db_closeversion(gdb, &ver, ISC_FALSE);
+}
+
+static void
writeset(const char *prefix, dns_rdatatype_t type) {
char *filename;
char namestr[DNS_NAME_FORMATSIZE];
@@ -2755,7 +3085,7 @@ writeset(const char *prefix, dns_rdatatype_t type) {
isc_buffer_t namebuf;
isc_region_t r;
isc_result_t result;
- signer_key_t *key;
+ dns_dnsseckey_t *key, *tmpkey;
unsigned char dsbuf[DNS_DS_BUFFERSIZE];
unsigned char keybuf[DST_KEY_MAXSIZE];
unsigned int filenamelen;
@@ -2767,13 +3097,13 @@ writeset(const char *prefix, dns_rdatatype_t type) {
check_result(result, "dns_name_tofilenametext");
isc_buffer_putuint8(&namebuf, 0);
filenamelen = strlen(prefix) + strlen(namestr);
- if (directory != NULL)
- filenamelen += strlen(directory) + 1;
+ if (dsdir != NULL)
+ filenamelen += strlen(dsdir) + 1;
filename = isc_mem_get(mctx, filenamelen + 1);
if (filename == NULL)
fatal("out of memory");
- if (directory != NULL)
- sprintf(filename, "%s/", directory);
+ if (dsdir != NULL)
+ sprintf(filename, "%s/", dsdir);
else
filename[0] = 0;
strcat(filename, prefix);
@@ -2781,22 +3111,6 @@ writeset(const char *prefix, dns_rdatatype_t type) {
dns_diff_init(mctx, &diff);
- for (key = ISC_LIST_HEAD(keylist);
- key != NULL;
- key = ISC_LIST_NEXT(key, link))
- if (!key->isksk) {
- have_non_ksk = ISC_TRUE;
- break;
- }
-
- for (key = ISC_LIST_HEAD(keylist);
- key != NULL;
- key = ISC_LIST_NEXT(key, link))
- if (key->isksk) {
- have_ksk = ISC_TRUE;
- break;
- }
-
if (type == dns_rdatatype_dlv) {
dns_name_t tname;
unsigned int labels;
@@ -2815,7 +3129,28 @@ writeset(const char *prefix, dns_rdatatype_t type) {
key != NULL;
key = ISC_LIST_NEXT(key, link))
{
- if (have_ksk && have_non_ksk && !key->isksk)
+ if (REVOKE(key->key))
+ continue;
+ if (isksk(key)) {
+ have_ksk = ISC_TRUE;
+ have_non_ksk = ISC_FALSE;
+ } else {
+ have_ksk = ISC_FALSE;
+ have_non_ksk = ISC_TRUE;
+ }
+ for (tmpkey = ISC_LIST_HEAD(keylist);
+ tmpkey != NULL;
+ tmpkey = ISC_LIST_NEXT(tmpkey, link)) {
+ if (dst_key_alg(key->key) != dst_key_alg(tmpkey->key))
+ continue;
+ if (REVOKE(tmpkey->key))
+ continue;
+ if (isksk(tmpkey))
+ have_ksk = ISC_TRUE;
+ else
+ have_non_ksk = ISC_TRUE;
+ }
+ if (have_ksk && have_non_ksk && !isksk(key))
continue;
dns_rdata_init(&rdata);
dns_rdata_init(&ds);
@@ -2848,7 +3183,7 @@ writeset(const char *prefix, dns_rdatatype_t type) {
} else
result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
- gorigin, zonettl,
+ gorigin, zone_soa_min_ttl,
&rdata, &tuple);
check_result(result, "dns_difftuple_create");
dns_diff_append(&diff, &tuple);
@@ -2893,6 +3228,9 @@ print_version(FILE *fp) {
fprintf(fp, "; dnssec_signzone version " VERSION "\n");
}
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(void) {
fprintf(stderr, "Usage:\n");
@@ -2903,14 +3241,18 @@ usage(void) {
fprintf(stderr, "Version: %s\n", VERSION);
fprintf(stderr, "Options: (default value in parenthesis) \n");
- fprintf(stderr, "\t-c class (IN)\n");
- fprintf(stderr, "\t-d directory\n");
- fprintf(stderr, "\t\tdirectory to find keyset files (.)\n");
+ fprintf(stderr, "\t-S:\tsmart signing: automatically finds key files\n"
+ "\t\tfor the zone and determines how they are to "
+ "be used\n");
+ fprintf(stderr, "\t-K directory:\n");
+ fprintf(stderr, "\t\tdirectory to find key files (.)\n");
+ fprintf(stderr, "\t-d directory:\n");
+ fprintf(stderr, "\t\tdirectory to find dsset-* files (.)\n");
fprintf(stderr, "\t-g:\t");
- fprintf(stderr, "generate DS records from keyset files\n");
+ fprintf(stderr, "update DS records based on child zones' "
+ "dsset-* files\n");
fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n");
- fprintf(stderr, "\t\tRRSIG start time - absolute|offset "
- "(now - 1 hour)\n");
+ fprintf(stderr, "\t\tRRSIG start time - absolute|offset (now - 1 hour)\n");
fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n");
fprintf(stderr, "\t\tRRSIG end time - absolute|from start|from now "
"(now + 30 days)\n");
@@ -2918,8 +3260,7 @@ usage(void) {
fprintf(stderr, "\t\tcycle interval - resign "
"if < interval from end ( (end-start)/4 )\n");
fprintf(stderr, "\t-j jitter:\n");
- fprintf(stderr, "\t\trandomize signature end time up to jitter "
- "seconds\n");
+ fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n");
fprintf(stderr, "\t-v debuglevel (0)\n");
fprintf(stderr, "\t-o origin:\n");
fprintf(stderr, "\t\tzone origin (name of zonefile)\n");
@@ -2936,20 +3277,33 @@ usage(void) {
fprintf(stderr, "\t\ta file containing random data\n");
fprintf(stderr, "\t-a:\t");
fprintf(stderr, "verify generated signatures\n");
+ fprintf(stderr, "\t-c class (IN)\n");
+ fprintf(stderr, "\t-E engine:\n");
+#ifdef USE_PKCS11
+ fprintf(stderr, "\t\tname of an OpenSSL engine to use "
+ "(default is \"pkcs11\")\n");
+#else
+ fprintf(stderr, "\t\tname of an OpenSSL engine to use\n");
+#endif
fprintf(stderr, "\t-p:\t");
fprintf(stderr, "use pseudorandom data (faster but less secure)\n");
fprintf(stderr, "\t-P:\t");
fprintf(stderr, "disable post-sign verification\n");
+ fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs\n");
fprintf(stderr, "\t-t:\t");
fprintf(stderr, "print statistics\n");
+ fprintf(stderr, "\t-u:\t");
+ fprintf(stderr, "update or replace an existing NSEC/NSEC3 chain\n");
+ fprintf(stderr, "\t-x:\tsign DNSKEY record with KSKs only, not ZSKs\n");
+ fprintf(stderr, "\t-z:\tsign all records with KSKs\n");
+ fprintf(stderr, "\t-C:\tgenerate a keyset file, for compatibility\n"
+ "\t\twith older versions of dnssec-signzone -g\n");
fprintf(stderr, "\t-n ncpus (number of cpus present)\n");
fprintf(stderr, "\t-k key_signing_key\n");
fprintf(stderr, "\t-l lookasidezone\n");
- fprintf(stderr, "\t-3 salt (NSEC3 salt)\n");
- fprintf(stderr, "\t-H iterations (NSEC3 iterations)\n");
- fprintf(stderr, "\t-A (NSEC3 optout)\n");
- fprintf(stderr, "\t-z:\t");
- fprintf(stderr, "ignore KSK flag in DNSKEYs");
+ fprintf(stderr, "\t-3 NSEC3 salt\n");
+ fprintf(stderr, "\t-H NSEC3 iterations (10)\n");
+ fprintf(stderr, "\t-A NSEC3 optout\n");
fprintf(stderr, "\n");
@@ -3001,10 +3355,15 @@ main(int argc, char *argv[]) {
int ndskeys = 0;
char *endp;
isc_time_t timer_start, timer_finish;
- signer_key_t *key;
+ dns_dnsseckey_t *key;
isc_result_t result;
isc_log_t *log = NULL;
isc_boolean_t pseudorandom = ISC_FALSE;
+#ifdef USE_PKCS11
+ const char *engine = "pkcs11";
+#else
+ const char *engine = NULL;
+#endif
unsigned int eflags;
isc_boolean_t free_output = ISC_FALSE;
int tempfilelen;
@@ -3012,13 +3371,15 @@ main(int argc, char *argv[]) {
isc_task_t **tasks = NULL;
isc_buffer_t b;
int len;
- unsigned int iterations = 100U;
- const unsigned char *salt = NULL;
- size_t salt_length = 0;
- unsigned char saltbuf[255];
hashlist_t hashlist;
+ isc_boolean_t smartsign = ISC_FALSE;
+ isc_boolean_t make_keyset = ISC_FALSE;
+ isc_boolean_t set_salt = ISC_FALSE;
+ isc_boolean_t set_optout = ISC_FALSE;
+ isc_boolean_t set_iter = ISC_FALSE;
-#define CMDLINE_FLAGS "3:aAc:d:e:f:FghH:i:I:j:k:l:m:n:N:o:O:pPr:s:StUv:z"
+#define CMDLINE_FLAGS \
+ "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:pPr:s:ST:tuUv:xz"
/*
* Process memory debugging argument first.
@@ -3058,7 +3419,9 @@ main(int argc, char *argv[]) {
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (ch) {
case '3':
- if (strcmp(isc_commandline_argument, "-")) {
+ set_salt = ISC_TRUE;
+ nsec_datatype = dns_rdatatype_nsec3;
+ if (strcmp(isc_commandline_argument, "-") != 0) {
isc_buffer_t target;
char *sarg;
@@ -3068,29 +3431,42 @@ main(int argc, char *argv[]) {
result = isc_hex_decodestring(sarg, &target);
check_result(result,
"isc_hex_decodestring(salt)");
- salt = saltbuf;
salt_length = isc_buffer_usedlength(&target);
- } else {
- salt = saltbuf;
- salt_length = 0;
}
- nsec_datatype = dns_rdatatype_nsec3;
break;
case 'A':
- nsec3flags |= DNS_NSEC3FLAG_OPTOUT;
+ set_optout = ISC_TRUE;
+ if (OPTOUT(nsec3flags))
+ nsec3flags &= ~DNS_NSEC3FLAG_OPTOUT;
+ else
+ nsec3flags |= DNS_NSEC3FLAG_OPTOUT;
break;
case 'a':
tryverify = ISC_TRUE;
break;
+ case 'C':
+ make_keyset = ISC_TRUE;
+ break;
+
case 'c':
classname = isc_commandline_argument;
break;
case 'd':
- directory = isc_commandline_argument;
+ dsdir = isc_commandline_argument;
+ if (strlen(dsdir) == 0U)
+ fatal("DS directory must be non-empty string");
+ result = try_dir(dsdir);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot open directory %s: %s",
+ dsdir, isc_result_totext(result));
+ break;
+
+ case 'E':
+ engine = isc_commandline_argument;
break;
case 'e':
@@ -3106,11 +3482,11 @@ main(int argc, char *argv[]) {
break;
case 'H':
- iterations = strtoul(isc_commandline_argument,
- &endp, 0);
+ set_iter = ISC_TRUE;
+ nsec3iter = strtoul(isc_commandline_argument, &endp, 0);
if (*endp != '\0')
fatal("iterations must be numeric");
- if (iterations > 0xffffU)
+ if (nsec3iter > 0xffffU)
fatal("iterations too big");
break;
@@ -3118,6 +3494,10 @@ main(int argc, char *argv[]) {
usage();
break;
+ case 'I':
+ inputformatstr = isc_commandline_argument;
+ break;
+
case 'i':
endp = NULL;
cycle = strtol(isc_commandline_argument, &endp, 0);
@@ -3126,10 +3506,6 @@ main(int argc, char *argv[]) {
"positive");
break;
- case 'I':
- inputformatstr = isc_commandline_argument;
- break;
-
case 'j':
endp = NULL;
jitter = strtol(isc_commandline_argument, &endp, 0);
@@ -3137,6 +3513,10 @@ main(int argc, char *argv[]) {
fatal("jitter must be numeric and positive");
break;
+ case 'K':
+ directory = isc_commandline_argument;
+ break;
+
case 'k':
if (ndskeys == MAXDSKEYS)
fatal("too many key-signing keys specified");
@@ -3150,14 +3530,18 @@ main(int argc, char *argv[]) {
dns_fixedname_init(&dlv_fixed);
dlv = dns_fixedname_name(&dlv_fixed);
- result = dns_name_fromtext(dlv, &b, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(dlv, &b, dns_rootname, 0,
+ NULL);
check_result(result, "dns_name_fromtext(dlv)");
break;
case 'm':
break;
+ case 'N':
+ serialformatstr = isc_commandline_argument;
+ break;
+
case 'n':
endp = NULL;
ntasks = strtol(isc_commandline_argument, &endp, 0);
@@ -3165,38 +3549,38 @@ main(int argc, char *argv[]) {
fatal("number of cpus must be numeric");
break;
- case 'N':
- serialformatstr = isc_commandline_argument;
+ case 'O':
+ outputformatstr = isc_commandline_argument;
break;
case 'o':
origin = isc_commandline_argument;
break;
- case 'O':
- outputformatstr = isc_commandline_argument;
+ case 'P':
+ disable_zone_check = ISC_TRUE;
break;
case 'p':
pseudorandom = ISC_TRUE;
break;
- case 'P':
- disable_zone_check = ISC_TRUE;
- break;
-
case 'r':
setup_entropy(mctx, isc_commandline_argument, &ectx);
break;
+ case 'S':
+ smartsign = ISC_TRUE;
+ break;
+
case 's':
startstr = isc_commandline_argument;
break;
- case 'S':
- /* This is intentionally undocumented */
- /* -S: simple output style */
- masterstyle = &dns_master_style_simple;
+ case 'T':
+ endp = NULL;
+ set_keyttl = ISC_TRUE;
+ keyttl = strtottl(isc_commandline_argument);
break;
case 't':
@@ -3207,6 +3591,10 @@ main(int argc, char *argv[]) {
unknownalg = ISC_TRUE;
break;
+ case 'u':
+ update_chain = ISC_TRUE;
+ break;
+
case 'v':
endp = NULL;
verbose = strtol(isc_commandline_argument, &endp, 0);
@@ -3214,8 +3602,12 @@ main(int argc, char *argv[]) {
fatal("verbose level must be numeric");
break;
+ case 'x':
+ keyset_kskonly = ISC_TRUE;
+ break;
+
case 'z':
- ignoreksk = ISC_TRUE;
+ ignore_kskflag = ISC_TRUE;
break;
case 'F':
@@ -3245,20 +3637,21 @@ main(int argc, char *argv[]) {
if (result != ISC_R_SUCCESS)
fatal("could not create hash context");
- result = dst_lib_init(mctx, ectx, eflags);
+ result = dst_lib_init2(mctx, ectx, engine, eflags);
if (result != ISC_R_SUCCESS)
- fatal("could not initialize dst");
+ fatal("could not initialize dst: %s",
+ isc_result_totext(result));
isc_stdtime_get(&now);
- if (startstr != NULL)
+ if (startstr != NULL) {
starttime = strtotime(startstr, now, now);
- else
+ } else
starttime = now - 3600; /* Allow for some clock skew. */
- if (endstr != NULL)
+ if (endstr != NULL) {
endtime = strtotime(endstr, now, starttime);
- else
+ } else
endtime = starttime + (30 * 24 * 60 * 60);
if (cycle == -1)
@@ -3270,6 +3663,9 @@ main(int argc, char *argv[]) {
rdclass = strtoclass(classname);
+ if (directory == NULL)
+ directory = ".";
+
setup_logging(verbose, mctx, &log);
argc -= isc_commandline_index;
@@ -3335,7 +3731,19 @@ main(int argc, char *argv[]) {
loadzone(file, origin, rdclass, &gdb);
gorigin = dns_db_origin(gdb);
gclass = dns_db_class(gdb);
- zonettl = soattl();
+ get_soa_ttls();
+
+ if (!set_keyttl)
+ keyttl = soa_ttl;
+
+ /*
+ * Check for any existing NSEC3 parameters in the zone,
+ * and use them as defaults if -u was not specified.
+ */
+ if (update_chain && !set_optout && !set_iter && !set_salt)
+ nsec_datatype = dns_rdatatype_nsec;
+ else
+ set_nsec3params(update_chain, set_salt, set_optout, set_iter);
if (IS_NSEC3) {
isc_boolean_t answer;
@@ -3356,95 +3764,42 @@ main(int argc, char *argv[]) {
ISC_LIST_INIT(keylist);
isc_rwlock_init(&keylist_lock, 0, 0);
- if (argc == 0) {
- loadzonekeys(gdb);
- } else {
- for (i = 0; i < argc; i++) {
- dst_key_t *newkey = NULL;
-
- result = dst_key_fromnamedfile(argv[i],
- DST_TYPE_PUBLIC |
- DST_TYPE_PRIVATE,
- mctx, &newkey);
- if (result != ISC_R_SUCCESS)
- fatal("cannot load dnskey %s: %s", argv[i],
- isc_result_totext(result));
-
- if (!dns_name_equal(gorigin, dst_key_name(newkey)))
- fatal("key %s not at origin\n", argv[i]);
-
- key = ISC_LIST_HEAD(keylist);
- while (key != NULL) {
- dst_key_t *dkey = key->key;
- if (dst_key_id(dkey) == dst_key_id(newkey) &&
- dst_key_alg(dkey) == dst_key_alg(newkey) &&
- dns_name_equal(dst_key_name(dkey),
- dst_key_name(newkey)))
- {
- if (!dst_key_isprivate(dkey))
- fatal("cannot sign zone with "
- "non-private dnskey %s",
- argv[i]);
- break;
- }
- key = ISC_LIST_NEXT(key, link);
- }
- if (key == NULL) {
- key = newkeystruct(newkey, ISC_TRUE);
- key->commandline = ISC_TRUE;
- ISC_LIST_APPEND(keylist, key, link);
- } else
- dst_key_free(&newkey);
- }
-
- loadzonepubkeys(gdb);
- }
-
- for (i = 0; i < ndskeys; i++) {
- dst_key_t *newkey = NULL;
-
- result = dst_key_fromnamedfile(dskeyfile[i],
- DST_TYPE_PUBLIC |
- DST_TYPE_PRIVATE,
- mctx, &newkey);
- if (result != ISC_R_SUCCESS)
- fatal("cannot load dnskey %s: %s", dskeyfile[i],
- isc_result_totext(result));
+ /*
+ * Fill keylist with:
+ * 1) Keys listed in the DNSKEY set that have
+ * private keys associated, *if* no keys were
+ * set on the command line.
+ * 2) ZSKs set on the command line
+ * 3) KSKs set on the command line
+ * 4) Any keys remaining in the DNSKEY set which
+ * do not have private keys associated and were
+ * not specified on the command line.
+ */
+ if (argc == 0 || smartsign)
+ loadzonekeys(!smartsign, ISC_FALSE);
+ loadexplicitkeys(argv, argc, ISC_FALSE);
+ loadexplicitkeys(dskeyfile, ndskeys, ISC_TRUE);
+ loadzonekeys(!smartsign, ISC_TRUE);
- if (!dns_name_equal(gorigin, dst_key_name(newkey)))
- fatal("key %s not at origin\n", dskeyfile[i]);
+ /*
+ * If we're doing smart signing, look in the key repository for
+ * key files with metadata, and merge them with the keylist
+ * we have now.
+ */
+ if (smartsign)
+ build_final_keylist();
- key = ISC_LIST_HEAD(keylist);
- while (key != NULL) {
- dst_key_t *dkey = key->key;
- if (dst_key_id(dkey) == dst_key_id(newkey) &&
- dst_key_alg(dkey) == dst_key_alg(newkey) &&
- dns_name_equal(dst_key_name(dkey),
- dst_key_name(newkey)))
- {
- /* Override key flags. */
- key->issigningkey = ISC_TRUE;
- key->isksk = ISC_TRUE;
- key->isdsk = ISC_FALSE;
- dst_key_free(&dkey);
- key->key = newkey;
- break;
- }
- key = ISC_LIST_NEXT(key, link);
- }
- if (key == NULL) {
- /* Override dnskey flags. */
- key = newkeystruct(newkey, ISC_TRUE);
- key->isksk = ISC_TRUE;
- key->isdsk = ISC_FALSE;
- ISC_LIST_APPEND(keylist, key, link);
- }
+ /* Now enumerate the key list */
+ for (key = ISC_LIST_HEAD(keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ key->index = keycount++;
}
- if (ISC_LIST_EMPTY(keylist)) {
+ if (keycount == 0) {
if (disable_zone_check)
fprintf(stderr, "%s: warning: No keys specified "
- "or found\n", program);
+ "or found\n", program);
else
fatal("No signing keys specified or found.");
nokeys = ISC_TRUE;
@@ -3454,7 +3809,7 @@ main(int argc, char *argv[]) {
unsigned int max;
result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max);
check_result(result, "dns_nsec3_maxiterations()");
- if (iterations > max)
+ if (nsec3iter > max)
fatal("NSEC3 iterations too big for weakest DNSKEY "
"strength. Maximum iterations allowed %u.", max);
}
@@ -3478,15 +3833,18 @@ main(int argc, char *argv[]) {
break;
}
+ remove_duplicates();
+
if (IS_NSEC3)
- nsec3ify(dns_hash_sha1, iterations, salt, salt_length,
+ nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length,
&hashlist);
else
nsecify();
if (!nokeys) {
- writeset("keyset-", dns_rdatatype_dnskey);
writeset("dsset-", dns_rdatatype_ds);
+ if (make_keyset)
+ writeset("keyset-", dns_rdatatype_dnskey);
if (dlv != NULL) {
writeset("dlvset-", dns_rdatatype_dlv);
}
@@ -3591,8 +3949,7 @@ main(int argc, char *argv[]) {
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));
+ dns_dnsseckey_destroy(mctx, &key);
}
isc_mem_put(mctx, tempfile, tempfilelen);
diff --git a/bin/dnssec/dnssec-signzone.docbook b/bin/dnssec/dnssec-signzone.docbook
index 87a801e7442f..51a14968a9c3 100644
--- a/bin/dnssec/dnssec-signzone.docbook
+++ b/bin/dnssec/dnssec-signzone.docbook
@@ -18,10 +18,10 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.docbook,v 1.31.44.8 2009-11-06 21:36:22 each Exp $ -->
+<!-- $Id: dnssec-signzone.docbook,v 1.44 2009-12-03 23:18:16 each Exp $ -->
<refentry id="man.dnssec-signzone">
<refentryinfo>
- <date>June 08, 2009</date>
+ <date>June 05, 2009</date>
</refentryinfo>
<refmeta>
@@ -60,10 +60,12 @@
<arg><option>-a</option></arg>
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
<arg><option>-d <replaceable class="parameter">directory</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
<arg><option>-e <replaceable class="parameter">end-time</replaceable></option></arg>
<arg><option>-f <replaceable class="parameter">output-file</replaceable></option></arg>
<arg><option>-g</option></arg>
<arg><option>-h</option></arg>
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
<arg><option>-k <replaceable class="parameter">key</replaceable></option></arg>
<arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
<arg><option>-i <replaceable class="parameter">interval</replaceable></option></arg>
@@ -75,9 +77,13 @@
<arg><option>-p</option></arg>
<arg><option>-P</option></arg>
<arg><option>-r <replaceable class="parameter">randomdev</replaceable></option></arg>
+ <arg><option>-S</option></arg>
<arg><option>-s <replaceable class="parameter">start-time</replaceable></option></arg>
+ <arg><option>-T <replaceable class="parameter">ttl</replaceable></option></arg>
<arg><option>-t</option></arg>
+ <arg><option>-u</option></arg>
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
+ <arg><option>-x</option></arg>
<arg><option>-z</option></arg>
<arg><option>-3 <replaceable class="parameter">salt</replaceable></option></arg>
<arg><option>-H <replaceable class="parameter">iterations</replaceable></option></arg>
@@ -92,10 +98,10 @@
<para><command>dnssec-signzone</command>
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
- zone. It also generates a <filename>keyset-</filename> file containing
- the key-signing keys for the zone, and if signing a zone which
- contains delegations, it can optionally generate DS records for
- the child zones from their <filename>keyset-</filename> files.
+ zone. The security status of delegations from the signed zone
+ (that is, whether the child zones are secure or not) is
+ determined by the presence or absence of a
+ <filename>keyset</filename> file for each child zone.
</para>
</refsect1>
@@ -122,31 +128,37 @@
</varlistentry>
<varlistentry>
- <term>-k <replaceable class="parameter">key</replaceable></term>
+ <term>-C</term>
<listitem>
<para>
- Treat specified key as a key signing key ignoring any
- key flags. This option may be specified multiple times.
+ Compatibility mode: Generate a
+ <filename>keyset-<replaceable>zonename</replaceable></filename>
+ file in addition to
+ <filename>dsset-<replaceable>zonename</replaceable></filename>
+ when signing a zone, for use by older versions of
+ <command>dnssec-signzone</command>.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>-l <replaceable class="parameter">domain</replaceable></term>
+ <term>-d <replaceable class="parameter">directory</replaceable></term>
<listitem>
<para>
- Generate a DLV set in addition to the key (DNSKEY) and DS sets.
- The domain is appended to the name of the records.
+ Look for <filename>dsset-</filename> or
+ <filename>keyset-</filename> files in <option>directory</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>-d <replaceable class="parameter">directory</replaceable></term>
+ <term>-E <replaceable class="parameter">engine</replaceable></term>
<listitem>
<para>
- Look for <filename>keyset</filename> files in
- <option>directory</option> as the directory
+ Uses a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
</para>
</listitem>
</varlistentry>
@@ -155,10 +167,39 @@
<term>-g</term>
<listitem>
<para>
- If the zone contains any delegations, and there are
- <filename>keyset-</filename> files for any of the child zones,
- then DS records for the child zones will be generated from the
- keys in those files. Existing DS records will be removed.
+ Generate DS records for child zones from
+ <filename>dsset-</filename> or <filename>keyset-</filename>
+ file. Existing DS records will be removed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-K <replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ Key repository: Specify a directory to search for DNSSEC keys.
+ If not specified, defaults to the current directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-k <replaceable class="parameter">key</replaceable></term>
+ <listitem>
+ <para>
+ Treat specified key as a key signing key ignoring any
+ key flags. This option may be specified multiple times.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-l <replaceable class="parameter">domain</replaceable></term>
+ <listitem>
+ <para>
+ Generate a DLV set in addition to the key (DNSKEY) and DS sets.
+ The domain is appended to the name of the records.
</para>
</listitem>
</varlistentry>
@@ -190,6 +231,8 @@
the start time. A time relative to the current time is
indicated with now+N. If no <option>end-time</option> is
specified, 30 days from the start time is used as a default.
+ <option>end-time</option> must be later than
+ <option>start-time</option>.
</para>
</listitem>
</varlistentry>
@@ -396,6 +439,89 @@
</varlistentry>
<varlistentry>
+ <term>-S</term>
+ <listitem>
+ <para>
+ Smart signing: Instructs <command>dnssec-signzone</command> to
+ search the key repository for keys that match the zone being
+ signed, and to include them in the zone if appropriate.
+ </para>
+ <para>
+ When a key is found, its timing metadata is examined to
+ determine how it should be used, according to the following
+ rules. Each successive rule takes priority over the prior
+ ones:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <listitem>
+ <para>
+ If no timing metadata has been set for the key, the key is
+ published in the zone and used to sign the zone.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <listitem>
+ <para>
+ If the key's publication date is set and is in the past, the
+ key is published in the zone.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <listitem>
+ <para>
+ If the key's activation date is set and in the past, the
+ key is published (regardless of publication date) and
+ used to sign the zone.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <listitem>
+ <para>
+ If the key's revocation date is set and in the past, and the
+ key is published, then the key is revoked, and the revoked key
+ is used to sign the zone.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <listitem>
+ <para>
+ If either of the key's unpublication or deletion dates are set
+ and in the past, the key is NOT published or used to sign the
+ zone, regardless of any other metadata.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-T <replaceable class="parameter">ttl</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the TTL to be used for new DNSKEY records imported
+ into the zone from the key repository. If not specified,
+ the default is the minimum TTL value from the zone's SOA
+ record. This option is ignored when signing without
+ <option>-S</option>, since DNSKEY records are not imported
+ from the key repository in that case. It is also ignored if
+ there are any pre-existing DNSKEY records at the zone apex,
+ in which case new records' TTL values will be set to match
+ them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-t</term>
<listitem>
<para>
@@ -405,6 +531,20 @@
</varlistentry>
<varlistentry>
+ <term>-u</term>
+ <listitem>
+ <para>
+ Update NSEC/NSEC3 chain when re-signing a previously signed
+ zone. With this option, a zone signed with NSEC can be
+ switched to NSEC3, or a zone signed with NSEC3 can
+ be switch to NSEC or to NSEC3 with different parameters.
+ Without this option, <command>dnssec-signzone</command> will
+ retain the existing chain when re-signing.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-v <replaceable class="parameter">level</replaceable></term>
<listitem>
<para>
@@ -414,10 +554,26 @@
</varlistentry>
<varlistentry>
+ <term>-x</term>
+ <listitem>
+ <para>
+ Only sign the DNSKEY RRset with key-signing keys, and omit
+ signatures from zone-signing keys. (This is similar to the
+ <command>dnssec-dnskey-kskonly yes;</command> zone option in
+ <command>named</command>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-z</term>
<listitem>
<para>
- Ignore KSK flag on key when determining what to sign.
+ Ignore KSK flag on key when determining what to sign. This
+ causes KSK-flagged keys to sign all records, not just the
+ DNSKEY RRset. (This is similar to the
+ <command>update-check-ksk no;</command> zone option in
+ <command>named</command>.)
</para>
</listitem>
</varlistentry>
@@ -426,7 +582,7 @@
<term>-3 <replaceable class="parameter">salt</replaceable></term>
<listitem>
<para>
- Generate a NSEC3 chain with the given hex encoded salt.
+ Generate an NSEC3 chain with the given hex encoded salt.
A dash (<replaceable class="parameter">salt</replaceable>) can
be used to indicate that no salt is to be used when generating the NSEC3 chain.
</para>
@@ -437,8 +593,8 @@
<term>-H <replaceable class="parameter">iterations</replaceable></term>
<listitem>
<para>
- When generating a NSEC3 chain use this many interations. The
- default is 100.
+ When generating an NSEC3 chain, use this many interations. The
+ default is 10.
</para>
</listitem>
</varlistentry>
@@ -447,10 +603,16 @@
<term>-A</term>
<listitem>
<para>
- When generating a NSEC3 chain set the OPTOUT flag on all
+ When generating an NSEC3 chain set the OPTOUT flag on all
NSEC3 records and do not generate NSEC3 records for insecure
delegations.
</para>
+ <para>
+ Using this option twice (i.e., <option>-AA</option>)
+ turns the OPTOUT flag off for all records. This is useful
+ when using the <option>-u</option> option to modify an NSEC3
+ chain which previously had OPTOUT set.
+ </para>
</listitem>
</varlistentry>
@@ -484,10 +646,11 @@
<para>
The following command signs the <userinput>example.com</userinput>
zone with the DSA key generated by <command>dnssec-keygen</command>
- (Kexample.com.+003+17247). The zone's keys must be in the master
- file (<filename>db.example.com</filename>). This invocation looks
- for <filename>keyset</filename> files, in the current directory,
- so that DS records can be generated from them (<command>-g</command>).
+ (Kexample.com.+003+17247). Because the <command>-S</command> option
+ is not being used, the zone's keys must be in the master file
+ (<filename>db.example.com</filename>). This invocation looks
+ for <filename>dsset</filename> files, in the current directory,
+ so that DS records can be imported from them (<command>-g</command>).
</para>
<programlisting>% dnssec-signzone -g -o example.com db.example.com \
Kexample.com.+003+17247
@@ -510,33 +673,6 @@ db.example.com.signed
</refsect1>
<refsect1>
- <title>KNOWN BUGS</title>
- <para>
- <command>dnssec-signzone</command> was designed so that it could
- sign a zone partially, using only a subset of the DNSSEC keys
- needed to produce a fully-signed zone. This permits a zone
- administrator, for example, to sign a zone with one key on one
- machine, move the resulting partially-signed zone to a second
- machine, and sign it again with a second key.
- </para>
- <para>
- An unfortunate side-effect of this flexibility is that
- <command>dnssec-signzone</command> does not check to make sure
- it's signing a zone with any valid keys at all. An attempt to
- sign a zone without any keys will appear to succeed, producing
- a "signed" zone with no signatures. There is no warning issued
- when a zone is not fully signed.
- </para>
-
- <para>
- This will be corrected in a future release. In the meantime, ISC
- recommends examining the output of <command>dnssec-signzone</command>
- to confirm that the zone is properly signed by all keys before
- using it.
- </para>
- </refsect1>
-
- <refsect1>
<title>SEE ALSO</title>
<para><citerefentry>
<refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
diff --git a/bin/dnssec/dnssec-signzone.html b/bin/dnssec/dnssec-signzone.html
index 1d4ecffc85b4..28e7158e6e7c 100644
--- a/bin/dnssec/dnssec-signzone.html
+++ b/bin/dnssec/dnssec-signzone.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.html,v 1.33.44.8 2009-11-07 01:56:11 tbox Exp $ -->
+<!-- $Id: dnssec-signzone.html,v 1.45 2009-12-04 01:13:44 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,21 +29,21 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-P</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-t</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] [<code class="option">-3 <em class="replaceable"><code>salt</code></em></code>] [<code class="option">-H <em class="replaceable"><code>iterations</code></em></code>] [<code class="option">-A</code>] {zonefile} [key...]</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-P</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-S</code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-T <em class="replaceable"><code>ttl</code></em></code>] [<code class="option">-t</code>] [<code class="option">-u</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-x</code>] [<code class="option">-z</code>] [<code class="option">-3 <em class="replaceable"><code>salt</code></em></code>] [<code class="option">-H <em class="replaceable"><code>iterations</code></em></code>] [<code class="option">-A</code>] {zonefile} [key...]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543558"></a><h2>DESCRIPTION</h2>
+<a name="id2543596"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-signzone</strong></span>
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
- zone. It also generates a <code class="filename">keyset-</code> file containing
- the key-signing keys for the zone, and if signing a zone which
- contains delegations, it can optionally generate DS records for
- the child zones from their <code class="filename">keyset-</code> files.
+ zone. The security status of delegations from the signed zone
+ (that is, whether the child zones are secure or not) is
+ determined by the presence or absence of a
+ <code class="filename">keyset</code> file for each child zone.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543576"></a><h2>OPTIONS</h2>
+<a name="id2543611"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd><p>
@@ -53,6 +53,38 @@
<dd><p>
Specifies the DNS class of the zone.
</p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: Generate a
+ <code class="filename">keyset-<em class="replaceable"><code>zonename</code></em></code>
+ file in addition to
+ <code class="filename">dsset-<em class="replaceable"><code>zonename</code></em></code>
+ when signing a zone, for use by older versions of
+ <span><strong class="command">dnssec-signzone</strong></span>.
+ </p></dd>
+<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Look for <code class="filename">dsset-</code> or
+ <code class="filename">keyset-</code> files in <code class="option">directory</code>.
+ </p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Uses a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </p></dd>
+<dt><span class="term">-g</span></dt>
+<dd><p>
+ Generate DS records for child zones from
+ <code class="filename">dsset-</code> or <code class="filename">keyset-</code>
+ file. Existing DS records will be removed.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Key repository: Specify a directory to search for DNSSEC keys.
+ If not specified, defaults to the current directory.
+ </p></dd>
<dt><span class="term">-k <em class="replaceable"><code>key</code></em></span></dt>
<dd><p>
Treat specified key as a key signing key ignoring any
@@ -63,18 +95,6 @@
Generate a DLV set in addition to the key (DNSKEY) and DS sets.
The domain is appended to the name of the records.
</p></dd>
-<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
-<dd><p>
- Look for <code class="filename">keyset</code> files in
- <code class="option">directory</code> as the directory
- </p></dd>
-<dt><span class="term">-g</span></dt>
-<dd><p>
- If the zone contains any delegations, and there are
- <code class="filename">keyset-</code> files for any of the child zones,
- then DS records for the child zones will be generated from the
- keys in those files. Existing DS records will be removed.
- </p></dd>
<dt><span class="term">-s <em class="replaceable"><code>start-time</code></em></span></dt>
<dd><p>
Specify the date and time when the generated RRSIG records
@@ -95,6 +115,8 @@
the start time. A time relative to the current time is
indicated with now+N. If no <code class="option">end-time</code> is
specified, 30 days from the start time is used as a default.
+ <code class="option">end-time</code> must be later than
+ <code class="option">start-time</code>.
</p></dd>
<dt><span class="term">-f <em class="replaceable"><code>output-file</code></em></span></dt>
<dd><p>
@@ -229,35 +251,119 @@
<code class="filename">keyboard</code> indicates that keyboard
input should be used.
</p></dd>
+<dt><span class="term">-S</span></dt>
+<dd>
+<p>
+ Smart signing: Instructs <span><strong class="command">dnssec-signzone</strong></span> to
+ search the key repository for keys that match the zone being
+ signed, and to include them in the zone if appropriate.
+ </p>
+<p>
+ When a key is found, its timing metadata is examined to
+ determine how it should be used, according to the following
+ rules. Each successive rule takes priority over the prior
+ ones:
+ </p>
+<div class="variablelist"><dl>
+<dt></dt>
+<dd><p>
+ If no timing metadata has been set for the key, the key is
+ published in the zone and used to sign the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If the key's publication date is set and is in the past, the
+ key is published in the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If the key's activation date is set and in the past, the
+ key is published (regardless of publication date) and
+ used to sign the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If the key's revocation date is set and in the past, and the
+ key is published, then the key is revoked, and the revoked key
+ is used to sign the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If either of the key's unpublication or deletion dates are set
+ and in the past, the key is NOT published or used to sign the
+ zone, regardless of any other metadata.
+ </p></dd>
+</dl></div>
+</dd>
+<dt><span class="term">-T <em class="replaceable"><code>ttl</code></em></span></dt>
+<dd><p>
+ Specifies the TTL to be used for new DNSKEY records imported
+ into the zone from the key repository. If not specified,
+ the default is the minimum TTL value from the zone's SOA
+ record. This option is ignored when signing without
+ <code class="option">-S</code>, since DNSKEY records are not imported
+ from the key repository in that case. It is also ignored if
+ there are any pre-existing DNSKEY records at the zone apex,
+ in which case new records' TTL values will be set to match
+ them.
+ </p></dd>
<dt><span class="term">-t</span></dt>
<dd><p>
Print statistics at completion.
</p></dd>
+<dt><span class="term">-u</span></dt>
+<dd><p>
+ Update NSEC/NSEC3 chain when re-signing a previously signed
+ zone. With this option, a zone signed with NSEC can be
+ switched to NSEC3, or a zone signed with NSEC3 can
+ be switch to NSEC or to NSEC3 with different parameters.
+ Without this option, <span><strong class="command">dnssec-signzone</strong></span> will
+ retain the existing chain when re-signing.
+ </p></dd>
<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
<dd><p>
Sets the debugging level.
</p></dd>
+<dt><span class="term">-x</span></dt>
+<dd><p>
+ Only sign the DNSKEY RRset with key-signing keys, and omit
+ signatures from zone-signing keys. (This is similar to the
+ <span><strong class="command">dnssec-dnskey-kskonly yes;</strong></span> zone option in
+ <span><strong class="command">named</strong></span>.)
+ </p></dd>
<dt><span class="term">-z</span></dt>
<dd><p>
- Ignore KSK flag on key when determining what to sign.
+ Ignore KSK flag on key when determining what to sign. This
+ causes KSK-flagged keys to sign all records, not just the
+ DNSKEY RRset. (This is similar to the
+ <span><strong class="command">update-check-ksk no;</strong></span> zone option in
+ <span><strong class="command">named</strong></span>.)
</p></dd>
<dt><span class="term">-3 <em class="replaceable"><code>salt</code></em></span></dt>
<dd><p>
- Generate a NSEC3 chain with the given hex encoded salt.
+ Generate an NSEC3 chain with the given hex encoded salt.
A dash (<em class="replaceable"><code>salt</code></em>) can
be used to indicate that no salt is to be used when generating the NSEC3 chain.
</p></dd>
<dt><span class="term">-H <em class="replaceable"><code>iterations</code></em></span></dt>
<dd><p>
- When generating a NSEC3 chain use this many interations. The
- default is 100.
+ When generating an NSEC3 chain, use this many interations. The
+ default is 10.
</p></dd>
<dt><span class="term">-A</span></dt>
-<dd><p>
- When generating a NSEC3 chain set the OPTOUT flag on all
+<dd>
+<p>
+ When generating an NSEC3 chain set the OPTOUT flag on all
NSEC3 records and do not generate NSEC3 records for insecure
delegations.
- </p></dd>
+ </p>
+<p>
+ Using this option twice (i.e., <code class="option">-AA</code>)
+ turns the OPTOUT flag off for all records. This is useful
+ when using the <code class="option">-u</code> option to modify an NSEC3
+ chain which previously had OPTOUT set.
+ </p>
+</dd>
<dt><span class="term">zonefile</span></dt>
<dd><p>
The file containing the zone to be signed.
@@ -273,14 +379,15 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544503"></a><h2>EXAMPLE</h2>
+<a name="id2544896"></a><h2>EXAMPLE</h2>
<p>
The following command signs the <strong class="userinput"><code>example.com</code></strong>
zone with the DSA key generated by <span><strong class="command">dnssec-keygen</strong></span>
- (Kexample.com.+003+17247). The zone's keys must be in the master
- file (<code class="filename">db.example.com</code>). This invocation looks
- for <code class="filename">keyset</code> files, in the current directory,
- so that DS records can be generated from them (<span><strong class="command">-g</strong></span>).
+ (Kexample.com.+003+17247). Because the <span><strong class="command">-S</strong></span> option
+ is not being used, the zone's keys must be in the master file
+ (<code class="filename">db.example.com</code>). This invocation looks
+ for <code class="filename">dsset</code> files, in the current directory,
+ so that DS records can be imported from them (<span><strong class="command">-g</strong></span>).
</p>
<pre class="programlisting">% dnssec-signzone -g -o example.com db.example.com \
Kexample.com.+003+17247
@@ -302,39 +409,14 @@ db.example.com.signed
%</pre>
</div>
<div class="refsect1" lang="en">
-<a name="id2544554"></a><h2>KNOWN BUGS</h2>
-<p>
- <span><strong class="command">dnssec-signzone</strong></span> was designed so that it could
- sign a zone partially, using only a subset of the DNSSEC keys
- needed to produce a fully-signed zone. This permits a zone
- administrator, for example, to sign a zone with one key on one
- machine, move the resulting partially-signed zone to a second
- machine, and sign it again with a second key.
- </p>
-<p>
- An unfortunate side-effect of this flexibility is that
- <span><strong class="command">dnssec-signzone</strong></span> does not check to make sure
- it's signing a zone with any valid keys at all. An attempt to
- sign a zone without any keys will appear to succeed, producing
- a "signed" zone with no signatures. There is no warning issued
- when a zone is not fully signed.
- </p>
-<p>
- This will be corrected in a future release. In the meantime, ISC
- recommends examining the output of <span><strong class="command">dnssec-signzone</strong></span>
- to confirm that the zone is properly signed by all keys before
- using it.
- </p>
-</div>
-<div class="refsect1" lang="en">
-<a name="id2544716"></a><h2>SEE ALSO</h2>
+<a name="id2545019"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 4033</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544741"></a><h2>AUTHOR</h2>
+<a name="id2545044"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c
index 81120e34c49c..da6b0b2a789e 100644
--- a/bin/dnssec/dnssectool.c
+++ b/bin/dnssec/dnssectool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.c,v 1.45.334.5 2009-06-22 05:05:00 marka Exp $ */
+/* $Id: dnssectool.c,v 1.60 2010-01-19 23:48:56 tbox Exp $ */
/*! \file */
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <isc/buffer.h>
+#include <isc/dir.h>
#include <isc/entropy.h>
#include <isc/list.h>
#include <isc/mem.h>
@@ -36,6 +37,8 @@
#include <isc/util.h>
#include <isc/print.h>
+#include <dns/dnssec.h>
+#include <dns/keyvalues.h>
#include <dns/log.h>
#include <dns/name.h>
#include <dns/rdatastruct.h>
@@ -111,39 +114,16 @@ type_format(const dns_rdatatype_t type, char *cp, unsigned int size) {
}
void
-alg_format(const dns_secalg_t alg, char *cp, unsigned int size) {
- isc_buffer_t b;
- isc_region_t r;
- isc_result_t result;
-
- isc_buffer_init(&b, cp, size - 1);
- result = dns_secalg_totext(alg, &b);
- check_result(result, "dns_secalg_totext()");
- isc_buffer_usedregion(&b, &r);
- r.base[r.length] = 0;
-}
-
-void
sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size) {
char namestr[DNS_NAME_FORMATSIZE];
char algstr[DNS_NAME_FORMATSIZE];
dns_name_format(&sig->signer, namestr, sizeof(namestr));
- alg_format(sig->algorithm, algstr, sizeof(algstr));
+ dns_secalg_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;
@@ -265,32 +245,92 @@ cleanup_entropy(isc_entropy_t **ectx) {
isc_entropy_detach(ectx);
}
+static isc_stdtime_t
+time_units(isc_stdtime_t offset, char *suffix, const char *str) {
+ switch (suffix[0]) {
+ case 'Y': case 'y':
+ return (offset * (365 * 24 * 3600));
+ case 'M': case 'm':
+ switch (suffix[1]) {
+ case 'O': case 'o':
+ return (offset * (30 * 24 * 3600));
+ case 'I': case 'i':
+ return (offset * 60);
+ case '\0':
+ fatal("'%s' ambiguous: use 'mi' for minutes "
+ "or 'mo' for months", str);
+ default:
+ fatal("time value %s is invalid", str);
+ }
+ /* NOTREACHED */
+ break;
+ case 'W': case 'w':
+ return (offset * (7 * 24 * 3600));
+ case 'D': case 'd':
+ return (offset * (24 * 3600));
+ case 'H': case 'h':
+ return (offset * 3600);
+ case 'S': case 's': case '\0':
+ return (offset);
+ default:
+ fatal("time value %s is invalid", str);
+ }
+ /* NOTREACHED */
+ return(0); /* silence compiler warning */
+}
+
+dns_ttl_t
+strtottl(const char *str) {
+ const char *orig = str;
+ dns_ttl_t ttl;
+ char *endp;
+
+ ttl = strtol(str, &endp, 0);
+ if (ttl == 0 && endp == str)
+ fatal("TTL must be numeric");
+ ttl = time_units(ttl, endp, orig);
+ return (ttl);
+}
+
isc_stdtime_t
strtotime(const char *str, isc_int64_t now, isc_int64_t base) {
isc_int64_t val, offset;
isc_result_t result;
+ const char *orig = str;
char *endp;
- if (str[0] == '+') {
+ if ((str[0] == '0' || str[0] == '-') && str[1] == '\0')
+ return ((isc_stdtime_t) 0);
+
+ if (strncmp(str, "now", 3) == 0) {
+ base = now;
+ str += 3;
+ }
+
+ if (str[0] == '\0')
+ return ((isc_stdtime_t) base);
+ else if (str[0] == '+') {
offset = strtol(str + 1, &endp, 0);
- if (*endp != '\0')
- fatal("time value %s is invalid", str);
+ offset = time_units((isc_stdtime_t) offset, endp, orig);
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 (str[0] == '-') {
+ offset = strtol(str + 1, &endp, 0);
+ offset = time_units((isc_stdtime_t) offset, endp, orig);
+ val = base - 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);
+ fatal("time value %s is invalid: %s", orig,
+ isc_result_totext(result));
+ } else if (strlen(str) > 14U) {
+ fatal("time value %s is invalid", orig);
} else {
result = dns_time64_fromtext(str, &val);
if (result != ISC_R_SUCCESS)
- fatal("time value %s is invalid", str);
+ fatal("time value %s is invalid: %s", orig,
+ isc_result_totext(result));
}
return ((isc_stdtime_t) val);
@@ -311,3 +351,114 @@ strtoclass(const char *str) {
fatal("unknown class %s", str);
return (rdclass);
}
+
+isc_result_t
+try_dir(const char *dirname) {
+ isc_result_t result;
+ isc_dir_t d;
+
+ isc_dir_init(&d);
+ result = isc_dir_open(&d, dirname);
+ if (result == ISC_R_SUCCESS) {
+ isc_dir_close(&d);
+ }
+ return (result);
+}
+
+/*
+ * Check private key version compatibility.
+ */
+void
+check_keyversion(dst_key_t *key, char *keystr) {
+ int major, minor;
+ dst_key_getprivateformat(key, &major, &minor);
+ INSIST(major <= DST_MAJOR_VERSION); /* invalid private key */
+
+ if (major < DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
+ fatal("Key %s has incompatible format version %d.%d, "
+ "use -f to force upgrade to new version.",
+ keystr, major, minor);
+ if (minor > DST_MINOR_VERSION)
+ fatal("Key %s has incompatible format version %d.%d, "
+ "use -f to force downgrade to current version.",
+ keystr, major, minor);
+}
+
+void
+set_keyversion(dst_key_t *key) {
+ int major, minor;
+ dst_key_getprivateformat(key, &major, &minor);
+ INSIST(major <= DST_MAJOR_VERSION);
+
+ if (major != DST_MAJOR_VERSION || minor != DST_MINOR_VERSION)
+ dst_key_setprivateformat(key, DST_MAJOR_VERSION,
+ DST_MINOR_VERSION);
+
+ /*
+ * If the key is from a version older than 1.3, set
+ * set the creation date
+ */
+ if (major < 1 || (major == 1 && minor <= 2)) {
+ isc_stdtime_t now;
+ isc_stdtime_get(&now);
+ dst_key_settime(key, DST_TIME_CREATED, now);
+ }
+}
+
+isc_boolean_t
+key_collision(isc_uint16_t id, dns_name_t *name, const char *dir,
+ dns_secalg_t alg, isc_mem_t *mctx, isc_boolean_t *exact)
+{
+ isc_result_t result;
+ isc_boolean_t conflict = ISC_FALSE;
+ dns_dnsseckeylist_t matchkeys;
+ dns_dnsseckey_t *key = NULL;
+ isc_uint16_t oldid, diff;
+ isc_uint16_t bits = DNS_KEYFLAG_REVOKE; /* flag bits to look for */
+
+ if (exact != NULL)
+ *exact = ISC_FALSE;
+
+ ISC_LIST_INIT(matchkeys);
+ result = dns_dnssec_findmatchingkeys(name, dir, mctx, &matchkeys);
+ if (result == ISC_R_NOTFOUND)
+ return (ISC_FALSE);
+
+ while (!ISC_LIST_EMPTY(matchkeys) && !conflict) {
+ key = ISC_LIST_HEAD(matchkeys);
+ if (dst_key_alg(key->key) != alg)
+ goto next;
+
+ oldid = dst_key_id(key->key);
+ diff = (oldid > id) ? (oldid - id) : (id - oldid);
+ if ((diff & ~bits) == 0) {
+ conflict = ISC_TRUE;
+ if (diff != 0) {
+ if (verbose > 1)
+ fprintf(stderr, "Key ID %d could "
+ "collide with %d\n",
+ id, oldid);
+ } else {
+ if (exact != NULL)
+ *exact = ISC_TRUE;
+ if (verbose > 1)
+ fprintf(stderr, "Key ID %d exists\n",
+ id);
+ }
+ }
+
+ next:
+ ISC_LIST_UNLINK(matchkeys, key, link);
+ dns_dnsseckey_destroy(mctx, &key);
+ }
+
+ /* Finish freeing the list */
+ while (!ISC_LIST_EMPTY(matchkeys)) {
+ key = ISC_LIST_HEAD(matchkeys);
+ ISC_LIST_UNLINK(matchkeys, key, link);
+ dns_dnsseckey_destroy(mctx, &key);
+ }
+
+ return (conflict);
+}
+
diff --git a/bin/dnssec/dnssectool.h b/bin/dnssec/dnssectool.h
index 8cc133df42f4..b52bc135ea0e 100644
--- a/bin/dnssec/dnssectool.h
+++ b/bin/dnssec/dnssectool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssectool.h,v 1.22.48.2 2009-09-04 23:46:58 tbox Exp $ */
+/* $Id: dnssectool.h,v 1.31 2010-01-19 23:48:56 tbox Exp $ */
#ifndef DNSSECTOOL_H
#define DNSSECTOOL_H 1
@@ -27,8 +27,9 @@
typedef void (fatalcallback_t)(void);
-void
-fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
+ISC_PLATFORM_NORETURN_PRE void
+fatal(const char *format, ...)
+ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
void
setfatalcallback(fatalcallback_t *callback);
@@ -44,16 +45,8 @@ type_format(const dns_rdatatype_t type, char *cp, unsigned int size);
#define TYPE_FORMATSIZE 20
void
-alg_format(const dns_secalg_t alg, char *cp, unsigned int size);
-#define ALG_FORMATSIZE 20
-
-void
sig_format(dns_rdata_rrsig_t *sig, char *cp, unsigned int size);
-#define SIG_FORMATSIZE (DNS_NAME_FORMATSIZE + ALG_FORMATSIZE + sizeof("65535"))
-
-void
-key_format(const dst_key_t *key, char *cp, unsigned int size);
-#define KEY_FORMATSIZE (DNS_NAME_FORMATSIZE + ALG_FORMATSIZE + sizeof("65535"))
+#define SIG_FORMATSIZE (DNS_NAME_FORMATSIZE + DNS_SECALG_FORMATSIZE + sizeof("65535"))
void
setup_logging(int verbose, isc_mem_t *mctx, isc_log_t **logp);
@@ -67,10 +60,24 @@ setup_entropy(isc_mem_t *mctx, const char *randomfile, isc_entropy_t **ectx);
void
cleanup_entropy(isc_entropy_t **ectx);
+dns_ttl_t strtottl(const char *str);
+
isc_stdtime_t
strtotime(const char *str, isc_int64_t now, isc_int64_t base);
dns_rdataclass_t
strtoclass(const char *str);
+isc_result_t
+try_dir(const char *dirname);
+
+void
+check_keyversion(dst_key_t *key, char *keystr);
+
+void
+set_keyversion(dst_key_t *key);
+
+isc_boolean_t
+key_collision(isc_uint16_t id, dns_name_t *name, const char *dir,
+ dns_secalg_t alg, isc_mem_t *mctx, isc_boolean_t *exact);
#endif /* DNSSEC_DNSSECTOOL_H */
diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in
index ee7613435759..a3dbb3802dc9 100644
--- a/bin/named/Makefile.in
+++ b/bin/named/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.101 2008-09-23 17:25:47 jinmei Exp $
+# $Id: Makefile.in,v 1.114 2010-12-22 09:00:40 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -43,9 +43,9 @@ DLZDRIVER_LIBS = @DLZ_DRIVER_LIBS@
CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \
${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \
${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \
- ${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES}
+ ${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES} @DST_OPENSSL_INC@
-CDEFINES = @USE_DLZ@
+CDEFINES = @USE_DLZ@ @USE_PKCS11@ @USE_OPENSSL@
CWARNINGS =
@@ -53,6 +53,7 @@ DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCLIBS = ../../lib/isccc/libisccc.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
LWRESLIBS = ../../lib/lwres/liblwres.@A@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
@@ -70,6 +71,10 @@ LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \
${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} \
${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@
+NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \
+ ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCNOSYMLIBS} \
+ ${DLZDRIVER_LIBS} ${DBDRIVER_LIBS} @LIBS@
+
SUBDIRS = unix
TARGETS = named@EXEEXT@ lwresd@EXEEXT@
@@ -86,10 +91,12 @@ OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \
UOBJS = unix/os.@O@
+SYMOBJS = symtbl.@O@
+
SRCS = builtin.c client.c config.c control.c \
controlconf.c interfacemgr.c \
listenlist.c log.c logconf.c main.c notify.c \
- query.c server.c sortlist.c statschannel.c \
+ query.c server.c sortlist.c statschannel.c symtbl.c symtbl-empty.c \
tkeyconf.c tsigconf.c update.c xfrout.c \
zoneconf.c \
lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \
@@ -111,15 +118,20 @@ main.@O@: main.c
-DNS_LOCALSTATEDIR=\"${localstatedir}\" \
-DNS_SYSCONFDIR=\"${sysconfdir}\" -c ${srcdir}/main.c
-config.@O@: config.c
+bind.keys.h: ${top_srcdir}/bind.keys ${srcdir}/bindkeys.pl
+ ${PERL} ${srcdir}/bindkeys.pl < ${top_srcdir}/bind.keys > $@
+
+config.@O@: config.c bind.keys.h
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
-DVERSION=\"${VERSION}\" \
-DNS_LOCALSTATEDIR=\"${localstatedir}\" \
+ -DNS_SYSCONFDIR=\"${sysconfdir}\" \
-c ${srcdir}/config.c
named@EXEEXT@: ${OBJS} ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
- ${OBJS} ${UOBJS} ${LIBS}
+ export MAKE_SYMTABLE="yes"; \
+ export BASEOBJS="${OBJS} ${UOBJS}"; \
+ ${FINALBUILDCMD}
lwresd@EXEEXT@: named@EXEEXT@
rm -f lwresd@EXEEXT@
@@ -133,7 +145,10 @@ docclean manclean maintainer-clean::
clean distclean maintainer-clean::
rm -f ${TARGETS} ${OBJS}
-bind9.xsl.h: bind9.xsl convertxsl.pl
+maintainer-clean::
+ rm -f bind.keys.h
+
+bind9.xsl.h: bind9.xsl ${srcdir}/convertxsl.pl
${PERL} ${srcdir}/convertxsl.pl < ${srcdir}/bind9.xsl > bind9.xsl.h
depend: bind9.xsl.h
diff --git a/bin/named/bind.keys.h b/bin/named/bind.keys.h
new file mode 100644
index 000000000000..0177214159e7
--- /dev/null
+++ b/bin/named/bind.keys.h
@@ -0,0 +1,99 @@
+/*
+ * Generated by bindkeys.pl 1.7 2011-01-04 23:47:13 tbox Exp
+ * From bind.keys 1.7 2011-01-03 23:45:07 each Exp
+ */
+#define TRUSTED_KEYS "\
+# The bind.keys file is used to override the built-in DNSSEC trust anchors\n\
+# which are included as part of BIND 9. As of the current release, the only\n\
+# trust anchors it contains are those for the DNS root zone (\".\"), and for\n\
+# the ISC DNSSEC Lookaside Validation zone (\"dlv.isc.org\"). Trust anchors\n\
+# for any other zones MUST be configured elsewhere; if they are configured\n\
+# here, they will not be recognized or used by named.\n\
+#\n\
+# The built-in trust anchors are provided for convenience of configuration.\n\
+# They are not activated within named.conf unless specifically switched on.\n\
+# To use the built-in root key, set \"dnssec-validation auto;\" in\n\
+# named.conf options. To use the built-in DLV key, set\n\
+# \"dnssec-lookaside auto;\". Without these options being set,\n\
+# the keys in this file are ignored.\n\
+#\n\
+# This file is NOT expected to be user-configured.\n\
+#\n\
+# These keys are current as of January 2011. If any key fails to\n\
+# initialize correctly, it may have expired. In that event you should\n\
+# replace this file with a current version. The latest version of\n\
+# bind.keys can always be obtained from ISC at https://www.isc.org/bind-keys.\n\
+\n\
+trusted-keys {\n\
+ # ISC DLV: See https://www.isc.org/solutions/dlv for details.\n\
+ # NOTE: This key is activated by setting \"dnssec-lookaside auto;\"\n\
+ # in named.conf.\n\
+ dlv.isc.org. 257 3 5 \"BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2\n\
+ brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+\n\
+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5\n\
+ ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk\n\
+ Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM\n\
+ QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt\n\
+ TDN0YUuWrBNh\";\n\
+\n\
+ # ROOT KEY: See https://data.iana.org/root-anchors/root-anchors.xml\n\
+ # for current trust anchor information.\n\
+ # NOTE: This key is activated by setting \"dnssec-validation auto;\"\n\
+ # in named.conf.\n\
+ . 257 3 8 \"AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF\n\
+ FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX\n\
+ bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD\n\
+ X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz\n\
+ W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS\n\
+ Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq\n\
+ QxA+Uk1ihz0=\";\n\
+};\n\
+"
+
+#define MANAGED_KEYS "\
+# The bind.keys file is used to override the built-in DNSSEC trust anchors\n\
+# which are included as part of BIND 9. As of the current release, the only\n\
+# trust anchors it contains are those for the DNS root zone (\".\"), and for\n\
+# the ISC DNSSEC Lookaside Validation zone (\"dlv.isc.org\"). Trust anchors\n\
+# for any other zones MUST be configured elsewhere; if they are configured\n\
+# here, they will not be recognized or used by named.\n\
+#\n\
+# The built-in trust anchors are provided for convenience of configuration.\n\
+# They are not activated within named.conf unless specifically switched on.\n\
+# To use the built-in root key, set \"dnssec-validation auto;\" in\n\
+# named.conf options. To use the built-in DLV key, set\n\
+# \"dnssec-lookaside auto;\". Without these options being set,\n\
+# the keys in this file are ignored.\n\
+#\n\
+# This file is NOT expected to be user-configured.\n\
+#\n\
+# These keys are current as of January 2011. If any key fails to\n\
+# initialize correctly, it may have expired. In that event you should\n\
+# replace this file with a current version. The latest version of\n\
+# bind.keys can always be obtained from ISC at https://www.isc.org/bind-keys.\n\
+\n\
+managed-keys {\n\
+ # ISC DLV: See https://www.isc.org/solutions/dlv for details.\n\
+ # NOTE: This key is activated by setting \"dnssec-lookaside auto;\"\n\
+ # in named.conf.\n\
+ dlv.isc.org. initial-key 257 3 5 \"BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2\n\
+ brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+\n\
+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5\n\
+ ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk\n\
+ Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM\n\
+ QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt\n\
+ TDN0YUuWrBNh\";\n\
+\n\
+ # ROOT KEY: See https://data.iana.org/root-anchors/root-anchors.xml\n\
+ # for current trust anchor information.\n\
+ # NOTE: This key is activated by setting \"dnssec-validation auto;\"\n\
+ # in named.conf.\n\
+ . initial-key 257 3 8 \"AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF\n\
+ FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX\n\
+ bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD\n\
+ X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz\n\
+ W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS\n\
+ Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq\n\
+ QxA+Uk1ihz0=\";\n\
+};\n\
+"
diff --git a/bin/named/bind9.xsl b/bin/named/bind9.xsl
index 71d2eba108d2..5913c1cc2000 100644
--- a/bin/named/bind9.xsl
+++ b/bin/named/bind9.xsl
@@ -15,7 +15,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: bind9.xsl,v 1.19.82.2 2009-01-29 23:47:43 tbox Exp $ -->
+<!-- $Id: bind9.xsl,v 1.21 2009-01-27 23:47:54 tbox Exp $ -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
diff --git a/bin/named/bind9.xsl.h b/bin/named/bind9.xsl.h
index d68675131eb9..b6f1f5491b95 100644
--- a/bin/named/bind9.xsl.h
+++ b/bin/named/bind9.xsl.h
@@ -1,6 +1,6 @@
/*
* Generated by convertxsl.pl 1.14 2008-07-17 23:43:26 jinmei Exp
- * From bind9.xsl 1.19.82.2 2009-01-29 23:47:43 tbox Exp
+ * From bind9.xsl 1.21 2009-01-27 23:47:54 tbox Exp
*/
static char xslmsg[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
@@ -20,7 +20,7 @@ static char xslmsg[] =
" - PERFORMANCE OF THIS SOFTWARE.\n"
"-->\n"
"\n"
- "<!-- \045Id: bind9.xsl,v 1.19.82.2 2009-01-29 23:47:43 tbox Exp \045 -->\n"
+ "<!-- \045Id: bind9.xsl,v 1.21 2009-01-27 23:47:54 tbox Exp \045 -->\n"
"\n"
"<xsl:stylesheet version=\"1.0\"\n"
" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n"
diff --git a/bin/named/builtin.c b/bin/named/builtin.c
index 60cb634fabd3..d7730e7afed0 100644
--- a/bin/named/builtin.c
+++ b/bin/named/builtin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: builtin.c,v 1.12.334.3 2010-08-03 23:45:47 tbox Exp $ */
+/* $Id: builtin.c,v 1.20 2011-01-07 23:47:07 tbox Exp $ */
/*! \file
* \brief
@@ -47,6 +47,7 @@ static isc_result_t do_hostname_lookup(dns_sdblookup_t *lookup);
static isc_result_t do_authors_lookup(dns_sdblookup_t *lookup);
static isc_result_t do_id_lookup(dns_sdblookup_t *lookup);
static isc_result_t do_empty_lookup(dns_sdblookup_t *lookup);
+static isc_result_t do_dns64_lookup(dns_sdblookup_t *lookup);
/*
* We can't use function pointers as the db_data directly
@@ -65,9 +66,179 @@ static builtin_t hostname_builtin = { do_hostname_lookup, NULL, NULL };
static builtin_t authors_builtin = { do_authors_lookup, NULL, NULL };
static builtin_t id_builtin = { do_id_lookup, NULL, NULL };
static builtin_t empty_builtin = { do_empty_lookup, NULL, NULL };
+static builtin_t dns64_builtin = { do_dns64_lookup, NULL, NULL };
static dns_sdbimplementation_t *builtin_impl;
+static const char hex[] = "0123456789abcdef";
+static const char HEX[] = "0123456789ABCDEF";
+
+static isc_result_t
+dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) {
+ size_t zlen, nlen, j;
+ const char *s;
+ unsigned char v[16];
+ unsigned int i;
+ char reverse[sizeof("123.123.123.123.in-addr.arpa.")];
+
+ /*
+ * The sum the length of the relative name and the length of the zone
+ * name for a IPv6 reverse lookup comes to 71.
+ *
+ * The reverse of 2001::10.0.0.1 (dns64 2001::/96) has a zone of
+ * "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.2.ip6.arpa"
+ * and a name of "1.0.0.0.0.0.a.0". The sum of the lengths of these
+ * two strings is 71.
+ *
+ * The minimum length for a ip6.arpa zone name is 8.
+ *
+ * The length of name should always be odd as we are expecting
+ * a series of nibbles.
+ */
+ zlen = strlen(zone);
+ nlen = strlen(name);
+ if ((zlen + nlen) > 71U || zlen < 8U || (nlen % 2) != 1U)
+ return (ISC_R_NOTFOUND);
+
+ /*
+ * We assume the zone name is well formed.
+ */
+
+ /*
+ * XXXMPA We could check the dns64 suffix here if we need to.
+ */
+ /*
+ * Check that name is a series of nibbles.
+ * Compute the byte values that correspond to the nibbles as we go.
+ *
+ * Shift the final result 4 bits, by setting 'i' to 1, if we if we
+ * have a odd number of nibbles so that "must be zero" tests below
+ * are byte aligned and we correctly return ISC_R_NOTFOUND or
+ * ISC_R_SUCCESS. We will not generate a CNAME in this case.
+ */
+ i = (nlen % 4) == 1U ? 1 : 0;
+ j = nlen;
+ memset(v, 0, sizeof(v));
+ while (j >= 1U) {
+ INSIST((i/2) < sizeof(v));
+ if (j > 1U && name[1] != '.')
+ return (ISC_R_NOTFOUND);
+ v[i/2] >>= 4;
+ if ((s = strchr(hex, name[0])) != NULL)
+ v[i/2] |= (s - hex) << 4;
+ else if ((s = strchr(HEX, name[0])) != NULL)
+ v[i/2] |= (s - HEX) << 4;
+ else
+ return (ISC_R_NOTFOUND);
+ if (j > 1U)
+ j -= 2;
+ else
+ j -= 1;
+ name += 2;
+ i++;
+ }
+
+ /*
+ * If we get here then we know name only consisted of nibbles.
+ * Now we need to determine if the name exists or not and whether
+ * it corresponds to a empty node in the zone or there should be
+ * a CNAME.
+ */
+ switch (zlen) {
+ case 24: /* prefix len 32 */
+ /*
+ * If the total length is not 71 then this is a empty node
+ * so return success.
+ */
+ if (nlen + zlen != 71U)
+ return (ISC_R_SUCCESS);
+ snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
+ v[8], v[9], v[10], v[11]);
+ break;
+ case 28: /* prefix len 40 */
+ /*
+ * The nibbles that map to this byte must be zero for 'name'
+ * to exist in the zone.
+ */
+ if (nlen > 11U && v[nlen/4 - 3] != 0)
+ return (ISC_R_NOTFOUND);
+ /*
+ * If the total length is not 71 then this is a empty node
+ * so return success.
+ */
+ if (nlen + zlen != 71U)
+ return (ISC_R_SUCCESS);
+ snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
+ v[6], v[8], v[9], v[10]);
+ break;
+ case 32: /* prefix len 48 */
+ /*
+ * The nibbles that map to this byte must be zero for 'name'
+ * to exist in the zone.
+ */
+ if (nlen > 7U && v[nlen/4 - 2] != 0)
+ return (ISC_R_NOTFOUND);
+ /*
+ * If the total length is not 71 then this is a empty node
+ * so return success.
+ */
+ if (nlen + zlen != 71U)
+ return (ISC_R_SUCCESS);
+ snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
+ v[5], v[6], v[8], v[9]);
+ break;
+ case 36: /* prefix len 56 */
+ /*
+ * The nibbles that map to this byte must be zero for 'name'
+ * to exist in the zone.
+ */
+ if (nlen > 3U && v[nlen/4 - 1] != 0)
+ return (ISC_R_NOTFOUND);
+ /*
+ * If the total length is not 71 then this is a empty node
+ * so return success.
+ */
+ if (nlen + zlen != 71U)
+ return (ISC_R_SUCCESS);
+ snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
+ v[4], v[5], v[6], v[8]);
+ break;
+ case 40: /* prefix len 64 */
+ /*
+ * The nibbles that map to this byte must be zero for 'name'
+ * to exist in the zone.
+ */
+ if (v[nlen/4] != 0)
+ return (ISC_R_NOTFOUND);
+ /*
+ * If the total length is not 71 then this is a empty node
+ * so return success.
+ */
+ if (nlen + zlen != 71U)
+ return (ISC_R_SUCCESS);
+ snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
+ v[3], v[4], v[5], v[6]);
+ break;
+ case 56: /* prefix len 96 */
+ /*
+ * If the total length is not 71 then this is a empty node
+ * so return success.
+ */
+ if (nlen + zlen != 71U)
+ return (ISC_R_SUCCESS);
+ snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
+ v[0], v[1], v[2], v[3]);
+ break;
+ default:
+ /*
+ * This should never be reached unless someone adds a
+ * zone declaration with this internal type to named.conf.
+ */
+ return (ISC_R_NOTFOUND);
+ }
+ return (dns_sdb_putrr(lookup, "CNAME", 600, reverse));
+}
+
static isc_result_t
builtin_lookup(const char *zone, const char *name, void *dbdata,
dns_sdblookup_t *lookup)
@@ -78,6 +249,8 @@ builtin_lookup(const char *zone, const char *name, void *dbdata,
if (strcmp(name, "@") == 0)
return (b->do_lookup(lookup));
+ else if (b->do_lookup == do_dns64_lookup)
+ return (dns64_cname(zone, name, lookup));
else
return (ISC_R_NOTFOUND);
}
@@ -132,11 +305,13 @@ do_authors_lookup(dns_sdblookup_t *lookup) {
"Michael Graff",
"Andreas Gustafsson",
"Bob Halley",
+ "Evan Hunt",
"JINMEI Tatuya",
"David Lawrence",
"Danny Mayer",
"Damien Neil",
"Matt Nelson",
+ "Jeremy C. Reed",
"Michael Sawyer",
"Brian Wellington",
NULL
@@ -174,6 +349,12 @@ do_id_lookup(dns_sdblookup_t *lookup) {
}
static isc_result_t
+do_dns64_lookup(dns_sdblookup_t *lookup) {
+ UNUSED(lookup);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
do_empty_lookup(dns_sdblookup_t *lookup) {
UNUSED(lookup);
@@ -220,7 +401,7 @@ builtin_create(const char *zone, int argc, char **argv,
UNUSED(zone);
UNUSED(driverdata);
- if (strcmp(argv[0], "empty") == 0) {
+ if (strcmp(argv[0], "empty") == 0 || strcmp(argv[0], "dns64") == 0) {
if (argc != 3)
return (DNS_R_SYNTAX);
} else if (argc != 1)
@@ -234,7 +415,8 @@ builtin_create(const char *zone, int argc, char **argv,
*dbdata = &authors_builtin;
else if (strcmp(argv[0], "id") == 0)
*dbdata = &id_builtin;
- else if (strcmp(argv[0], "empty") == 0) {
+ else if (strcmp(argv[0], "empty") == 0 ||
+ strcmp(argv[0], "dns64") == 0) {
builtin_t *empty;
char *server;
char *contact;
@@ -246,7 +428,10 @@ builtin_create(const char *zone, int argc, char **argv,
server = isc_mem_strdup(ns_g_mctx, argv[1]);
contact = isc_mem_strdup(ns_g_mctx, argv[2]);
if (empty == NULL || server == NULL || contact == NULL) {
- *dbdata = &empty_builtin;
+ if (strcmp(argv[0], "empty") == 0)
+ *dbdata = &empty_builtin;
+ else
+ *dbdata = &dns64_builtin;
if (server != NULL)
isc_mem_free(ns_g_mctx, server);
if (contact != NULL)
@@ -254,7 +439,12 @@ builtin_create(const char *zone, int argc, char **argv,
if (empty != NULL)
isc_mem_put(ns_g_mctx, empty, sizeof (*empty));
} else {
- memcpy(empty, &empty_builtin, sizeof (empty_builtin));
+ if (strcmp(argv[0], "empty") == 0)
+ memcpy(empty, &empty_builtin,
+ sizeof (empty_builtin));
+ else
+ memcpy(empty, &dns64_builtin,
+ sizeof (empty_builtin));
empty->server = server;
empty->contact = contact;
*dbdata = empty;
@@ -276,7 +466,7 @@ builtin_destroy(const char *zone, void *driverdata, void **dbdata) {
*/
if (*dbdata == &version_builtin || *dbdata == &hostname_builtin ||
*dbdata == &authors_builtin || *dbdata == &id_builtin ||
- *dbdata == &empty_builtin)
+ *dbdata == &empty_builtin || *dbdata == &dns64_builtin)
return;
isc_mem_free(ns_g_mctx, b->server);
@@ -306,3 +496,4 @@ void
ns_builtin_deinit(void) {
dns_sdb_unregister(&builtin_impl);
}
+
diff --git a/bin/named/client.c b/bin/named/client.c
index 6236d27f28a0..bc9cc878adbc 100644
--- a/bin/named/client.c
+++ b/bin/named/client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: client.c,v 1.259.12.5 2010-09-24 08:30:27 tbox Exp $ */
+/* $Id: client.c,v 1.271 2011-01-11 23:47:12 tbox Exp $ */
#include <config.h>
@@ -918,7 +918,7 @@ ns_client_send(ns_client_t *client) {
dns_compress_t cctx;
isc_boolean_t cleanup_cctx = ISC_FALSE;
unsigned char sendbuf[SEND_BUFFER_SIZE];
- unsigned int dnssec_opts;
+ unsigned int render_opts;
unsigned int preferred_glue;
isc_boolean_t opt_included = ISC_FALSE;
@@ -930,10 +930,21 @@ ns_client_send(ns_client_t *client) {
client->message->flags |= DNS_MESSAGEFLAG_RA;
if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0)
- dnssec_opts = 0;
+ render_opts = 0;
else
- dnssec_opts = DNS_MESSAGERENDER_OMITDNSSEC;
-
+ render_opts = DNS_MESSAGERENDER_OMITDNSSEC;
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ /*
+ * filter-aaaa-on-v4 yes or break-dnssec option to suppress
+ * AAAA records
+ * We already know that request came via IPv4,
+ * that we have both AAAA and A records,
+ * and that we either have no signatures that the client wants
+ * or we are supposed to break DNSSEC.
+ */
+ if ((client->attributes & NS_CLIENTATTR_FILTER_AAAA) != 0)
+ render_opts |= DNS_MESSAGERENDER_FILTER_AAAA;
+#endif
preferred_glue = 0;
if (client->view != NULL) {
if (client->view->preferred_glue == dns_rdatatype_a)
@@ -977,7 +988,7 @@ ns_client_send(ns_client_t *client) {
result = dns_message_rendersection(client->message,
DNS_SECTION_ANSWER,
DNS_MESSAGERENDER_PARTIAL |
- dnssec_opts);
+ render_opts);
if (result == ISC_R_NOSPACE) {
client->message->flags |= DNS_MESSAGEFLAG_TC;
goto renderend;
@@ -987,7 +998,7 @@ ns_client_send(ns_client_t *client) {
result = dns_message_rendersection(client->message,
DNS_SECTION_AUTHORITY,
DNS_MESSAGERENDER_PARTIAL |
- dnssec_opts);
+ render_opts);
if (result == ISC_R_NOSPACE) {
client->message->flags |= DNS_MESSAGEFLAG_TC;
goto renderend;
@@ -996,7 +1007,7 @@ ns_client_send(ns_client_t *client) {
goto done;
result = dns_message_rendersection(client->message,
DNS_SECTION_ADDITIONAL,
- preferred_glue | dnssec_opts);
+ preferred_glue | render_opts);
if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
goto done;
renderend:
@@ -1355,7 +1366,6 @@ client_request(isc_task_t *task, isc_event_t *event) {
dns_name_t *signame;
isc_boolean_t ra; /* Recursion available. */
isc_netaddr_t netaddr;
- isc_netaddr_t destaddr;
int match;
dns_messageid_t id;
unsigned int flags;
@@ -1473,7 +1483,7 @@ client_request(isc_task_t *task, isc_event_t *event) {
/*
* Silently drop multicast requests for the present.
- * XXXMPA look at when/if mDNS spec stabilizes.
+ * XXXMPA revisit this as mDNS spec was published.
*/
if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) {
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
@@ -1647,24 +1657,20 @@ client_request(isc_task_t *task, isc_event_t *event) {
* etc), we regard this as an error for safety.
*/
if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0)
- isc_netaddr_fromsockaddr(&destaddr, &client->interface->addr);
+ isc_netaddr_fromsockaddr(&client->destaddr,
+ &client->interface->addr);
else {
+ isc_sockaddr_t sockaddr;
result = ISC_R_FAILURE;
- if (TCP_CLIENT(client)) {
- isc_sockaddr_t destsockaddr;
-
+ if (TCP_CLIENT(client))
result = isc_socket_getsockname(client->tcpsocket,
- &destsockaddr);
- if (result == ISC_R_SUCCESS)
- isc_netaddr_fromsockaddr(&destaddr,
- &destsockaddr);
- }
+ &sockaddr);
+ if (result == ISC_R_SUCCESS)
+ isc_netaddr_fromsockaddr(&client->destaddr, &sockaddr);
if (result != ISC_R_SUCCESS &&
client->interface->addr.type.sa.sa_family == AF_INET6 &&
(client->attributes & NS_CLIENTATTR_PKTINFO) != 0) {
- isc_uint32_t zone = 0;
-
/*
* XXXJT technically, we should convert the receiving
* interface ID to a proper scope zone ID. However,
@@ -1673,12 +1679,11 @@ client_request(isc_task_t *task, isc_event_t *event) {
* interface index as link ID. Despite the assumption,
* it should cover most typical cases.
*/
- if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr))
- zone = (isc_uint32_t)client->pktinfo.ipi6_ifindex;
-
- isc_netaddr_fromin6(&destaddr,
+ isc_netaddr_fromin6(&client->destaddr,
&client->pktinfo.ipi6_addr);
- isc_netaddr_setzone(&destaddr, zone);
+ if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr))
+ isc_netaddr_setzone(&client->destaddr,
+ client->pktinfo.ipi6_ifindex);
result = ISC_R_SUCCESS;
}
if (result != ISC_R_SUCCESS) {
@@ -1708,7 +1713,8 @@ client_request(isc_task_t *task, isc_event_t *event) {
tsig = dns_tsigkey_identity(client->message->tsigkey);
if (allowed(&netaddr, tsig, view->matchclients) &&
- allowed(&destaddr, tsig, view->matchdestinations) &&
+ allowed(&client->destaddr, tsig,
+ view->matchdestinations) &&
!((client->message->flags & DNS_MESSAGEFLAG_RD)
== 0 && view->matchrecursiveonly))
{
@@ -1771,9 +1777,11 @@ client_request(isc_task_t *task, isc_event_t *event) {
}
if (result == ISC_R_SUCCESS) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ dns_name_format(&client->signername, namebuf, sizeof(namebuf));
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
- "request has valid signature");
+ "request has valid signature: %s", namebuf);
client->signer = &client->signername;
} else if (result == ISC_R_NOTFOUND) {
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
@@ -1861,10 +1869,10 @@ client_request(isc_task_t *task, isc_event_t *event) {
ns_client_checkaclsilent(client, NULL,
client->view->cacheacl,
ISC_TRUE) == ISC_R_SUCCESS &&
- ns_client_checkaclsilent(client, &client->interface->addr,
+ ns_client_checkaclsilent(client, &client->destaddr,
client->view->recursiononacl,
ISC_TRUE) == ISC_R_SUCCESS &&
- ns_client_checkaclsilent(client, &client->interface->addr,
+ ns_client_checkaclsilent(client, &client->destaddr,
client->view->cacheonacl,
ISC_TRUE) == ISC_R_SUCCESS)
ra = ISC_TRUE;
@@ -2600,12 +2608,12 @@ ns_client_getsockaddr(ns_client_t *client) {
}
isc_result_t
-ns_client_checkaclsilent(ns_client_t *client, isc_sockaddr_t *sockaddr,
+ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
dns_acl_t *acl, isc_boolean_t default_allow)
{
isc_result_t result;
+ isc_netaddr_t tmpnetaddr;
int match;
- isc_netaddr_t netaddr;
if (acl == NULL) {
if (default_allow)
@@ -2614,15 +2622,13 @@ ns_client_checkaclsilent(ns_client_t *client, isc_sockaddr_t *sockaddr,
goto deny;
}
+ if (netaddr == NULL) {
+ isc_netaddr_fromsockaddr(&tmpnetaddr, &client->peeraddr);
+ netaddr = &tmpnetaddr;
+ }
- if (sockaddr == NULL)
- isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
- else
- isc_netaddr_fromsockaddr(&netaddr, sockaddr);
-
- result = dns_acl_match(&netaddr, client->signer, acl,
- &ns_g_server->aclenv,
- &match, NULL);
+ 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. */
@@ -2642,8 +2648,14 @@ ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr,
const char *opname, dns_acl_t *acl,
isc_boolean_t default_allow, int log_level)
{
- isc_result_t result =
- ns_client_checkaclsilent(client, sockaddr, acl, default_allow);
+ isc_result_t result;
+ isc_netaddr_t netaddr;
+
+ if (sockaddr != NULL)
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+
+ result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL,
+ acl, default_allow);
if (result == ISC_R_SUCCESS)
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
@@ -2753,9 +2765,14 @@ void
ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {
ns_client_t *client;
char namebuf[DNS_NAME_FORMATSIZE];
+ char original[DNS_NAME_FORMATSIZE];
char peerbuf[ISC_SOCKADDR_FORMATSIZE];
+ char typebuf[DNS_RDATATYPE_FORMATSIZE];
+ char classbuf[DNS_RDATACLASS_FORMATSIZE];
const char *name;
const char *sep;
+ const char *origfor;
+ dns_rdataset_t *rdataset;
REQUIRE(VALID_MANAGER(manager));
@@ -2773,8 +2790,31 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {
sep = "";
}
dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
- fprintf(f, "; client %s%s%s: '%s' requesttime %d\n",
- peerbuf, sep, name, namebuf, client->requesttime);
+ if (client->query.qname != client->query.origqname &&
+ client->query.origqname != NULL) {
+ origfor = " for ";
+ dns_name_format(client->query.origqname, original,
+ sizeof(original));
+ } else {
+ origfor = "";
+ original[0] = '\0';
+ }
+ rdataset = ISC_LIST_HEAD(client->query.qname->list);
+ if (rdataset == NULL && client->query.origqname != NULL)
+ rdataset = ISC_LIST_HEAD(client->query.origqname->list);
+ if (rdataset != NULL) {
+ dns_rdatatype_format(rdataset->type, typebuf,
+ sizeof(typebuf));
+ dns_rdataclass_format(rdataset->rdclass, classbuf,
+ sizeof(classbuf));
+ } else {
+ strcpy(typebuf, "-");
+ strcpy(classbuf, "-");
+ }
+ fprintf(f, "; client %s%s%s: id %u '%s/%s/%s'%s%s "
+ "requesttime %d\n", peerbuf, sep, name,
+ client->message->id, namebuf, typebuf, classbuf,
+ origfor, original, client->requesttime);
client = ISC_LIST_NEXT(client, link);
}
UNLOCK(&manager->lock);
diff --git a/bin/named/config.c b/bin/named/config.c
index 43d0e5287d04..704d7ecc55ef 100644
--- a/bin/named/config.c
+++ b/bin/named/config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: config.c,v 1.93.14.2 2009-03-17 23:47:28 tbox Exp $ */
+/* $Id: config.c,v 1.113.16.1.2.1 2011-06-02 23:47:28 tbox Exp $ */
/*! \file */
@@ -42,9 +42,13 @@
#include <dns/tsig.h>
#include <dns/zone.h>
+#include <dst/dst.h>
+
#include <named/config.h>
#include <named/globals.h>
+#include "bind.keys.h"
+
/*% default configuration */
static char defaultconf[] = "\
options {\n\
@@ -55,7 +59,10 @@ options {\n\
files unlimited;\n\
stacksize default;\n"
#endif
-" deallocate-on-exit true;\n\
+"# session-keyfile \"" NS_LOCALSTATEDIR "/run/named/session.key\";\n\
+ session-keyname local-ddns;\n\
+ session-keyalg hmac-sha256;\n\
+ deallocate-on-exit true;\n\
# directory <none>\n\
dump-file \"named_dump.db\";\n\
fake-iquery no;\n\
@@ -70,8 +77,10 @@ options {\n\
multiple-cnames no;\n\
# named-xfer <obsolete>;\n\
# pid-file \"" NS_LOCALSTATEDIR "/run/named/named.pid\"; /* or /lwresd.pid */\n\
+ bindkeys-file \"" NS_SYSCONFDIR "/bind.keys\";\n\
port 53;\n\
recursing-file \"named.recursing\";\n\
+ secroots-file \"named.secroots\";\n\
"
#ifdef PATH_RANDOMDEV
"\
@@ -80,6 +89,7 @@ options {\n\
#endif
"\
recursive-clients 1000;\n\
+ resolver-query-timeout 30;\n\
rrset-order {type NS order random; order cyclic; };\n\
serial-queries 20;\n\
serial-query-rate 20;\n\
@@ -102,6 +112,9 @@ options {\n\
request-nsid false;\n\
reserved-sockets 512;\n\
\n\
+ /* DLV */\n\
+ dnssec-lookaside . trust-anchor dlv.isc.org;\n\
+\n\
/* view */\n\
allow-notify {none;};\n\
allow-update-forwarding {none;};\n\
@@ -135,6 +148,7 @@ options {\n\
check-names master fail;\n\
check-names slave warn;\n\
check-names response ignore;\n\
+ check-dup-records warn;\n\
check-mx warn;\n\
acache-enable no;\n\
acache-cleaning-interval 60;\n\
@@ -146,7 +160,13 @@ options {\n\
max-clients-per-query 100;\n\
zero-no-soa-ttl-cache no;\n\
nsec3-test-zone no;\n\
+ allow-new-zones no;\n\
+"
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+" filter-aaaa-on-v4 no;\n\
+ filter-aaaa { any; };\n\
"
+#endif
" /* zone */\n\
allow-query {any;};\n\
@@ -174,6 +194,7 @@ options {\n\
max-refresh-time 2419200; /* 4 weeks */\n\
min-refresh-time 300;\n\
multi-master no;\n\
+ dnssec-secure-to-insecure no;\n\
sig-validity-interval 30; /* days */\n\
sig-signing-nodes 100;\n\
sig-signing-signatures 10;\n\
@@ -188,6 +209,7 @@ options {\n\
check-srv-cname warn;\n\
zero-no-soa-ttl yes;\n\
update-check-ksk yes;\n\
+ dnssec-dnskey-kskonly no;\n\
try-tcp-refresh yes; /* BIND 8 compat */\n\
};\n\
"
@@ -198,6 +220,7 @@ options {\n\
view \"_bind\" chaos {\n\
recursion no;\n\
notify no;\n\
+ allow-new-zones no;\n\
\n\
zone \"version.bind\" chaos {\n\
type master;\n\
@@ -213,11 +236,24 @@ view \"_bind\" chaos {\n\
type master;\n\
database \"_builtin authors\";\n\
};\n\
+\n\
zone \"id.server\" chaos {\n\
type master;\n\
database \"_builtin id\";\n\
};\n\
};\n\
+"
+"#\n\
+# Default trusted key(s) for builtin DLV support\n\
+# (used if \"dnssec-lookaside auto;\" is set and\n\
+# sysconfdir/bind.keys doesn't exist).\n\
+#\n\
+# BEGIN MANAGED KEYS\n"
+
+/* Imported from bind.keys.h: */
+MANAGED_KEYS
+
+"# END MANAGED KEYS\n\
";
isc_result_t
@@ -339,6 +375,8 @@ ns_config_getzonetype(const cfg_obj_t *zonetypeobj) {
ztype = dns_zone_slave;
else if (strcasecmp(str, "stub") == 0)
ztype = dns_zone_stub;
+ else if (strcasecmp(str, "static-stub") == 0)
+ ztype = dns_zone_staticstub;
else
INSIST(0);
return (ztype);
@@ -615,7 +653,7 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
isc_buffer_add(&b, strlen(keystr));
dns_fixedname_init(&fname);
result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_name_dup(dns_fixedname_name(&fname), mctx,
@@ -747,23 +785,31 @@ struct keyalgorithms {
const char *str;
enum { hmacnone, hmacmd5, hmacsha1, hmacsha224,
hmacsha256, hmacsha384, hmacsha512 } hmac;
+ unsigned int type;
isc_uint16_t size;
} algorithms[] = {
- { "hmac-md5", hmacmd5, 128 },
- { "hmac-md5.sig-alg.reg.int", hmacmd5, 0 },
- { "hmac-md5.sig-alg.reg.int.", hmacmd5, 0 },
- { "hmac-sha1", hmacsha1, 160 },
- { "hmac-sha224", hmacsha224, 224 },
- { "hmac-sha256", hmacsha256, 256 },
- { "hmac-sha384", hmacsha384, 384 },
- { "hmac-sha512", hmacsha512, 512 },
- { NULL, hmacnone, 0 }
+ { "hmac-md5", hmacmd5, DST_ALG_HMACMD5, 128 },
+ { "hmac-md5.sig-alg.reg.int", hmacmd5, DST_ALG_HMACMD5, 0 },
+ { "hmac-md5.sig-alg.reg.int.", hmacmd5, DST_ALG_HMACMD5, 0 },
+ { "hmac-sha1", hmacsha1, DST_ALG_HMACSHA1, 160 },
+ { "hmac-sha224", hmacsha224, DST_ALG_HMACSHA224, 224 },
+ { "hmac-sha256", hmacsha256, DST_ALG_HMACSHA256, 256 },
+ { "hmac-sha384", hmacsha384, DST_ALG_HMACSHA384, 384 },
+ { "hmac-sha512", hmacsha512, DST_ALG_HMACSHA512, 512 },
+ { NULL, hmacnone, DST_ALG_UNKNOWN, 0 }
};
isc_result_t
ns_config_getkeyalgorithm(const char *str, dns_name_t **name,
isc_uint16_t *digestbits)
{
+ return (ns_config_getkeyalgorithm2(str, name, NULL, digestbits));
+}
+
+isc_result_t
+ns_config_getkeyalgorithm2(const char *str, dns_name_t **name,
+ unsigned int *typep, isc_uint16_t *digestbits)
+{
int i;
size_t len = 0;
isc_uint16_t bits;
@@ -801,6 +847,8 @@ ns_config_getkeyalgorithm(const char *str, dns_name_t **name,
INSIST(0);
}
}
+ if (typep != NULL)
+ *typep = algorithms[i].type;
if (digestbits != NULL)
*digestbits = bits;
return (ISC_R_SUCCESS);
diff --git a/bin/named/control.c b/bin/named/control.c
index 38115d607bbb..3fc7bd3916f5 100644
--- a/bin/named/control.c
+++ b/bin/named/control.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: control.c,v 1.33.266.4 2010-12-03 23:45:46 tbox Exp $ */
+/* $Id: control.c,v 1.41 2010-12-03 22:05:19 each Exp $ */
/*! \file */
@@ -158,6 +158,8 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
} else if (command_compare(command, NS_COMMAND_DUMPDB)) {
ns_server_dumpdb(ns_g_server, command);
result = ISC_R_SUCCESS;
+ } else if (command_compare(command, NS_COMMAND_SECROOTS)) {
+ result = ns_server_dumpsecroots(ns_g_server, command);
} else if (command_compare(command, NS_COMMAND_TRACE)) {
result = ns_server_setdebuglevel(ns_g_server, command);
} else if (command_compare(command, NS_COMMAND_NOTRACE)) {
@@ -192,6 +194,13 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
result = ns_server_notifycommand(ns_g_server, command, text);
} else if (command_compare(command, NS_COMMAND_VALIDATION)) {
result = ns_server_validation(ns_g_server, command);
+ } else if (command_compare(command, NS_COMMAND_SIGN) ||
+ command_compare(command, NS_COMMAND_LOADKEYS)) {
+ result = ns_server_rekey(ns_g_server, command);
+ } else if (command_compare(command, NS_COMMAND_ADDZONE)) {
+ result = ns_server_add_zone(ns_g_server, command);
+ } else if (command_compare(command, NS_COMMAND_DELZONE)) {
+ result = ns_server_del_zone(ns_g_server, command);
} else {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h
index 5ad9c6bf5ff0..33f124d94c14 100644
--- a/bin/named/include/named/client.h
+++ b/bin/named/include/named/client.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: client.h,v 1.86.120.2 2009-01-18 23:47:34 tbox Exp $ */
+/* $Id: client.h,v 1.91 2009-10-26 23:14:53 each Exp $ */
#ifndef NAMED_CLIENT_H
#define NAMED_CLIENT_H 1
@@ -138,6 +138,7 @@ struct ns_client {
ns_interface_t *interface;
isc_sockaddr_t peeraddr;
isc_boolean_t peeraddr_valid;
+ isc_netaddr_t destaddr;
struct in6_pktinfo pktinfo;
isc_event_t ctlevent;
/*%
@@ -167,6 +168,10 @@ struct ns_client {
#define NS_CLIENTATTR_MULTICAST 0x08 /*%< recv'd from multicast */
#define NS_CLIENTATTR_WANTDNSSEC 0x10 /*%< include dnssec records */
#define NS_CLIENTATTR_WANTNSID 0x20 /*%< include nameserver ID */
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+#define NS_CLIENTATTR_FILTER_AAAA 0x40 /*%< suppress AAAAs */
+#define NS_CLIENTATTR_FILTER_AAAA_RC 0x80 /*%< recursing for A against AAAA */
+#endif
extern unsigned int ns_client_requests;
@@ -274,10 +279,8 @@ ns_client_getsockaddr(ns_client_t *client);
*/
isc_result_t
-ns_client_checkaclsilent(ns_client_t *client,
- isc_sockaddr_t *sockaddr,
- dns_acl_t *acl,
- isc_boolean_t default_allow);
+ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
+ dns_acl_t *acl, isc_boolean_t default_allow);
/*%
* Convenience function for client request ACL checking.
@@ -296,12 +299,12 @@ ns_client_checkaclsilent(ns_client_t *client,
*
* Requires:
*\li 'client' points to a valid client.
- *\li 'sockaddr' points to a valid address, or is NULL.
+ *\li 'netaddr' points to a valid address, or is NULL.
*\li 'acl' points to a valid ACL, or is NULL.
*
* Returns:
*\li ISC_R_SUCCESS if the request should be allowed
- * \li ISC_R_REFUSED if the request should be denied
+ * \li DNS_R_REFUSED if the request should be denied
*\li No other return values are possible.
*/
diff --git a/bin/named/include/named/config.h b/bin/named/include/named/config.h
index fa96d32947e3..d1570b0e5704 100644
--- a/bin/named/include/named/config.h
+++ b/bin/named/include/named/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001, 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: config.h,v 1.14 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: config.h,v 1.16 2009-06-11 23:47:55 tbox Exp $ */
#ifndef NAMED_CONFIG_H
#define NAMED_CONFIG_H 1
@@ -75,5 +75,8 @@ ns_config_getport(const cfg_obj_t *config, in_port_t *portp);
isc_result_t
ns_config_getkeyalgorithm(const char *str, dns_name_t **name,
isc_uint16_t *digestbits);
+isc_result_t
+ns_config_getkeyalgorithm2(const char *str, dns_name_t **name,
+ unsigned int *typep, isc_uint16_t *digestbits);
#endif /* NAMED_CONFIG_H */
diff --git a/bin/named/include/named/control.h b/bin/named/include/named/control.h
index 436fb19c7bf6..e699892ca4ce 100644
--- a/bin/named/include/named/control.h
+++ b/bin/named/include/named/control.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: control.h,v 1.25 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: control.h,v 1.31 2010-08-16 22:21:06 marka Exp $ */
#ifndef NAMED_CONTROL_H
#define NAMED_CONTROL_H 1
@@ -42,6 +42,7 @@
#define NS_COMMAND_DUMPSTATS "stats"
#define NS_COMMAND_QUERYLOG "querylog"
#define NS_COMMAND_DUMPDB "dumpdb"
+#define NS_COMMAND_SECROOTS "secroots"
#define NS_COMMAND_TRACE "trace"
#define NS_COMMAND_NOTRACE "notrace"
#define NS_COMMAND_FLUSH "flush"
@@ -57,6 +58,10 @@
#define NS_COMMAND_NULL "null"
#define NS_COMMAND_NOTIFY "notify"
#define NS_COMMAND_VALIDATION "validation"
+#define NS_COMMAND_SIGN "sign"
+#define NS_COMMAND_LOADKEYS "loadkeys"
+#define NS_COMMAND_ADDZONE "addzone"
+#define NS_COMMAND_DELZONE "delzone"
isc_result_t
ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp);
diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h
index 1d57a18f2008..f155c7f05ed5 100644
--- a/bin/named/include/named/globals.h
+++ b/bin/named/include/named/globals.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: globals.h,v 1.80.12.3 2010-09-15 12:16:50 marka Exp $ */
+/* $Id: globals.h,v 1.89 2010-09-15 12:07:55 marka Exp $ */
#ifndef NAMED_GLOBALS_H
#define NAMED_GLOBALS_H 1
@@ -30,6 +30,8 @@
#include <dns/zone.h>
+#include <dst/dst.h>
+
#include <named/types.h>
#undef EXTERN
@@ -86,8 +88,13 @@ EXTERN cfg_obj_t * ns_g_config INIT(NULL);
EXTERN const cfg_obj_t * ns_g_defaults INIT(NULL);
EXTERN const char * ns_g_conffile INIT(NS_SYSCONFDIR
"/named.conf");
+EXTERN cfg_obj_t * ns_g_bindkeys INIT(NULL);
EXTERN const char * ns_g_keyfile INIT(NS_SYSCONFDIR
"/rndc.key");
+
+EXTERN dns_tsigkey_t * ns_g_sessionkey INIT(NULL);
+EXTERN dns_name_t ns_g_sessionkeyname;
+
EXTERN const char * lwresd_g_conffile INIT(NS_SYSCONFDIR
"/lwresd.conf");
EXTERN const char * lwresd_g_resolvconffile INIT("/etc"
@@ -112,6 +119,10 @@ 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_defaultsessionkeyfile
+ INIT(NS_LOCALSTATEDIR "/run/named/"
+ "session.key");
+
#if NS_RUN_PID_DIR
EXTERN const char * ns_g_defaultpidfile INIT(NS_LOCALSTATEDIR
"/run/named/"
@@ -128,6 +139,12 @@ EXTERN const char * lwresd_g_defaultpidfile INIT(NS_LOCALSTATEDIR
EXTERN const char * ns_g_username INIT(NULL);
+#ifdef USE_PKCS11
+EXTERN const char * ns_g_engine INIT("pkcs11");
+#else
+EXTERN const char * ns_g_engine INIT(NULL);
+#endif
+
EXTERN int ns_g_listen INIT(3);
EXTERN isc_time_t ns_g_boottime;
EXTERN isc_boolean_t ns_g_memstatistics INIT(ISC_FALSE);
diff --git a/bin/named/include/named/log.h b/bin/named/include/named/log.h
index 0cfbee9ad396..1ce680f31e02 100644
--- a/bin/named/include/named/log.h
+++ b/bin/named/include/named/log.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: log.h,v 1.25.332.2 2009-01-07 23:47:16 tbox Exp $ */
+/* $Id: log.h,v 1.27 2009-01-07 23:47:46 tbox Exp $ */
#ifndef NAMED_LOG_H
#define NAMED_LOG_H 1
diff --git a/bin/named/include/named/lwdclient.h b/bin/named/include/named/lwdclient.h
index 44e1fa6e0878..5451b73675ab 100644
--- a/bin/named/include/named/lwdclient.h
+++ b/bin/named/include/named/lwdclient.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lwdclient.h,v 1.18.332.2 2009-01-18 23:47:34 tbox Exp $ */
+/* $Id: lwdclient.h,v 1.20 2009-01-17 23:47:42 tbox Exp $ */
#ifndef NAMED_LWDCLIENT_H
#define NAMED_LWDCLIENT_H 1
diff --git a/bin/named/include/named/main.h b/bin/named/include/named/main.h
index 96fb23edd80a..6116add55b85 100644
--- a/bin/named/include/named/main.h
+++ b/bin/named/include/named/main.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,15 +15,16 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: main.h,v 1.15 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: main.h,v 1.17 2009-09-29 23:48:03 tbox Exp $ */
#ifndef NAMED_MAIN_H
#define NAMED_MAIN_H 1
/*! \file */
-void
-ns_main_earlyfatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
+ISC_PLATFORM_NORETURN_PRE void
+ns_main_earlyfatal(const char *format, ...)
+ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
void
ns_main_earlywarning(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
diff --git a/bin/named/include/named/notify.h b/bin/named/include/named/notify.h
index ac7fe2d3a9a6..34fabcd0620c 100644
--- a/bin/named/include/named/notify.h
+++ b/bin/named/include/named/notify.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: notify.h,v 1.14.332.2 2009-01-18 23:47:34 tbox Exp $ */
+/* $Id: notify.h,v 1.16 2009-01-17 23:47:42 tbox Exp $ */
#ifndef NAMED_NOTIFY_H
#define NAMED_NOTIFY_H 1
diff --git a/bin/named/include/named/query.h b/bin/named/include/named/query.h
index 2f00f1ea3843..37f771bd5960 100644
--- a/bin/named/include/named/query.h
+++ b/bin/named/include/named/query.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.h,v 1.40.332.2 2010-09-24 08:30:28 tbox Exp $ */
+/* $Id: query.h,v 1.45 2011-01-13 04:59:24 tbox Exp $ */
#ifndef NAMED_QUERY_H
#define NAMED_QUERY_H 1
@@ -26,6 +26,8 @@
#include <isc/buffer.h>
#include <isc/netaddr.h>
+#include <dns/rdataset.h>
+#include <dns/rpz.h>
#include <dns/types.h>
#include <named/types.h>
@@ -34,6 +36,7 @@
typedef struct ns_dbversion {
dns_db_t *db;
dns_dbversion_t *version;
+ isc_boolean_t acl_checked;
isc_boolean_t queryok;
ISC_LINK(struct ns_dbversion) link;
} ns_dbversion_t;
@@ -54,9 +57,16 @@ struct ns_query {
isc_boolean_t isreferral;
isc_mutex_t fetchlock;
dns_fetch_t * fetch;
+ dns_rpz_st_t * rpz_st;
isc_bufferlist_t namebufs;
ISC_LIST(ns_dbversion_t) activeversions;
ISC_LIST(ns_dbversion_t) freeversions;
+ dns_rdataset_t * dns64_aaaa;
+ dns_rdataset_t * dns64_sigaaaa;
+ isc_boolean_t * dns64_aaaaok;
+ unsigned int dns64_aaaaoklen;
+ unsigned int dns64_options;
+ unsigned int dns64_ttl;
};
#define NS_QUERYATTR_RECURSIONOK 0x0001
@@ -73,6 +83,9 @@ struct ns_query {
#define NS_QUERYATTR_NOADDITIONAL 0x0800
#define NS_QUERYATTR_CACHEACLOKVALID 0x1000
#define NS_QUERYATTR_CACHEACLOK 0x2000
+#define NS_QUERYATTR_DNS64 0x4000
+#define NS_QUERYATTR_DNS64EXCLUDE 0x8000
+
isc_result_t
ns_query_init(ns_client_t *client);
diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h
index 3a4c5f7248e2..3c6426eecf61 100644
--- a/bin/named/include/named/server.h
+++ b/bin/named/include/named/server.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.h,v 1.93.120.3 2009-07-11 04:23:53 marka Exp $ */
+/* $Id: server.h,v 1.110 2010-08-16 23:46:52 tbox Exp $ */
#ifndef NAMED_SERVER_H
#define NAMED_SERVER_H 1
@@ -54,6 +54,8 @@ struct ns_server {
dns_acl_t *blackholeacl;
char * statsfile; /*%< Statistics file name */
char * dumpfile; /*%< Dump file name */
+ char * secrootsfile; /*%< Secroots file name */
+ char * bindkeysfile; /*%< bind.keys file name */
char * recfile; /*%< Recursive file name */
isc_boolean_t version_set; /*%< User has set version */
char * version; /*%< User-specified version */
@@ -91,13 +93,14 @@ struct ns_server {
isc_boolean_t flushonshutdown;
isc_boolean_t log_queries; /*%< For BIND 8 compatibility */
- isc_stats_t * nsstats; /*%< Server statistics */
- dns_stats_t * rcvquerystats; /*% Incoming query statistics */
- dns_stats_t * opcodestats; /*%< Incoming message statistics */
- isc_stats_t * zonestats; /*% Zone management statistics */
- isc_stats_t * resolverstats; /*% Resolver statistics */
+ ns_cachelist_t cachelist; /*%< Possibly shared caches */
+ isc_stats_t * nsstats; /*%< Server stats */
+ dns_stats_t * rcvquerystats; /*% Incoming query stats */
+ dns_stats_t * opcodestats; /*%< Incoming message stats */
+ isc_stats_t * zonestats; /*% Zone management stats */
+ isc_stats_t * resolverstats; /*% Resolver stats */
+ isc_stats_t * sockstats; /*%< Socket stats */
- isc_stats_t * sockstats; /*%< Socket statistics */
ns_controls_t * controls; /*%< Control channels */
unsigned int dispatchgen;
ns_dispatchlist_t dispatches;
@@ -105,6 +108,12 @@ struct ns_server {
dns_acache_t *acache;
ns_statschannellist_t statschannels;
+
+ dns_tsigkey_t *sessionkey;
+ char *session_keyfile;
+ dns_name_t *session_keyname;
+ unsigned int session_keyalg;
+ isc_uint16_t session_keybits;
};
#define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R')
@@ -237,6 +246,12 @@ isc_result_t
ns_server_dumpdb(ns_server_t *server, char *args);
/*%
+ * Dump the current security roots to the secroots file.
+ */
+isc_result_t
+ns_server_dumpsecroots(ns_server_t *server, char *args);
+
+/*%
* Change or increment the server debug level.
*/
isc_result_t
@@ -280,6 +295,16 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
isc_buffer_t *text);
/*%
+ * Update a zone's DNSKEY set from the key repository. If
+ * the command that triggered the call to this function was "sign",
+ * then force a full signing of the zone. If it was "loadkeys",
+ * then don't sign the zone; any needed changes to signatures can
+ * take place incrementally.
+ */
+isc_result_t
+ns_server_rekey(ns_server_t *server, char *args);
+
+/*%
* Dump the current recursive queries.
*/
isc_result_t
@@ -297,4 +322,16 @@ ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr);
isc_result_t
ns_server_validation(ns_server_t *server, char *args);
+/*%
+ * Add a zone to a running process
+ */
+isc_result_t
+ns_server_add_zone(ns_server_t *server, char *args);
+
+/*%
+ * Deletes a zone from a running process
+ */
+isc_result_t
+ns_server_del_zone(ns_server_t *server, char *args);
+
#endif /* NAMED_SERVER_H */
diff --git a/bin/named/include/named/tsigconf.h b/bin/named/include/named/tsigconf.h
index a4841bad9df9..4a59ec2c0ff7 100644
--- a/bin/named/include/named/tsigconf.h
+++ b/bin/named/include/named/tsigconf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tsigconf.h,v 1.16 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: tsigconf.h,v 1.18 2009-06-11 23:47:55 tbox Exp $ */
#ifndef NS_TSIGCONF_H
#define NS_TSIGCONF_H 1
@@ -36,8 +36,9 @@ ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
*
* Requires:
* \li 'config' is not NULL.
+ * \li 'vconfig' is not NULL.
* \li 'mctx' is not NULL
- * \li 'ring' is not NULL, and '*ring' is NULL
+ * \li 'ringp' is not NULL, and '*ringp' is NULL
*
* Returns:
* \li ISC_R_SUCCESS
diff --git a/bin/named/include/named/types.h b/bin/named/include/named/types.h
index b0729a787ba7..96c4c012b71f 100644
--- a/bin/named/include/named/types.h
+++ b/bin/named/include/named/types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.29 2008-01-17 23:46:59 tbox Exp $ */
+/* $Id: types.h,v 1.31 2009-01-09 23:47:45 tbox Exp $ */
#ifndef NAMED_TYPES_H
#define NAMED_TYPES_H 1
@@ -24,6 +24,8 @@
#include <dns/types.h>
+typedef struct ns_cache ns_cache_t;
+typedef ISC_LIST(ns_cache_t) ns_cachelist_t;
typedef struct ns_client ns_client_t;
typedef struct ns_clientmgr ns_clientmgr_t;
typedef struct ns_query ns_query_t;
diff --git a/bin/named/include/named/zoneconf.h b/bin/named/include/named/zoneconf.h
index ab84c84515bf..65cf72f9f3ac 100644
--- a/bin/named/include/named/zoneconf.h
+++ b/bin/named/include/named/zoneconf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zoneconf.h,v 1.26 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: zoneconf.h,v 1.28 2010-12-20 23:47:20 tbox Exp $ */
#ifndef NS_ZONECONF_H
#define NS_ZONECONF_H 1
@@ -58,6 +58,21 @@ ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig);
* and recreated, return ISC_FALSE.
*/
+
+isc_result_t
+ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
+ dns_rdataclass_t rdclass, dns_name_t *name);
+/*%>
+ * configure a DLZ zone, setting up the database methods and calling
+ * postload to load the origin values
+ *
+ * Require:
+ * \li 'dlzdatabase' to be a valid dlz database
+ * \li 'zone' to be initialized.
+ * \li 'rdclass' to be a valid rdataclass
+ * \li 'name' to be a valid zone origin name
+ */
+
ISC_LANG_ENDDECLS
#endif /* NS_ZONECONF_H */
diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c
index fad32137f6df..e99d3b9cfe38 100644
--- a/bin/named/interfacemgr.c
+++ b/bin/named/interfacemgr.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: interfacemgr.c,v 1.93.70.2 2009-01-18 23:47:34 tbox Exp $ */
+/* $Id: interfacemgr.c,v 1.95 2009-01-17 23:47:42 tbox Exp $ */
/*! \file */
diff --git a/bin/named/log.c b/bin/named/log.c
index 867ad56b8c51..5d1c942074ca 100644
--- a/bin/named/log.c
+++ b/bin/named/log.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: log.c,v 1.46.334.3 2009-01-07 01:50:14 jinmei Exp $ */
+/* $Id: log.c,v 1.49 2009-01-07 01:46:40 jinmei Exp $ */
/*! \file */
diff --git a/bin/named/lwdgabn.c b/bin/named/lwdgabn.c
index 66d724624a5c..6a609c9acc4f 100644
--- a/bin/named/lwdgabn.c
+++ b/bin/named/lwdgabn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lwdgabn.c,v 1.22 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: lwdgabn.c,v 1.24 2009-09-02 23:48:01 tbox Exp $ */
/*! \file */
@@ -619,7 +619,7 @@ ns_lwdclient_processgabn(ns_lwdclient_t *client, lwres_buffer_t *b) {
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);
+ &namebuf, NULL, 0, NULL);
if (result != ISC_R_SUCCESS)
goto out;
ns_lwsearchctx_init(&client->searchctx,
diff --git a/bin/named/lwdgrbn.c b/bin/named/lwdgrbn.c
index bf29a481c488..22b62c625c12 100644
--- a/bin/named/lwdgrbn.c
+++ b/bin/named/lwdgrbn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lwdgrbn.c,v 1.20 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: lwdgrbn.c,v 1.22 2009-09-02 23:48:01 tbox Exp $ */
/*! \file */
@@ -472,7 +472,7 @@ ns_lwdclient_processgrbn(ns_lwdclient_t *client, lwres_buffer_t *b) {
dns_fixedname_init(&client->query_name);
result = dns_name_fromtext(dns_fixedname_name(&client->query_name),
- &namebuf, NULL, ISC_FALSE, NULL);
+ &namebuf, NULL, 0, NULL);
if (result != ISC_R_SUCCESS)
goto out;
ns_lwsearchctx_init(&client->searchctx,
diff --git a/bin/named/lwresd.8 b/bin/named/lwresd.8
index d1e760d10887..30dfbd55e783 100644
--- a/bin/named/lwresd.8
+++ b/bin/named/lwresd.8
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwresd.8,v 1.29.14.2 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwresd.8,v 1.31 2009-07-11 01:12:45 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/bin/named/lwresd.c b/bin/named/lwresd.c
index b7dc0af1038f..ad3670960cb1 100644
--- a/bin/named/lwresd.c
+++ b/bin/named/lwresd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lwresd.c,v 1.58 2008-07-23 23:27:54 marka Exp $ */
+/* $Id: lwresd.c,v 1.60 2009-09-02 23:48:01 tbox Exp $ */
/*! \file
* \brief
@@ -372,8 +372,7 @@ ns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres,
strlen(searchstr));
isc_buffer_add(&namebuf, strlen(searchstr));
result = dns_name_fromtext(name, &namebuf,
- dns_rootname, ISC_FALSE,
- NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx,
NS_LOGCATEGORY_GENERAL,
diff --git a/bin/named/lwresd.docbook b/bin/named/lwresd.docbook
index f8e1500d0479..934b5da21dcc 100644
--- a/bin/named/lwresd.docbook
+++ b/bin/named/lwresd.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwresd.docbook,v 1.18.14.2 2009-01-22 23:47:05 tbox Exp $ -->
+<!-- $Id: lwresd.docbook,v 1.20 2009-01-20 23:47:56 tbox Exp $ -->
<refentry>
<refentryinfo>
<date>June 30, 2000</date>
diff --git a/bin/named/lwresd.html b/bin/named/lwresd.html
index dec47caa2b86..223b1c2c5250 100644
--- a/bin/named/lwresd.html
+++ b/bin/named/lwresd.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwresd.html,v 1.25.14.2 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwresd.html,v 1.27 2009-07-11 01:12:45 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/bin/named/main.c b/bin/named/main.c
index a1d94fff80d5..84d86b146f4c 100644
--- a/bin/named/main.c
+++ b/bin/named/main.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: main.c,v 1.166.34.7 2010-09-15 12:16:49 marka Exp $ */
+/* $Id: main.c,v 1.180 2010-12-22 03:59:02 marka Exp $ */
/*! \file */
@@ -26,6 +26,7 @@
#include <string.h>
#include <isc/app.h>
+#include <isc/backtrace.h>
#include <isc/commandline.h>
#include <isc/dir.h>
#include <isc/entropy.h>
@@ -69,6 +70,12 @@
#include <named/ns_smf_globals.h>
#endif
+#ifdef OPENSSL
+#include <openssl/opensslv.h>
+#endif
+#ifdef HAVE_LIBXML2
+#include <libxml/xmlversion.h>
+#endif
/*
* Include header files for database drivers here.
*/
@@ -81,12 +88,20 @@
#include <dlz/dlz_drivers.h>
#endif
+/*
+ * The maximum number of stack frames to dump on assertion failure.
+ */
+#ifndef BACKTRACE_MAXFRAME
+#define BACKTRACE_MAXFRAME 128
+#endif
+
static isc_boolean_t want_stats = ISC_FALSE;
static char program_name[ISC_DIR_NAMEMAX] = "named";
static char absolute_conffile[ISC_DIR_PATHMAX];
static char saved_command_line[512];
static char version[512];
static unsigned int maxsocks = 0;
+static int maxudp = 0;
void
ns_main_earlywarning(const char *format, ...) {
@@ -129,10 +144,20 @@ ns_main_earlyfatal(const char *format, ...) {
exit(1);
}
+ISC_PLATFORM_NORETURN_PRE static void
+assertion_failed(const char *file, int line, isc_assertiontype_t type,
+ const char *cond) ISC_PLATFORM_NORETURN_POST;
+
static void
assertion_failed(const char *file, int line, isc_assertiontype_t type,
const char *cond)
{
+ void *tracebuf[BACKTRACE_MAXFRAME];
+ int i, nframes;
+ isc_result_t result;
+ const char *logsuffix = "";
+ const char *fname;
+
/*
* Handle assertion failures.
*/
@@ -144,10 +169,40 @@ assertion_failed(const char *file, int line, isc_assertiontype_t type,
*/
isc_assertion_setcallback(NULL);
+ result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME,
+ &nframes);
+ if (result == ISC_R_SUCCESS && nframes > 0)
+ logsuffix = ", back trace";
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);
+ "%s:%d: %s(%s) failed%s", file, line,
+ isc_assertion_typetotext(type), cond, logsuffix);
+ if (result == ISC_R_SUCCESS) {
+ for (i = 0; i < nframes; i++) {
+ unsigned long offset;
+
+ fname = NULL;
+ result = isc_backtrace_getsymbol(tracebuf[i],
+ &fname,
+ &offset);
+ if (result == ISC_R_SUCCESS) {
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN,
+ ISC_LOG_CRITICAL,
+ "#%d %p in %s()+0x%lx", i,
+ tracebuf[i], fname,
+ offset);
+ } else {
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN,
+ ISC_LOG_CRITICAL,
+ "#%d %p in ??", i,
+ tracebuf[i]);
+ }
+ }
+ }
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL,
"exiting (due to assertion failure)");
@@ -162,9 +217,10 @@ assertion_failed(const char *file, int line, isc_assertiontype_t type,
exit(1);
}
-static void
+ISC_PLATFORM_NORETURN_PRE static void
library_fatal_error(const char *file, int line, const char *format,
- va_list args) ISC_FORMAT_PRINTF(3, 0);
+ va_list args)
+ISC_FORMAT_PRINTF(3, 0) ISC_PLATFORM_NORETURN_POST;
static void
library_fatal_error(const char *file, int line, const char *format,
@@ -248,8 +304,9 @@ usage(void) {
}
fprintf(stderr,
"usage: named [-4|-6] [-c conffile] [-d debuglevel] "
- "[-f|-g] [-n number_of_cpus]\n"
- " [-p port] [-s] [-t chrootdir] [-u username]\n"
+ "[-E engine] [-f|-g]\n"
+ " [-n number_of_cpus] [-p port] [-s] "
+ "[-t chrootdir] [-u username]\n"
" [-m {usage|trace|record|size|mctx}]\n");
}
@@ -358,7 +415,7 @@ parse_command_line(int argc, char *argv[]) {
isc_commandline_errprint = ISC_FALSE;
while ((ch = isc_commandline_parse(argc, argv,
- "46c:C:d:fgi:lm:n:N:p:P:"
+ "46c:C:d:E:fFgi:lm:n:N:p:P:"
"sS:t:T:u:vVx:")) != -1) {
switch (ch) {
case '4':
@@ -394,6 +451,9 @@ parse_command_line(int argc, char *argv[]) {
ns_g_debuglevel = parse_int(isc_commandline_argument,
"debug level");
break;
+ case 'E':
+ ns_g_engine = isc_commandline_argument;
+ break;
case 'f':
ns_g_foreground = ISC_TRUE;
break;
@@ -451,12 +511,16 @@ parse_command_line(int argc, char *argv[]) {
* clienttest: make clients single shot with their
* own memory context.
*/
- if (strcmp(isc_commandline_argument, "clienttest") == 0)
+ if (!strcmp(isc_commandline_argument, "clienttest"))
ns_g_clienttest = ISC_TRUE;
else if (!strcmp(isc_commandline_argument, "nosoa"))
ns_g_nosoa = ISC_TRUE;
else if (!strcmp(isc_commandline_argument, "noaa"))
ns_g_noaa = ISC_TRUE;
+ else if (!strcmp(isc_commandline_argument, "maxudp512"))
+ maxudp = 512;
+ else if (!strcmp(isc_commandline_argument, "maxudp1460"))
+ maxudp = 1460;
else
fprintf(stderr, "unknown -T flag '%s\n",
isc_commandline_argument);
@@ -470,13 +534,25 @@ parse_command_line(int argc, char *argv[]) {
case 'V':
printf("BIND %s built with %s\n", ns_g_version,
ns_g_configargs);
+#ifdef OPENSSL
+ printf("using OpenSSL version: %s\n",
+ OPENSSL_VERSION_TEXT);
+#endif
+#ifdef HAVE_LIBXML2
+ printf("using libxml2 version: %s\n",
+ LIBXML_DOTTED_VERSION);
+#endif
exit(0);
+ case 'F':
+ /* Reserved for FIPS mode */
+ /* FALLTHROUGH */
case '?':
usage();
if (isc_commandline_option == '?')
exit(0);
ns_main_earlyfatal("unknown option '-%c'",
isc_commandline_option);
+ /* FALLTHROUGH */
default:
ns_main_earlyfatal("parsing options returned %d", ch);
}
@@ -529,6 +605,7 @@ create_managers(void) {
isc_result_totext(result));
return (ISC_R_UNEXPECTED);
}
+ isc__socketmgr_maxudp(ns_g_socketmgr, maxudp);
result = isc_socketmgr_getmaxsockets(ns_g_socketmgr, &socks);
if (result == ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
@@ -579,6 +656,34 @@ destroy_managers(void) {
}
static void
+dump_symboltable() {
+ int i;
+ isc_result_t result;
+ const char *fname;
+ const void *addr;
+
+ if (isc__backtrace_nsymbols == 0)
+ return;
+
+ if (!isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(99)))
+ return;
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
+ ISC_LOG_DEBUG(99), "Symbol table:");
+
+ for (i = 0, result = ISC_R_SUCCESS; result == ISC_R_SUCCESS; i++) {
+ addr = NULL;
+ fname = NULL;
+ result = isc_backtrace_getsymbolfromindex(i, &addr, &fname);
+ if (result == ISC_R_SUCCESS) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(99),
+ "[%d] %p %s", i, addr, fname);
+ }
+ }
+}
+
+static void
setup(void) {
isc_result_t result;
isc_resourcevalue_t old_openfiles;
@@ -685,6 +790,8 @@ setup(void) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
ISC_LOG_NOTICE, "built with %s", ns_g_configargs);
+ dump_symboltable();
+
/*
* Get the initial resource limits.
*/
@@ -723,8 +830,8 @@ setup(void) {
absolute_conffile,
sizeof(absolute_conffile));
if (result != ISC_R_SUCCESS)
- ns_main_earlyfatal("could not construct absolute path of "
- "configuration file: %s",
+ ns_main_earlyfatal("could not construct absolute path "
+ "of configuration file: %s",
isc_result_totext(result));
ns_g_conffile = absolute_conffile;
}
@@ -896,6 +1003,9 @@ main(int argc, char *argv[]) {
if (strcmp(program_name, "lwresd") == 0)
ns_g_lwresdonly = ISC_TRUE;
+ if (result != ISC_R_SUCCESS)
+ ns_main_earlyfatal("failed to build internal symbol table");
+
isc_assertion_setcallback(assertion_failed);
isc_error_setfatal(library_fatal_error);
isc_error_setunexpected(library_unexpected_error);
diff --git a/bin/named/named.8 b/bin/named/named.8
index 90782ed8171e..23805b04a935 100644
--- a/bin/named/named.8
+++ b/bin/named/named.8
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: named.8,v 1.38.14.2 2009-12-03 05:06:38 tbox Exp $
+.\" $Id: named.8,v 1.41 2009-10-06 01:14:41 tbox Exp $
.\"
.hy 0
.ad l
@@ -33,7 +33,7 @@
named \- Internet domain name server
.SH "SYNOPSIS"
.HP 6
-\fBnamed\fR [\fB\-4\fR] [\fB\-6\fR] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-S\ \fR\fB\fI#max\-socks\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-V\fR] [\fB\-x\ \fR\fB\fIcache\-file\fR\fR]
+\fBnamed\fR [\fB\-4\fR] [\fB\-6\fR] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-E\ \fR\fB\fIengine\-name\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-S\ \fR\fB\fI#max\-socks\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-V\fR] [\fB\-x\ \fR\fB\fIcache\-file\fR\fR]
.SH "DESCRIPTION"
.PP
\fBnamed\fR
@@ -83,6 +83,13 @@ Set the daemon's debug level to
become more verbose as the debug level increases.
.RE
.PP
+\-E \fIengine\-name\fR
+.RS 4
+Use a crypto hardware (OpenSSL engine) for the crypto operations it supports, for instance re\-signing with private keys from a secure key store. When compiled with PKCS#11 support
+\fIengine\-name\fR
+defaults to pkcs11, the empty name resets it to no engine.
+.RE
+.PP
\-f
.RS 4
Run the server in the foreground (i.e. do not daemonize).
diff --git a/bin/named/named.conf.5 b/bin/named/named.conf.5
index cd0d4ad75543..9dc7002b09c9 100644
--- a/bin/named/named.conf.5
+++ b/bin/named/named.conf.5
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: named.conf.5,v 1.36.48.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: named.conf.5,v 1.44.12.1 2011-02-03 12:29:12 tbox Exp $
.\"
.hy 0
.ad l
@@ -102,6 +102,15 @@ trusted\-keys {
};
.fi
.RE
+.SH "MANAGED\-KEYS"
+.sp
+.RS 4
+.nf
+managed\-keys {
+ \fIdomain_name\fR \fBinitial\-key\fR \fIflags\fR \fIprotocol\fR \fIalgorithm\fR \fIkey\fR; ...
+};
+.fi
+.RE
.SH "CONTROLS"
.sp
.RS 4
@@ -186,6 +195,7 @@ options {
tcp\-listen\-queue \fIinteger\fR;
tkey\-dhkey \fIquoted_string\fR \fIinteger\fR;
tkey\-gssapi\-credential \fIquoted_string\fR;
+ tkey\-gssapi\-keytab \fIquoted_string\fR;
tkey\-domain \fIquoted_string\fR;
transfers\-per\-ns \fIinteger\fR;
transfers\-in \fIinteger\fR;
@@ -214,6 +224,7 @@ options {
queryport\-pool\-ports \fIinteger\fR;
queryport\-pool\-updateinterval \fIinteger\fR;
cleaning\-interval \fIinteger\fR;
+ resolver\-query\-timeout \fIinteger\fR;
min\-roots \fIinteger\fR; // not implemented
lame\-ttl \fIinteger\fR;
max\-ncache\-ttl \fIinteger\fR;
@@ -244,8 +255,19 @@ options {
dnssec\-enable \fIboolean\fR;
dnssec\-validation \fIboolean\fR;
dnssec\-lookaside \fIstring\fR trust\-anchor \fIstring\fR;
+ dnssec\-lookaside ( \fIauto\fR | \fIdomain\fR trust\-anchor \fIdomain\fR );
dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR;
dnssec\-accept\-expired \fIboolean\fR;
+ dns64\-server \fIstring\fR;
+ dns64\-contact \fIstring\fR;
+ dns64 \fIprefix\fR {
+ clients { <replacable>acl</replacable>; };
+ exclude { <replacable>acl</replacable>; };
+ mapped { <replacable>acl</replacable>; };
+ break\-dnssec \fIboolean\fR;
+ recursive\-only \fIboolean\fR;
+ suffix \fIipv6_address\fR;
+ };
empty\-server \fIstring\fR;
empty\-contact \fIstring\fR;
empty\-zones\-enable \fIboolean\fR;
@@ -260,6 +282,7 @@ options {
allow\-update { \fIaddress_match_element\fR; ... };
allow\-update\-forwarding { \fIaddress_match_element\fR; ... };
update\-check\-ksk \fIboolean\fR;
+ dnssec\-dnskey\-kskonly \fIboolean\fR;
masterfile\-format ( text | raw );
notify \fInotifytype\fR;
notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ];
@@ -299,9 +322,18 @@ options {
use\-alt\-transfer\-source \fIboolean\fR;
zone\-statistics \fIboolean\fR;
key\-directory \fIquoted_string\fR;
+ managed\-keys\-directory \fIquoted_string\fR;
+ auto\-dnssec \fBallow\fR|\fBmaintain\fR|\fBcreate\fR|\fBoff\fR;
try\-tcp\-refresh \fIboolean\fR;
zero\-no\-soa\-ttl \fIboolean\fR;
zero\-no\-soa\-ttl\-cache \fIboolean\fR;
+ dnssec\-secure\-to\-insecure \fIboolean\fR;
+ deny\-answer\-addresses {
+ \fIaddress_match_list\fR
+ } [ except\-from { \fInamelist\fR } ];
+ deny\-answer\-aliases {
+ \fInamelist\fR
+ } [ except\-from { \fInamelist\fR } ];
nsec3\-test\-zone \fIboolean\fR; // testing only
allow\-v6\-synthesis { \fIaddress_match_element\fR; ... }; // obsolete
deallocate\-on\-exit \fIboolean\fR; // obsolete
@@ -337,7 +369,8 @@ view \fIstring\fR \fIoptional_class\fR {
...
};
trusted\-keys {
- \fIstring\fR \fIinteger\fR \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; ...
+ \fIstring\fR \fIinteger\fR \fIinteger\fR \fIinteger\fR \fIquoted_string\fR;
+ [...]
};
allow\-recursion { \fIaddress_match_element\fR; ... };
allow\-recursion\-on { \fIaddress_match_element\fR; ... };
@@ -361,6 +394,7 @@ view \fIstring\fR \fIoptional_class\fR {
queryport\-pool\-ports \fIinteger\fR;
queryport\-pool\-updateinterval \fIinteger\fR;
cleaning\-interval \fIinteger\fR;
+ resolver\-query\-timeout \fIinteger\fR;
min\-roots \fIinteger\fR; // not implemented
lame\-ttl \fIinteger\fR;
max\-ncache\-ttl \fIinteger\fR;
@@ -393,6 +427,16 @@ view \fIstring\fR \fIoptional_class\fR {
dnssec\-lookaside \fIstring\fR trust\-anchor \fIstring\fR;
dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR;
dnssec\-accept\-expired \fIboolean\fR;
+ dns64\-server \fIstring\fR;
+ dns64\-contact \fIstring\fR;
+ dns64 \fIprefix\fR {
+ clients { <replacable>acl</replacable>; };
+ exclude { <replacable>acl</replacable>; };
+ mapped { <replacable>acl</replacable>; };
+ break\-dnssec \fIboolean\fR;
+ recursive\-only \fIboolean\fR;
+ suffix \fIipv6_address\fR;
+ };
empty\-server \fIstring\fR;
empty\-contact \fIstring\fR;
empty\-zones\-enable \fIboolean\fR;
@@ -407,6 +451,7 @@ view \fIstring\fR \fIoptional_class\fR {
allow\-update { \fIaddress_match_element\fR; ... };
allow\-update\-forwarding { \fIaddress_match_element\fR; ... };
update\-check\-ksk \fIboolean\fR;
+ dnssec\-dnskey\-kskonly \fIboolean\fR;
masterfile\-format ( text | raw );
notify \fInotifytype\fR;
notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ];
@@ -445,6 +490,7 @@ view \fIstring\fR \fIoptional_class\fR {
key\-directory \fIquoted_string\fR;
zero\-no\-soa\-ttl \fIboolean\fR;
zero\-no\-soa\-ttl\-cache \fIboolean\fR;
+ dnssec\-secure\-to\-insecure \fIboolean\fR;
allow\-v6\-synthesis { \fIaddress_match_element\fR; ... }; // obsolete
fetch\-glue \fIboolean\fR; // obsolete
maintain\-ixfr\-base \fIboolean\fR; // obsolete
@@ -476,19 +522,22 @@ zone \fIstring\fR \fIoptional_class\fR {
ixfr\-from\-differences \fIboolean\fR;
journal \fIquoted_string\fR;
zero\-no\-soa\-ttl \fIboolean\fR;
+ dnssec\-secure\-to\-insecure \fIboolean\fR;
allow\-query { \fIaddress_match_element\fR; ... };
allow\-query\-on { \fIaddress_match_element\fR; ... };
allow\-transfer { \fIaddress_match_element\fR; ... };
allow\-update { \fIaddress_match_element\fR; ... };
allow\-update\-forwarding { \fIaddress_match_element\fR; ... };
- update\-policy {
- ( grant | deny ) \fIstring\fR
+ update\-policy \fIlocal\fR | \fI {
+ ( grant | deny ) \fR\fI\fIstring\fR\fR\fI
( name | subdomain | wildcard | self | selfsub | selfwild |
krb5\-self | ms\-self | krb5\-subdomain | ms\-subdomain |
- tcp\-self | 6to4\-self ) \fIstring\fR
- \fIrrtypelist\fR; ...
- };
+ tcp\-self | zonesub | 6to4\-self ) \fR\fI\fIstring\fR\fR\fI
+ \fR\fI\fIrrtypelist\fR\fR\fI;
+ \fR\fI[...]\fR\fI
+ }\fR;
update\-check\-ksk \fIboolean\fR;
+ dnssec\-dnskey\-kskonly \fIboolean\fR;
masterfile\-format ( text | raw );
notify \fInotifytype\fR;
notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ];
@@ -544,5 +593,5 @@ zone \fIstring\fR \fIoptional_class\fR {
\fBrndc\fR(8),
BIND 9 Administrator Reference Manual.
.SH "COPYRIGHT"
-Copyright \(co 2004\-2008 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2004\-2011 Internet Systems Consortium, Inc. ("ISC")
.br
diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook
index d98e2899295a..962eaaa0e2bd 100644
--- a/bin/named/named.conf.docbook
+++ b/bin/named/named.conf.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named.conf.docbook,v 1.39 2008-09-24 02:46:21 marka Exp $ -->
+<!-- $Id: named.conf.docbook,v 1.49.14.1 2011-02-03 05:50:05 marka Exp $ -->
<refentry>
<refentryinfo>
<date>Aug 13, 2004</date>
@@ -41,6 +41,9 @@
<year>2006</year>
<year>2007</year>
<year>2008</year>
+ <year>2009</year>
+ <year>2010</year>
+ <year>2011</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
@@ -132,6 +135,15 @@ trusted-keys {
</refsect1>
<refsect1>
+ <title>MANAGED-KEYS</title>
+ <literallayout>
+managed-keys {
+ <replaceable>domain_name</replaceable> <constant>initial-key</constant> <replaceable>flags</replaceable> <replaceable>protocol</replaceable> <replaceable>algorithm</replaceable> <replaceable>key</replaceable>; ...
+};
+</literallayout>
+ </refsect1>
+
+ <refsect1>
<title>CONTROLS</title>
<literallayout>
controls {
@@ -214,6 +226,7 @@ options {
tcp-listen-queue <replaceable>integer</replaceable>;
tkey-dhkey <replaceable>quoted_string</replaceable> <replaceable>integer</replaceable>;
tkey-gssapi-credential <replaceable>quoted_string</replaceable>;
+ tkey-gssapi-keytab <replaceable>quoted_string</replaceable>;
tkey-domain <replaceable>quoted_string</replaceable>;
transfers-per-ns <replaceable>integer</replaceable>;
transfers-in <replaceable>integer</replaceable>;
@@ -242,6 +255,7 @@ options {
queryport-pool-ports <replaceable>integer</replaceable>;
queryport-pool-updateinterval <replaceable>integer</replaceable>;
cleaning-interval <replaceable>integer</replaceable>;
+ resolver-query-timeout <replaceable>integer</replaceable>;
min-roots <replaceable>integer</replaceable>; // not implemented
lame-ttl <replaceable>integer</replaceable>;
max-ncache-ttl <replaceable>integer</replaceable>;
@@ -272,9 +286,21 @@ options {
dnssec-enable <replaceable>boolean</replaceable>;
dnssec-validation <replaceable>boolean</replaceable>;
dnssec-lookaside <replaceable>string</replaceable> trust-anchor <replaceable>string</replaceable>;
+ dnssec-lookaside ( <replaceable>auto</replaceable> | <replaceable>domain</replaceable> trust-anchor <replaceable>domain</replaceable> );
dnssec-must-be-secure <replaceable>string</replaceable> <replaceable>boolean</replaceable>;
dnssec-accept-expired <replaceable>boolean</replaceable>;
+ dns64-server <replaceable>string</replaceable>;
+ dns64-contact <replaceable>string</replaceable>;
+ dns64 <replaceable>prefix</replaceable> {
+ clients { <replacable>acl</replacable>; };
+ exclude { <replacable>acl</replacable>; };
+ mapped { <replacable>acl</replacable>; };
+ break-dnssec <replaceable>boolean</replaceable>;
+ recursive-only <replaceable>boolean</replaceable>;
+ suffix <replaceable>ipv6_address</replaceable>;
+ };
+
empty-server <replaceable>string</replaceable>;
empty-contact <replaceable>string</replaceable>;
empty-zones-enable <replaceable>boolean</replaceable>;
@@ -291,6 +317,7 @@ options {
allow-update { <replaceable>address_match_element</replaceable>; ... };
allow-update-forwarding { <replaceable>address_match_element</replaceable>; ... };
update-check-ksk <replaceable>boolean</replaceable>;
+ dnssec-dnskey-kskonly <replaceable>boolean</replaceable>;
masterfile-format ( text | raw );
notify <replaceable>notifytype</replaceable>;
@@ -337,9 +364,18 @@ options {
zone-statistics <replaceable>boolean</replaceable>;
key-directory <replaceable>quoted_string</replaceable>;
+ managed-keys-directory <replaceable>quoted_string</replaceable>;
+ auto-dnssec <constant>allow</constant>|<constant>maintain</constant>|<constant>create</constant>|<constant>off</constant>;
try-tcp-refresh <replaceable>boolean</replaceable>;
zero-no-soa-ttl <replaceable>boolean</replaceable>;
zero-no-soa-ttl-cache <replaceable>boolean</replaceable>;
+ dnssec-secure-to-insecure <replaceable>boolean</replaceable>;
+ deny-answer-addresses {
+ <replaceable>address_match_list</replaceable>
+ } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;
+ deny-answer-aliases {
+ <replaceable>namelist</replaceable>
+ } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;
nsec3-test-zone <replaceable>boolean</replaceable>; // testing only
@@ -381,7 +417,8 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
};
trusted-keys {
- <replaceable>string</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>quoted_string</replaceable>; ...
+ <replaceable>string</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>quoted_string</replaceable>;
+ <optional>...</optional>
};
allow-recursion { <replaceable>address_match_element</replaceable>; ... };
@@ -406,6 +443,7 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
queryport-pool-ports <replaceable>integer</replaceable>;
queryport-pool-updateinterval <replaceable>integer</replaceable>;
cleaning-interval <replaceable>integer</replaceable>;
+ resolver-query-timeout <replaceable>integer</replaceable>;
min-roots <replaceable>integer</replaceable>; // not implemented
lame-ttl <replaceable>integer</replaceable>;
max-ncache-ttl <replaceable>integer</replaceable>;
@@ -439,6 +477,17 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
dnssec-must-be-secure <replaceable>string</replaceable> <replaceable>boolean</replaceable>;
dnssec-accept-expired <replaceable>boolean</replaceable>;
+ dns64-server <replaceable>string</replaceable>;
+ dns64-contact <replaceable>string</replaceable>;
+ dns64 <replaceable>prefix</replaceable> {
+ clients { <replacable>acl</replacable>; };
+ exclude { <replacable>acl</replacable>; };
+ mapped { <replacable>acl</replacable>; };
+ break-dnssec <replaceable>boolean</replaceable>;
+ recursive-only <replaceable>boolean</replaceable>;
+ suffix <replaceable>ipv6_address</replaceable>;
+ };
+
empty-server <replaceable>string</replaceable>;
empty-contact <replaceable>string</replaceable>;
empty-zones-enable <replaceable>boolean</replaceable>;
@@ -455,6 +504,7 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
allow-update { <replaceable>address_match_element</replaceable>; ... };
allow-update-forwarding { <replaceable>address_match_element</replaceable>; ... };
update-check-ksk <replaceable>boolean</replaceable>;
+ dnssec-dnskey-kskonly <replaceable>boolean</replaceable>;
masterfile-format ( text | raw );
notify <replaceable>notifytype</replaceable>;
@@ -499,6 +549,7 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
key-directory <replaceable>quoted_string</replaceable>;
zero-no-soa-ttl <replaceable>boolean</replaceable>;
zero-no-soa-ttl-cache <replaceable>boolean</replaceable>;
+ dnssec-secure-to-insecure <replaceable>boolean</replaceable>;
allow-v6-synthesis { <replaceable>address_match_element</replaceable>; ... }; // obsolete
fetch-glue <replaceable>boolean</replaceable>; // obsolete
@@ -533,20 +584,23 @@ zone <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
ixfr-from-differences <replaceable>boolean</replaceable>;
journal <replaceable>quoted_string</replaceable>;
zero-no-soa-ttl <replaceable>boolean</replaceable>;
+ dnssec-secure-to-insecure <replaceable>boolean</replaceable>;
allow-query { <replaceable>address_match_element</replaceable>; ... };
allow-query-on { <replaceable>address_match_element</replaceable>; ... };
allow-transfer { <replaceable>address_match_element</replaceable>; ... };
allow-update { <replaceable>address_match_element</replaceable>; ... };
allow-update-forwarding { <replaceable>address_match_element</replaceable>; ... };
- update-policy {
+ update-policy <replaceable>local</replaceable> | <replaceable> {
( grant | deny ) <replaceable>string</replaceable>
( name | subdomain | wildcard | self | selfsub | selfwild |
krb5-self | ms-self | krb5-subdomain | ms-subdomain |
- tcp-self | 6to4-self ) <replaceable>string</replaceable>
- <replaceable>rrtypelist</replaceable>; ...
- };
+ tcp-self | zonesub | 6to4-self ) <replaceable>string</replaceable>
+ <replaceable>rrtypelist</replaceable>;
+ <optional>...</optional>
+ }</replaceable>;
update-check-ksk <replaceable>boolean</replaceable>;
+ dnssec-dnskey-kskonly <replaceable>boolean</replaceable>;
masterfile-format ( text | raw );
notify <replaceable>notifytype</replaceable>;
diff --git a/bin/named/named.conf.html b/bin/named/named.conf.html
index fccad183f9e6..f20e411f45b0 100644
--- a/bin/named/named.conf.html
+++ b/bin/named/named.conf.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
@@ -13,7 +13,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named.conf.html,v 1.45.48.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: named.conf.html,v 1.53.12.1 2011-02-03 12:29:12 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -31,7 +31,7 @@
<div class="cmdsynopsis"><p><code class="command">named.conf</code> </p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543342"></a><h2>DESCRIPTION</h2>
+<a name="id2543352"></a><h2>DESCRIPTION</h2>
<p><code class="filename">named.conf</code> is the configuration file
for
<span><strong class="command">named</strong></span>. Statements are enclosed
@@ -50,14 +50,14 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543370"></a><h2>ACL</h2>
+<a name="id2543380"></a><h2>ACL</h2>
<div class="literallayout"><p><br>
acl <em class="replaceable"><code>string</code></em> { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543386"></a><h2>KEY</h2>
+<a name="id2543396"></a><h2>KEY</h2>
<div class="literallayout"><p><br>
key <em class="replaceable"><code>domain_name</code></em> {<br>
algorithm <em class="replaceable"><code>string</code></em>;<br>
@@ -66,7 +66,7 @@ key <em class="replaceable"><code>domain_name</code></em> {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543405"></a><h2>MASTERS</h2>
+<a name="id2543415"></a><h2>MASTERS</h2>
<div class="literallayout"><p><br>
masters <em class="replaceable"><code>string</code></em> [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br>
( <em class="replaceable"><code>masters</code></em> | <em class="replaceable"><code>ipv4_address</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] |<br>
@@ -75,7 +75,7 @@ masters <em class="replaceable"><code>string</code></em> [<span class="optional"
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543451"></a><h2>SERVER</h2>
+<a name="id2543461"></a><h2>SERVER</h2>
<div class="literallayout"><p><br>
server ( <em class="replaceable"><code>ipv4_address[<span class="optional">/prefixlen</span>]</code></em> | <em class="replaceable"><code>ipv6_address[<span class="optional">/prefixlen</span>]</code></em> ) {<br>
bogus <em class="replaceable"><code>boolean</code></em>;<br>
@@ -97,7 +97,7 @@ server ( <em class="replaceable"><code>ipv4_address[<span class="optional">/pref
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543520"></a><h2>TRUSTED-KEYS</h2>
+<a name="id2543529"></a><h2>TRUSTED-KEYS</h2>
<div class="literallayout"><p><br>
trusted-keys {<br>
<em class="replaceable"><code>domain_name</code></em> <em class="replaceable"><code>flags</code></em> <em class="replaceable"><code>protocol</code></em> <em class="replaceable"><code>algorithm</code></em> <em class="replaceable"><code>key</code></em>; ... <br>
@@ -105,7 +105,15 @@ trusted-keys {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543545"></a><h2>CONTROLS</h2>
+<a name="id2543555"></a><h2>MANAGED-KEYS</h2>
+<div class="literallayout"><p><br>
+managed-keys {<br>
+ <em class="replaceable"><code>domain_name</code></em> <code class="constant">initial-key</code> <em class="replaceable"><code>flags</code></em> <em class="replaceable"><code>protocol</code></em> <em class="replaceable"><code>algorithm</code></em> <em class="replaceable"><code>key</code></em>; ... <br>
+};<br>
+</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543584"></a><h2>CONTROLS</h2>
<div class="literallayout"><p><br>
controls {<br>
inet ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> | * )<br>
@@ -117,7 +125,7 @@ controls {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543580"></a><h2>LOGGING</h2>
+<a name="id2543619"></a><h2>LOGGING</h2>
<div class="literallayout"><p><br>
logging {<br>
channel <em class="replaceable"><code>string</code></em> {<br>
@@ -135,7 +143,7 @@ logging {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543619"></a><h2>LWRES</h2>
+<a name="id2543657"></a><h2>LWRES</h2>
<div class="literallayout"><p><br>
lwres {<br>
listen-on [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br>
@@ -148,7 +156,7 @@ lwres {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543660"></a><h2>OPTIONS</h2>
+<a name="id2543699"></a><h2>OPTIONS</h2>
<div class="literallayout"><p><br>
options {<br>
avoid-v4-udp-ports { <em class="replaceable"><code>port</code></em>; ... };<br>
@@ -184,6 +192,7 @@ options {<br>
tcp-listen-queue <em class="replaceable"><code>integer</code></em>;<br>
tkey-dhkey <em class="replaceable"><code>quoted_string</code></em> <em class="replaceable"><code>integer</code></em>;<br>
tkey-gssapi-credential <em class="replaceable"><code>quoted_string</code></em>;<br>
+ tkey-gssapi-keytab <em class="replaceable"><code>quoted_string</code></em>;<br>
tkey-domain <em class="replaceable"><code>quoted_string</code></em>;<br>
transfers-per-ns <em class="replaceable"><code>integer</code></em>;<br>
transfers-in <em class="replaceable"><code>integer</code></em>;<br>
@@ -212,6 +221,7 @@ options {<br>
queryport-pool-ports <em class="replaceable"><code>integer</code></em>;<br>
queryport-pool-updateinterval <em class="replaceable"><code>integer</code></em>;<br>
cleaning-interval <em class="replaceable"><code>integer</code></em>;<br>
+ resolver-query-timeout <em class="replaceable"><code>integer</code></em>;<br>
min-roots <em class="replaceable"><code>integer</code></em>; // not implemented<br>
lame-ttl <em class="replaceable"><code>integer</code></em>;<br>
max-ncache-ttl <em class="replaceable"><code>integer</code></em>;<br>
@@ -242,9 +252,21 @@ options {<br>
dnssec-enable <em class="replaceable"><code>boolean</code></em>;<br>
dnssec-validation <em class="replaceable"><code>boolean</code></em>;<br>
dnssec-lookaside <em class="replaceable"><code>string</code></em> trust-anchor <em class="replaceable"><code>string</code></em>;<br>
+ dnssec-lookaside ( <em class="replaceable"><code>auto</code></em> | <em class="replaceable"><code>domain</code></em> trust-anchor <em class="replaceable"><code>domain</code></em> );<br>
dnssec-must-be-secure <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>boolean</code></em>;<br>
dnssec-accept-expired <em class="replaceable"><code>boolean</code></em>;<br>
<br>
+ dns64-server <em class="replaceable"><code>string</code></em>;<br>
+ dns64-contact <em class="replaceable"><code>string</code></em>;<br>
+ dns64 <em class="replaceable"><code>prefix</code></em> {<br>
+ clients { <font color="red">&lt;replacable&gt;acl&lt;/replacable&gt;</font>; };<br>
+ exclude { <font color="red">&lt;replacable&gt;acl&lt;/replacable&gt;</font>; };<br>
+ mapped { <font color="red">&lt;replacable&gt;acl&lt;/replacable&gt;</font>; };<br>
+ break-dnssec <em class="replaceable"><code>boolean</code></em>;<br>
+ recursive-only <em class="replaceable"><code>boolean</code></em>;<br>
+ suffix <em class="replaceable"><code>ipv6_address</code></em>;<br>
+ };<br>
+<br>
empty-server <em class="replaceable"><code>string</code></em>;<br>
empty-contact <em class="replaceable"><code>string</code></em>;<br>
empty-zones-enable <em class="replaceable"><code>boolean</code></em>;<br>
@@ -261,6 +283,7 @@ options {<br>
allow-update { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
allow-update-forwarding { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
update-check-ksk <em class="replaceable"><code>boolean</code></em>;<br>
+ dnssec-dnskey-kskonly <em class="replaceable"><code>boolean</code></em>;<br>
<br>
masterfile-format ( text | raw );<br>
notify <em class="replaceable"><code>notifytype</code></em>;<br>
@@ -307,9 +330,18 @@ options {<br>
<br>
zone-statistics <em class="replaceable"><code>boolean</code></em>;<br>
key-directory <em class="replaceable"><code>quoted_string</code></em>;<br>
+ managed-keys-directory <em class="replaceable"><code>quoted_string</code></em>;<br>
+ auto-dnssec <code class="constant">allow</code>|<code class="constant">maintain</code>|<code class="constant">create</code>|<code class="constant">off</code>;<br>
try-tcp-refresh <em class="replaceable"><code>boolean</code></em>;<br>
zero-no-soa-ttl <em class="replaceable"><code>boolean</code></em>;<br>
zero-no-soa-ttl-cache <em class="replaceable"><code>boolean</code></em>;<br>
+ dnssec-secure-to-insecure <em class="replaceable"><code>boolean</code></em>;<br>
+ deny-answer-addresses {<br>
+ <em class="replaceable"><code>address_match_list</code></em><br>
+ } [<span class="optional"> except-from { <em class="replaceable"><code>namelist</code></em> } </span>];<br>
+ deny-answer-aliases {<br>
+ <em class="replaceable"><code>namelist</code></em><br>
+ } [<span class="optional"> except-from { <em class="replaceable"><code>namelist</code></em> } </span>];<br>
<br>
nsec3-test-zone <em class="replaceable"><code>boolean</code></em>;  // testing only<br>
<br>
@@ -329,7 +361,7 @@ options {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544452"></a><h2>VIEW</h2>
+<a name="id2544577"></a><h2>VIEW</h2>
<div class="literallayout"><p><br>
view <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>optional_class</code></em> {<br>
match-clients { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
@@ -350,7 +382,8 @@ view <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
};<br>
<br>
trusted-keys {<br>
- <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>quoted_string</code></em>; ...<br>
+ <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>quoted_string</code></em>;<br>
+ [<span class="optional">...</span>]<br>
};<br>
<br>
allow-recursion { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
@@ -375,6 +408,7 @@ view <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
queryport-pool-ports <em class="replaceable"><code>integer</code></em>;<br>
queryport-pool-updateinterval <em class="replaceable"><code>integer</code></em>;<br>
cleaning-interval <em class="replaceable"><code>integer</code></em>;<br>
+ resolver-query-timeout <em class="replaceable"><code>integer</code></em>;<br>
min-roots <em class="replaceable"><code>integer</code></em>; // not implemented<br>
lame-ttl <em class="replaceable"><code>integer</code></em>;<br>
max-ncache-ttl <em class="replaceable"><code>integer</code></em>;<br>
@@ -408,6 +442,17 @@ view <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
dnssec-must-be-secure <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>boolean</code></em>;<br>
dnssec-accept-expired <em class="replaceable"><code>boolean</code></em>;<br>
<br>
+ dns64-server <em class="replaceable"><code>string</code></em>;<br>
+ dns64-contact <em class="replaceable"><code>string</code></em>;<br>
+ dns64 <em class="replaceable"><code>prefix</code></em> {<br>
+ clients { <font color="red">&lt;replacable&gt;acl&lt;/replacable&gt;</font>; };<br>
+ exclude { <font color="red">&lt;replacable&gt;acl&lt;/replacable&gt;</font>; };<br>
+ mapped { <font color="red">&lt;replacable&gt;acl&lt;/replacable&gt;</font>; };<br>
+ break-dnssec <em class="replaceable"><code>boolean</code></em>;<br>
+ recursive-only <em class="replaceable"><code>boolean</code></em>;<br>
+ suffix <em class="replaceable"><code>ipv6_address</code></em>;<br>
+ };<br>
+<br>
empty-server <em class="replaceable"><code>string</code></em>;<br>
empty-contact <em class="replaceable"><code>string</code></em>;<br>
empty-zones-enable <em class="replaceable"><code>boolean</code></em>;<br>
@@ -424,6 +469,7 @@ view <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
allow-update { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
allow-update-forwarding { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
update-check-ksk <em class="replaceable"><code>boolean</code></em>;<br>
+ dnssec-dnskey-kskonly <em class="replaceable"><code>boolean</code></em>;<br>
<br>
masterfile-format ( text | raw );<br>
notify <em class="replaceable"><code>notifytype</code></em>;<br>
@@ -468,6 +514,7 @@ view <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
key-directory <em class="replaceable"><code>quoted_string</code></em>;<br>
zero-no-soa-ttl <em class="replaceable"><code>boolean</code></em>;<br>
zero-no-soa-ttl-cache <em class="replaceable"><code>boolean</code></em>;<br>
+ dnssec-secure-to-insecure <em class="replaceable"><code>boolean</code></em>;<br>
<br>
allow-v6-synthesis { <em class="replaceable"><code>address_match_element</code></em>; ... }; // obsolete<br>
fetch-glue <em class="replaceable"><code>boolean</code></em>; // obsolete<br>
@@ -477,7 +524,7 @@ view <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2545113"></a><h2>ZONE</h2>
+<a name="id2545280"></a><h2>ZONE</h2>
<div class="literallayout"><p><br>
zone <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>optional_class</code></em> {<br>
type ( master | slave | stub | hint |<br>
@@ -501,20 +548,23 @@ zone <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
ixfr-from-differences <em class="replaceable"><code>boolean</code></em>;<br>
journal <em class="replaceable"><code>quoted_string</code></em>;<br>
zero-no-soa-ttl <em class="replaceable"><code>boolean</code></em>;<br>
+ dnssec-secure-to-insecure <em class="replaceable"><code>boolean</code></em>;<br>
<br>
allow-query { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
allow-query-on { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
allow-transfer { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
allow-update { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
allow-update-forwarding { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
- update-policy {<br>
+ update-policy <em class="replaceable"><code>local</code></em> | <em class="replaceable"><code> {<br>
( grant | deny ) <em class="replaceable"><code>string</code></em><br>
( name | subdomain | wildcard | self | selfsub | selfwild |<br>
                  krb5-self | ms-self | krb5-subdomain | ms-subdomain |<br>
-   tcp-self | 6to4-self ) <em class="replaceable"><code>string</code></em><br>
- <em class="replaceable"><code>rrtypelist</code></em>; ...<br>
- };<br>
+   tcp-self | zonesub | 6to4-self ) <em class="replaceable"><code>string</code></em><br>
+ <em class="replaceable"><code>rrtypelist</code></em>;<br>
+ [<span class="optional">...</span>]<br>
+ }</code></em>;<br>
update-check-ksk <em class="replaceable"><code>boolean</code></em>;<br>
+ dnssec-dnskey-kskonly <em class="replaceable"><code>boolean</code></em>;<br>
<br>
masterfile-format ( text | raw );<br>
notify <em class="replaceable"><code>notifytype</code></em>;<br>
@@ -569,12 +619,12 @@ zone <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2545410"></a><h2>FILES</h2>
+<a name="id2545659"></a><h2>FILES</h2>
<p><code class="filename">/etc/named.conf</code>
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2545421"></a><h2>SEE ALSO</h2>
+<a name="id2545671"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkconf</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>,
diff --git a/bin/named/named.docbook b/bin/named/named.docbook
index 808e998eb8a5..214f8ac6e9d7 100644
--- a/bin/named/named.docbook
+++ b/bin/named/named.docbook
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named.docbook,v 1.23.14.2 2009-12-03 04:49:32 tbox Exp $ -->
+<!-- $Id: named.docbook,v 1.26 2009-10-05 17:30:49 fdupont Exp $ -->
<refentry id="man.named">
<refentryinfo>
<date>May 21, 2009</date>
@@ -60,6 +60,7 @@
<arg><option>-6</option></arg>
<arg><option>-c <replaceable class="parameter">config-file</replaceable></option></arg>
<arg><option>-d <replaceable class="parameter">debug-level</replaceable></option></arg>
+ <arg><option>-E <replaceable class="parameter">engine-name</replaceable></option></arg>
<arg><option>-f</option></arg>
<arg><option>-g</option></arg>
<arg><option>-m <replaceable class="parameter">flag</replaceable></option></arg>
@@ -116,6 +117,7 @@
</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term>-c <replaceable class="parameter">config-file</replaceable></term>
<listitem>
@@ -145,6 +147,19 @@
</varlistentry>
<varlistentry>
+ <term>-E <replaceable class="parameter">engine-name</replaceable></term>
+ <listitem>
+ <para>
+ Use a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance re-signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ <replaceable class="parameter">engine-name</replaceable>
+ defaults to pkcs11, the empty name resets it to no engine.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-f</term>
<listitem>
<para>
diff --git a/bin/named/named.html b/bin/named/named.html
index 031b4921ff4e..fa869c4c6d10 100644
--- a/bin/named/named.html
+++ b/bin/named/named.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named.html,v 1.30.14.2 2009-12-03 05:06:38 tbox Exp $ -->
+<!-- $Id: named.html,v 1.33 2009-10-06 01:14:41 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,10 +29,10 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">named</code> [<code class="option">-4</code>] [<code class="option">-6</code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-S <em class="replaceable"><code>#max-socks</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>] [<code class="option">-V</code>] [<code class="option">-x <em class="replaceable"><code>cache-file</code></em></code>]</p></div>
+<div class="cmdsynopsis"><p><code class="command">named</code> [<code class="option">-4</code>] [<code class="option">-6</code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine-name</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-S <em class="replaceable"><code>#max-socks</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>] [<code class="option">-V</code>] [<code class="option">-x <em class="replaceable"><code>cache-file</code></em></code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543472"></a><h2>DESCRIPTION</h2>
+<a name="id2543480"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named</strong></span>
is a Domain Name System (DNS) server,
part of the BIND 9 distribution from ISC. For more
@@ -47,7 +47,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543496"></a><h2>OPTIONS</h2>
+<a name="id2543505"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-4</span></dt>
<dd><p>
@@ -79,6 +79,14 @@
Debugging traces from <span><strong class="command">named</strong></span> become
more verbose as the debug level increases.
</p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine-name</code></em></span></dt>
+<dd><p>
+ Use a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance re-signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ <em class="replaceable"><code>engine-name</code></em>
+ defaults to pkcs11, the empty name resets it to no engine.
+ </p></dd>
<dt><span class="term">-f</span></dt>
<dd><p>
Run the server in the foreground (i.e. do not daemonize).
@@ -220,7 +228,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543931"></a><h2>SIGNALS</h2>
+<a name="id2543962"></a><h2>SIGNALS</h2>
<p>
In routine operation, signals should not be used to control
the nameserver; <span><strong class="command">rndc</strong></span> should be used
@@ -241,7 +249,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543979"></a><h2>CONFIGURATION</h2>
+<a name="id2544010"></a><h2>CONFIGURATION</h2>
<p>
The <span><strong class="command">named</strong></span> configuration file is too complex
to describe in detail here. A complete description is provided
@@ -258,7 +266,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544016"></a><h2>FILES</h2>
+<a name="id2544046"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="filename">/etc/named.conf</code></span></dt>
<dd><p>
@@ -271,7 +279,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544123"></a><h2>SEE ALSO</h2>
+<a name="id2544086"></a><h2>SEE ALSO</h2>
<p><em class="citetitle">RFC 1033</em>,
<em class="citetitle">RFC 1034</em>,
<em class="citetitle">RFC 1035</em>,
@@ -284,7 +292,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544194"></a><h2>AUTHOR</h2>
+<a name="id2544293"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/bin/named/query.c b/bin/named/query.c
index fa34da6e28c0..1950257dca2c 100644
--- a/bin/named/query.c
+++ b/bin/named/query.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.c,v 1.313.20.24 2010-09-24 08:09:07 marka Exp $ */
+/* $Id: query.c,v 1.353.8.2.2.5 2011-06-09 03:17:10 marka Exp $ */
/*! \file */
@@ -34,6 +34,7 @@
#ifdef DLZ
#include <dns/dlz.h>
#endif
+#include <dns/dns64.h>
#include <dns/dnssec.h>
#include <dns/events.h>
#include <dns/message.h>
@@ -62,6 +63,17 @@
#include <named/sortlist.h>
#include <named/xfrout.h>
+#if 0
+/*
+ * It has been recommended that DNS64 be changed to return excluded
+ * AAAA addresses if DNS64 synthesis does not occur. This minimises
+ * the impact on the lookup results. While most DNS AAAA lookups are
+ * done to send IP packets to a host, not all of them are and filtering
+ * excluded addresses has a negative impact on those uses.
+ */
+#define dns64_bis_return_excluded_addresses 1
+#endif
+
/*% Partial answer? */
#define PARTIALANSWER(c) (((c)->query.attributes & \
NS_QUERYATTR_PARTIALANSWER) != 0)
@@ -92,6 +104,12 @@
/*% Secure? */
#define SECURE(c) (((c)->query.attributes & \
NS_QUERYATTR_SECURE) != 0)
+/*% DNS64 A lookup? */
+#define DNS64(c) (((c)->query.attributes & \
+ NS_QUERYATTR_DNS64) != 0)
+
+#define DNS64EXCLUDE(c) (((c)->query.attributes & \
+ NS_QUERYATTR_DNS64EXCLUDE) != 0)
/*% No QNAME Proof? */
#define NOQNAME(r) (((r)->attributes & \
@@ -116,6 +134,7 @@
#define DNS_GETDB_NOEXACT 0x01U
#define DNS_GETDB_NOLOG 0x02U
#define DNS_GETDB_PARTIAL 0x04U
+#define DNS_GETDB_IGNOREACL 0x08U
#define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0)
@@ -141,6 +160,9 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
static inline void
log_queryerror(ns_client_t *client, isc_result_t result, int line, int level);
+static void
+rpz_st_clear(ns_client_t *client);
+
/*%
* Increment query statistics counters.
*/
@@ -252,6 +274,19 @@ ns_query_cancel(ns_client_t *client) {
}
static inline void
+query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
+ dns_rdataset_t *rdataset = *rdatasetp;
+
+ CTRACE("query_putrdataset");
+ if (rdataset != NULL) {
+ if (dns_rdataset_isassociated(rdataset))
+ dns_rdataset_disassociate(rdataset);
+ dns_message_puttemprdataset(client->message, rdatasetp);
+ }
+ CTRACE("query_putrdataset: done");
+}
+
+static inline void
query_reset(ns_client_t *client, isc_boolean_t everything) {
isc_buffer_t *dbuf, *dbuf_next;
ns_dbversion_t *dbversion, *dbversion_next;
@@ -285,6 +320,18 @@ query_reset(ns_client_t *client, isc_boolean_t everything) {
if (client->query.authzone != NULL)
dns_zone_detach(&client->query.authzone);
+ if (client->query.dns64_aaaa != NULL)
+ query_putrdataset(client, &client->query.dns64_aaaa);
+ if (client->query.dns64_sigaaaa != NULL)
+ query_putrdataset(client, &client->query.dns64_sigaaaa);
+ if (client->query.dns64_aaaaok != NULL) {
+ isc_mem_put(client->mctx, client->query.dns64_aaaaok,
+ client->query.dns64_aaaaoklen *
+ sizeof(isc_boolean_t));
+ client->query.dns64_aaaaok = NULL;
+ client->query.dns64_aaaaoklen = 0;
+ }
+
query_freefreeversions(client, everything);
for (dbuf = ISC_LIST_HEAD(client->query.namebufs);
@@ -310,13 +357,22 @@ query_reset(ns_client_t *client, isc_boolean_t everything) {
NS_QUERYATTR_SECURE);
client->query.restarts = 0;
client->query.timerset = ISC_FALSE;
+ if (client->query.rpz_st != NULL) {
+ rpz_st_clear(client);
+ if (everything) {
+ isc_mem_put(client->mctx, client->query.rpz_st,
+ sizeof(*client->query.rpz_st));
+ client->query.rpz_st = NULL;
+ }
+ }
client->query.origqname = NULL;
- client->query.qname = NULL;
client->query.dboptions = 0;
client->query.fetchoptions = 0;
client->query.gluedb = NULL;
client->query.authdbset = ISC_FALSE;
client->query.isreferral = ISC_FALSE;
+ client->query.dns64_options = 0;
+ client->query.dns64_ttl = ISC_UINT32_MAX;
}
static void
@@ -473,20 +529,6 @@ query_newrdataset(ns_client_t *client) {
return (rdataset);
}
-static inline void
-query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
- dns_rdataset_t *rdataset = *rdatasetp;
-
- CTRACE("query_putrdataset");
- if (rdataset != NULL) {
- if (dns_rdataset_isassociated(rdataset))
- dns_rdataset_disassociate(rdataset);
- dns_message_puttemprdataset(client->message, rdatasetp);
- }
- CTRACE("query_putrdataset: done");
-}
-
-
static inline isc_result_t
query_newdbversion(ns_client_t *client, unsigned int n) {
unsigned int i;
@@ -540,6 +582,7 @@ ns_query_init(ns_client_t *client) {
ISC_LIST_INIT(client->query.freeversions);
client->query.restarts = 0;
client->query.timerset = ISC_FALSE;
+ client->query.rpz_st = NULL;
client->query.qname = NULL;
result = isc_mutex_init(&client->query.fetchlock);
if (result != ISC_R_SUCCESS)
@@ -549,6 +592,10 @@ ns_query_init(ns_client_t *client) {
client->query.authzone = NULL;
client->query.authdbset = ISC_FALSE;
client->query.isreferral = ISC_FALSE;
+ client->query.dns64_aaaa = NULL;
+ client->query.dns64_sigaaaa = NULL;
+ client->query.dns64_aaaaok = NULL;
+ client->query.dns64_aaaaoklen = 0;
query_reset(client, ISC_FALSE);
result = query_newdbversion(client, 3);
if (result != ISC_R_SUCCESS) {
@@ -563,8 +610,7 @@ ns_query_init(ns_client_t *client) {
}
static inline ns_dbversion_t *
-query_findversion(ns_client_t *client, dns_db_t *db,
- isc_boolean_t *newzonep)
+query_findversion(ns_client_t *client, dns_db_t *db)
{
ns_dbversion_t *dbversion;
@@ -590,12 +636,11 @@ query_findversion(ns_client_t *client, dns_db_t *db,
return (NULL);
dns_db_attach(db, &dbversion->db);
dns_db_currentversion(db, &dbversion->version);
+ dbversion->acl_checked = ISC_FALSE;
dbversion->queryok = ISC_FALSE;
ISC_LIST_APPEND(client->query.activeversions,
dbversion, link);
- *newzonep = ISC_TRUE;
- } else
- *newzonep = ISC_FALSE;
+ }
return (dbversion);
}
@@ -607,7 +652,6 @@ query_validatezonedb(ns_client_t *client, dns_name_t *name,
dns_dbversion_t **versionp)
{
isc_result_t result;
- isc_boolean_t check_acl, new_zone;
dns_acl_t *queryacl;
ns_dbversion_t *dbversion;
@@ -623,7 +667,17 @@ query_validatezonedb(ns_client_t *client, dns_name_t *name,
if (!client->view->additionalfromauth &&
client->query.authdbset &&
db != client->query.authdb)
- goto refuse;
+ return (DNS_R_REFUSED);
+
+ /*
+ * Non recursive query to a static-stub zone is prohibited; its
+ * zone content is not public data, but a part of local configuration
+ * and should not be disclosed.
+ */
+ if (dns_zone_gettype(zone) == dns_zone_staticstub &&
+ !RECURSIONOK(client)) {
+ return (DNS_R_REFUSED);
+ }
/*
* If the zone has an ACL, we'll check it, otherwise
@@ -633,23 +687,19 @@ query_validatezonedb(ns_client_t *client, dns_name_t *name,
* Also, get the database version to use.
*/
- check_acl = ISC_TRUE; /* Keep compiler happy. */
- queryacl = NULL;
-
/*
* Get the current version of this database.
*/
- dbversion = query_findversion(client, db, &new_zone);
- if (dbversion == NULL) {
- result = DNS_R_SERVFAIL;
- goto fail;
- }
- if (new_zone) {
- check_acl = ISC_TRUE;
- } else if (!dbversion->queryok) {
- goto refuse;
- } else {
- check_acl = ISC_FALSE;
+ dbversion = query_findversion(client, db);
+ if (dbversion == NULL)
+ return (DNS_R_SERVFAIL);
+
+ if ((options & DNS_GETDB_IGNOREACL) != 0)
+ goto approved;
+ if (dbversion->acl_checked) {
+ if (!dbversion->queryok)
+ return (DNS_R_REFUSED);
+ goto approved;
}
queryacl = dns_zone_getqueryacl(zone);
@@ -663,88 +713,69 @@ query_validatezonedb(ns_client_t *client, dns_name_t *name,
* allowed to make queries, otherwise the query should
* be refused.
*/
- check_acl = ISC_FALSE;
+ dbversion->acl_checked = ISC_TRUE;
if ((client->query.attributes &
- NS_QUERYATTR_QUERYOK) == 0)
- goto refuse;
- } else {
- /*
- * We haven't evaluated the view's queryacl yet.
- */
- check_acl = ISC_TRUE;
+ NS_QUERYATTR_QUERYOK) == 0) {
+ dbversion->queryok = ISC_FALSE;
+ return (DNS_R_REFUSED);
+ }
+ dbversion->queryok = ISC_TRUE;
+ goto approved;
}
}
- if (check_acl) {
- isc_boolean_t log = ISC_TF((options & DNS_GETDB_NOLOG) == 0);
-
- result = ns_client_checkaclsilent(client, NULL, queryacl,
- ISC_TRUE);
- if (log) {
- char msg[NS_CLIENT_ACLMSGSIZE("query")];
- if (result == ISC_R_SUCCESS) {
- if (isc_log_wouldlog(ns_g_lctx,
- ISC_LOG_DEBUG(3)))
- {
- ns_client_aclmsg("query", name, qtype,
- client->view->rdclass,
- msg, sizeof(msg));
- ns_client_log(client,
- DNS_LOGCATEGORY_SECURITY,
- NS_LOGMODULE_QUERY,
- ISC_LOG_DEBUG(3),
- "%s approved", msg);
- }
- } else {
+ result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE);
+ if ((options & DNS_GETDB_NOLOG) == 0) {
+ char msg[NS_CLIENT_ACLMSGSIZE("query")];
+ if (result == ISC_R_SUCCESS) {
+ if (isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(3))) {
ns_client_aclmsg("query", name, qtype,
client->view->rdclass,
msg, sizeof(msg));
- ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
- NS_LOGMODULE_QUERY, ISC_LOG_INFO,
- "%s denied", msg);
+ ns_client_log(client,
+ DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_QUERY,
+ ISC_LOG_DEBUG(3),
+ "%s approved", msg);
}
+ } else {
+ ns_client_aclmsg("query", name, qtype,
+ client->view->rdclass,
+ msg, sizeof(msg));
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_QUERY, ISC_LOG_INFO,
+ "%s denied", msg);
}
+ }
- if (queryacl == client->view->queryacl) {
- if (result == ISC_R_SUCCESS) {
- /*
- * We were allowed by the default
- * "allow-query" ACL. Remember this so we
- * don't have to check again.
- */
- client->query.attributes |=
- NS_QUERYATTR_QUERYOK;
- }
+ if (queryacl == client->view->queryacl) {
+ if (result == ISC_R_SUCCESS) {
/*
- * We've now evaluated the view's query ACL, and
- * the NS_QUERYATTR_QUERYOK attribute is now valid.
+ * We were allowed by the default
+ * "allow-query" ACL. Remember this so we
+ * don't have to check again.
*/
- client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
+ client->query.attributes |= NS_QUERYATTR_QUERYOK;
}
-
- if (result != ISC_R_SUCCESS)
- goto refuse;
+ /*
+ * We've now evaluated the view's query ACL, and
+ * the NS_QUERYATTR_QUERYOK attribute is now valid.
+ */
+ client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
}
- /* Approved. */
-
- /*
- * Remember the result of the ACL check so we
- * don't have to check again.
- */
+ dbversion->acl_checked = ISC_TRUE;
+ if (result != ISC_R_SUCCESS) {
+ dbversion->queryok = ISC_FALSE;
+ return (DNS_R_REFUSED);
+ }
dbversion->queryok = ISC_TRUE;
+ approved:
/* Transfer ownership, if necessary. */
if (versionp != NULL)
*versionp = dbversion->version;
-
return (ISC_R_SUCCESS);
-
- refuse:
- return (DNS_R_REFUSED);
-
- fail:
- return (result);
}
static inline isc_result_t
@@ -800,6 +831,97 @@ query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
return (result);
}
+static void
+rpz_log(ns_client_t *client) {
+ char namebuf1[DNS_NAME_FORMATSIZE];
+ char namebuf2[DNS_NAME_FORMATSIZE];
+ dns_rpz_st_t *st;
+ const char *pat;
+
+ if (!ns_g_server->log_queries ||
+ !isc_log_wouldlog(ns_g_lctx, DNS_RPZ_INFO_LEVEL))
+ return;
+
+ st = client->query.rpz_st;
+ dns_name_format(client->query.qname, namebuf1, sizeof(namebuf1));
+ dns_name_format(st->qname, namebuf2, sizeof(namebuf2));
+
+ switch (st->m.policy) {
+ case DNS_RPZ_POLICY_NO_OP:
+ pat ="response policy %s rewrite %s NO-OP using %s";
+ break;
+ case DNS_RPZ_POLICY_NXDOMAIN:
+ pat = "response policy %s rewrite %s to NXDOMAIN using %s";
+ break;
+ case DNS_RPZ_POLICY_NODATA:
+ pat = "response policy %s rewrite %s to NODATA using %s";
+ break;
+ case DNS_RPZ_POLICY_RECORD:
+ case DNS_RPZ_POLICY_CNAME:
+ pat = "response policy %s rewrite %s using %s";
+ break;
+ default:
+ INSIST(0);
+ }
+ ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
+ DNS_RPZ_INFO_LEVEL, pat, dns_rpz_type2str(st->m.type),
+ namebuf1, namebuf2);
+}
+
+static void
+rpz_fail_log(ns_client_t *client, int level, dns_rpz_type_t rpz_type,
+ dns_name_t *name, const char *str, isc_result_t result)
+{
+ char namebuf1[DNS_NAME_FORMATSIZE];
+ char namebuf2[DNS_NAME_FORMATSIZE];
+
+ if (!ns_g_server->log_queries || !isc_log_wouldlog(ns_g_lctx, level))
+ return;
+
+ dns_name_format(client->query.qname, namebuf1, sizeof(namebuf1));
+ dns_name_format(name, namebuf2, sizeof(namebuf2));
+ ns_client_log(client, NS_LOGCATEGORY_QUERY_EERRORS,
+ NS_LOGMODULE_QUERY, level,
+ "response policy %s rewrite %s via %s %sfailed: %s",
+ dns_rpz_type2str(rpz_type),
+ namebuf1, namebuf2, str, isc_result_totext(result));
+}
+
+/*
+ * Get a policy rewrite zone database.
+ */
+static isc_result_t
+rpz_getdb(ns_client_t *client, dns_rpz_type_t rpz_type,
+ dns_name_t *rpz_qname, dns_zone_t **zonep,
+ dns_db_t **dbp, dns_dbversion_t **versionp)
+{
+ char namebuf1[DNS_NAME_FORMATSIZE];
+ char namebuf2[DNS_NAME_FORMATSIZE];
+ dns_dbversion_t *rpz_version = NULL;
+ isc_result_t result;
+
+ result = query_getzonedb(client, rpz_qname, dns_rdatatype_any,
+ DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version);
+ if (result == ISC_R_SUCCESS) {
+ if (ns_g_server->log_queries &&
+ isc_log_wouldlog(ns_g_lctx, DNS_RPZ_DEBUG_LEVEL2)) {
+ dns_name_format(client->query.qname, namebuf1,
+ sizeof(namebuf1));
+ dns_name_format(rpz_qname, namebuf2, sizeof(namebuf2));
+ ns_client_log(client, NS_LOGCATEGORY_QUERIES,
+ NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2,
+ "try rpz %s rewrite %s via %s",
+ dns_rpz_type2str(rpz_type),
+ namebuf1, namebuf2);
+ }
+ *versionp = rpz_version;
+ return (ISC_R_SUCCESS);
+ }
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, rpz_type, rpz_qname,
+ "query_getzonedb() ", result);
+ return (result);
+}
+
static inline isc_result_t
query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
dns_db_t **dbp, unsigned int options)
@@ -1958,6 +2080,323 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
CTRACE("query_addrdataset: done");
}
+static isc_result_t
+query_dns64(ns_client_t *client, dns_name_t **namep, dns_rdataset_t *rdataset,
+ dns_rdataset_t *sigrdataset, isc_buffer_t *dbuf,
+ dns_section_t section)
+{
+ dns_name_t *name, *mname;
+ dns_rdata_t *dns64_rdata;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdatalist_t *dns64_rdatalist;
+ dns_rdataset_t *dns64_rdataset;
+ dns_rdataset_t *mrdataset;
+ isc_buffer_t *buffer;
+ isc_region_t r;
+ isc_result_t result;
+ dns_view_t *view = client->view;
+ isc_netaddr_t netaddr;
+ dns_dns64_t *dns64;
+ unsigned int flags = 0;
+
+ /*%
+ * To the current response for 'client', add the answer RRset
+ * '*rdatasetp' and an optional signature set '*sigrdatasetp', with
+ * owner name '*namep', to section 'section', unless they are
+ * already there. Also add any pertinent additional data.
+ *
+ * If 'dbuf' is not NULL, then '*namep' is the name whose data is
+ * stored in 'dbuf'. In this case, query_addrrset() guarantees that
+ * when it returns the name will either have been kept or released.
+ */
+ CTRACE("query_dns64");
+ name = *namep;
+ mname = NULL;
+ mrdataset = NULL;
+ buffer = NULL;
+ dns64_rdata = NULL;
+ dns64_rdataset = NULL;
+ dns64_rdatalist = NULL;
+ result = dns_message_findname(client->message, section,
+ name, dns_rdatatype_aaaa,
+ rdataset->covers,
+ &mname, &mrdataset);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * We've already got an RRset of the given name and type.
+ * There's nothing else to do;
+ */
+ CTRACE("query_dns64: dns_message_findname succeeded: done");
+ if (dbuf != NULL)
+ query_releasename(client, namep);
+ return (ISC_R_SUCCESS);
+ } else if (result == DNS_R_NXDOMAIN) {
+ /*
+ * The name doesn't exist.
+ */
+ if (dbuf != NULL)
+ query_keepname(client, name, dbuf);
+ dns_message_addname(client->message, name, section);
+ *namep = NULL;
+ mname = name;
+ } else {
+ RUNTIME_CHECK(result == DNS_R_NXRRSET);
+ if (dbuf != NULL)
+ query_releasename(client, namep);
+ }
+
+ if (rdataset->trust != dns_trust_secure &&
+ (section == DNS_SECTION_ANSWER ||
+ section == DNS_SECTION_AUTHORITY))
+ client->query.attributes &= ~NS_QUERYATTR_SECURE;
+
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+
+ result = isc_buffer_allocate(client->mctx, &buffer, view->dns64cnt *
+ 16 * dns_rdataset_count(rdataset));
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_message_gettemprdataset(client->message, &dns64_rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_message_gettemprdatalist(client->message,
+ &dns64_rdatalist);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ dns_rdataset_init(dns64_rdataset);
+ dns_rdatalist_init(dns64_rdatalist);
+ dns64_rdatalist->rdclass = dns_rdataclass_in;
+ dns64_rdatalist->type = dns_rdatatype_aaaa;
+ if (client->query.dns64_ttl != ISC_UINT32_MAX)
+ dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl,
+ client->query.dns64_ttl);
+ else
+ dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, 600);
+
+ if (RECURSIONOK(client))
+ flags |= DNS_DNS64_RECURSIVE;
+
+ /*
+ * We use the signatures from the A lookup to set DNS_DNS64_DNSSEC
+ * as this provides a easy way to see if the answer was signed.
+ */
+ if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
+ flags |= DNS_DNS64_DNSSEC;
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ for (dns64 = ISC_LIST_HEAD(client->view->dns64);
+ dns64 != NULL; dns64 = dns_dns64_next(dns64)) {
+
+ dns_rdataset_current(rdataset, &rdata);
+ isc__buffer_availableregion(buffer, &r);
+ INSIST(r.length >= 16);
+ result = dns_dns64_aaaafroma(dns64, &netaddr,
+ client->signer,
+ &ns_g_server->aclenv,
+ flags, rdata.data, r.base);
+ if (result != ISC_R_SUCCESS) {
+ dns_rdata_reset(&rdata);
+ continue;
+ }
+ isc_buffer_add(buffer, 16);
+ isc_buffer_remainingregion(buffer, &r);
+ isc_buffer_forward(buffer, 16);
+ result = dns_message_gettemprdata(client->message,
+ &dns64_rdata);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_rdata_init(dns64_rdata);
+ dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in,
+ dns_rdatatype_aaaa, &r);
+ ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata,
+ link);
+ dns64_rdata = NULL;
+ dns_rdata_reset(&rdata);
+ }
+ }
+ if (result != ISC_R_NOMORE)
+ goto cleanup;
+
+ if (ISC_LIST_EMPTY(dns64_rdatalist->rdata))
+ goto cleanup;
+
+ result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
+ dns64_rdataset->trust = rdataset->trust;
+ query_addrdataset(client, mname, dns64_rdataset);
+ dns64_rdataset = NULL;
+ dns64_rdatalist = NULL;
+ dns_message_takebuffer(client->message, &buffer);
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (buffer != NULL)
+ isc_buffer_free(&buffer);
+
+ if (dns64_rdata != NULL)
+ dns_message_puttemprdata(client->message, &dns64_rdata);
+
+ if (dns64_rdataset != NULL)
+ dns_message_puttemprdataset(client->message, &dns64_rdataset);
+
+ if (dns64_rdatalist != NULL) {
+ for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata);
+ dns64_rdata != NULL;
+ dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata))
+ {
+ ISC_LIST_UNLINK(dns64_rdatalist->rdata,
+ dns64_rdata, link);
+ dns_message_puttemprdata(client->message, &dns64_rdata);
+ }
+ dns_message_puttemprdatalist(client->message, &dns64_rdatalist);
+ }
+
+ CTRACE("query_dns64: done");
+ return (result);
+}
+
+static void
+query_filter64(ns_client_t *client, dns_name_t **namep,
+ dns_rdataset_t *rdataset, isc_buffer_t *dbuf,
+ dns_section_t section)
+{
+ dns_name_t *name, *mname;
+ dns_rdata_t *myrdata;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdatalist_t *myrdatalist;
+ dns_rdataset_t *myrdataset;
+ isc_buffer_t *buffer;
+ isc_region_t r;
+ isc_result_t result;
+ unsigned int i;
+
+ CTRACE("query_filter64");
+
+ INSIST(client->query.dns64_aaaaok != NULL);
+ INSIST(client->query.dns64_aaaaoklen == dns_rdataset_count(rdataset));
+
+ name = *namep;
+ mname = NULL;
+ buffer = NULL;
+ myrdata = NULL;
+ myrdataset = NULL;
+ myrdatalist = NULL;
+ result = dns_message_findname(client->message, section,
+ name, dns_rdatatype_aaaa,
+ rdataset->covers,
+ &mname, &myrdataset);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * We've already got an RRset of the given name and type.
+ * There's nothing else to do;
+ */
+ CTRACE("query_filter64: dns_message_findname succeeded: done");
+ if (dbuf != NULL)
+ query_releasename(client, namep);
+ return;
+ } else if (result == DNS_R_NXDOMAIN) {
+ mname = name;
+ *namep = NULL;
+ } else {
+ RUNTIME_CHECK(result == DNS_R_NXRRSET);
+ if (dbuf != NULL)
+ query_releasename(client, namep);
+ dbuf = NULL;
+ }
+
+ if (rdataset->trust != dns_trust_secure &&
+ (section == DNS_SECTION_ANSWER ||
+ section == DNS_SECTION_AUTHORITY))
+ client->query.attributes &= ~NS_QUERYATTR_SECURE;
+
+ result = isc_buffer_allocate(client->mctx, &buffer,
+ 16 * dns_rdataset_count(rdataset));
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_message_gettemprdataset(client->message, &myrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_message_gettemprdatalist(client->message, &myrdatalist);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ dns_rdataset_init(myrdataset);
+ dns_rdatalist_init(myrdatalist);
+ myrdatalist->rdclass = dns_rdataclass_in;
+ myrdatalist->type = dns_rdatatype_aaaa;
+ myrdatalist->ttl = rdataset->ttl;
+
+ i = 0;
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ if (!client->query.dns64_aaaaok[i++])
+ continue;
+ dns_rdataset_current(rdataset, &rdata);
+ INSIST(rdata.length == 16);
+ isc_buffer_putmem(buffer, rdata.data, rdata.length);
+ isc_buffer_remainingregion(buffer, &r);
+ isc_buffer_forward(buffer, rdata.length);
+ result = dns_message_gettemprdata(client->message, &myrdata);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_rdata_init(myrdata);
+ dns_rdata_fromregion(myrdata, dns_rdataclass_in,
+ dns_rdatatype_aaaa, &r);
+ ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link);
+ myrdata = NULL;
+ dns_rdata_reset(&rdata);
+ }
+ if (result != ISC_R_NOMORE)
+ goto cleanup;
+
+ result = dns_rdatalist_tordataset(myrdatalist, myrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
+ if (mname == name) {
+ if (dbuf != NULL)
+ query_keepname(client, name, dbuf);
+ dns_message_addname(client->message, name, section);
+ dbuf = NULL;
+ }
+ myrdataset->trust = rdataset->trust;
+ query_addrdataset(client, mname, myrdataset);
+ myrdataset = NULL;
+ myrdatalist = NULL;
+ dns_message_takebuffer(client->message, &buffer);
+
+ cleanup:
+ if (buffer != NULL)
+ isc_buffer_free(&buffer);
+
+ if (myrdata != NULL)
+ dns_message_puttemprdata(client->message, &myrdata);
+
+ if (myrdataset != NULL)
+ dns_message_puttemprdataset(client->message, &myrdataset);
+
+ if (myrdatalist != NULL) {
+ for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata);
+ myrdata != NULL;
+ myrdata = ISC_LIST_HEAD(myrdatalist->rdata))
+ {
+ ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link);
+ dns_message_puttemprdata(client->message, &myrdata);
+ }
+ dns_message_puttemprdatalist(client->message, &myrdatalist);
+ }
+ if (dbuf != NULL)
+ query_releasename(client, &name);
+
+ CTRACE("query_filter64: done");
+}
+
static void
query_addrrset(ns_client_t *client, dns_name_t **namep,
dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,
@@ -2036,7 +2475,7 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
static inline isc_result_t
query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
- isc_boolean_t zero_ttl, isc_boolean_t isassociated)
+ unsigned int override_ttl, isc_boolean_t isassociated)
{
dns_name_t *name;
dns_dbnode_t *node;
@@ -2119,10 +2558,11 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
if (result != ISC_R_SUCCESS)
goto cleanup;
- if (zero_ttl) {
- rdataset->ttl = 0;
+ if (override_ttl != ISC_UINT32_MAX &&
+ override_ttl < rdataset->ttl) {
+ rdataset->ttl = override_ttl;
if (sigrdataset != NULL)
- sigrdataset->ttl = 0;
+ sigrdataset->ttl = override_ttl;
}
/*
@@ -2246,67 +2686,79 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
return (eresult);
}
-static inline isc_result_t
-query_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,
- dns_rdataset_t *dname, dns_name_t **anamep,
- dns_rdatatype_t type)
+static isc_result_t
+query_add_cname(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,
+ dns_trust_t trust, dns_ttl_t ttl)
{
dns_rdataset_t *rdataset;
dns_rdatalist_t *rdatalist;
dns_rdata_t *rdata;
- isc_result_t result;
isc_region_t r;
+ dns_name_t *aname;
+ isc_result_t result;
/*
* We assume the name data referred to by tname won't go away.
*/
- REQUIRE(anamep != NULL);
+ aname = NULL;
+ result = dns_message_gettempname(client->message, &aname);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = dns_name_dup(qname, client->mctx, aname);
+ if (result != ISC_R_SUCCESS) {
+ dns_message_puttempname(client->message, &aname);
+ return (result);
+ }
rdatalist = NULL;
result = dns_message_gettemprdatalist(client->message, &rdatalist);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ dns_message_puttempname(client->message, &aname);
return (result);
+ }
rdata = NULL;
result = dns_message_gettemprdata(client->message, &rdata);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ dns_message_puttempname(client->message, &aname);
+ dns_message_puttemprdatalist(client->message, &rdatalist);
return (result);
+ }
rdataset = NULL;
result = dns_message_gettemprdataset(client->message, &rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_init(rdataset);
- result = dns_name_dup(qname, client->mctx, *anamep);
if (result != ISC_R_SUCCESS) {
- dns_message_puttemprdataset(client->message, &rdataset);
+ dns_message_puttempname(client->message, &aname);
+ dns_message_puttemprdatalist(client->message, &rdatalist);
+ dns_message_puttemprdata(client->message, &rdata);
return (result);
}
-
- rdatalist->type = type;
+ dns_rdataset_init(rdataset);
+ rdatalist->type = dns_rdatatype_cname;
rdatalist->covers = 0;
rdatalist->rdclass = client->message->rdclass;
- rdatalist->ttl = dname->ttl;
+ rdatalist->ttl = ttl;
dns_name_toregion(tname, &r);
rdata->data = r.base;
rdata->length = r.length;
rdata->rdclass = client->message->rdclass;
- rdata->type = type;
+ rdata->type = dns_rdatatype_cname;
ISC_LIST_INIT(rdatalist->rdata);
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
== ISC_R_SUCCESS);
- rdataset->trust = dname->trust;
+ rdataset->trust = trust;
- query_addrrset(client, anamep, &rdataset, NULL, NULL,
+ query_addrrset(client, &aname, &rdataset, NULL, NULL,
DNS_SECTION_ANSWER);
-
if (rdataset != NULL) {
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
dns_message_puttemprdataset(client->message, &rdataset);
}
+ if (aname != NULL)
+ dns_message_puttempname(client->message, &aname);
return (ISC_R_SUCCESS);
}
@@ -2860,7 +3312,7 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
* j.example -> z.i.example NSEC example
* owner common example
* next common example
- * wild *.f.example
+ * wild *.example
*/
options = client->query.dboptions | DNS_DBFIND_NOWILD;
dns_fixedname_init(&wfixed);
@@ -3196,8 +3648,9 @@ query_resume(isc_task_t *task, isc_event_t *event) {
}
static isc_result_t
-query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
- dns_rdataset_t *nameservers, isc_boolean_t resuming)
+query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
+ dns_name_t *qdomain, dns_rdataset_t *nameservers,
+ isc_boolean_t resuming)
{
isc_result_t result;
dns_rdataset_t *rdataset, *sigrdataset;
@@ -3229,7 +3682,11 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
NS_LOGMODULE_QUERY,
ISC_LOG_WARNING,
"recursive-clients soft limit "
- "exceeded, aborting oldest query");
+ "exceeded (%d/%d/%d), "
+ "aborting oldest query",
+ client->recursionquota->used,
+ client->recursionquota->soft,
+ client->recursionquota->max);
}
ns_client_killoldestquery(client);
result = ISC_R_SUCCESS;
@@ -3242,7 +3699,11 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_QUERY,
ISC_LOG_WARNING,
- "no more recursive clients: %s",
+ "no more recursive clients "
+ "(%d/%d/%d): %s",
+ ns_g_server->recursionquota.used,
+ ns_g_server->recursionquota.soft,
+ ns_g_server->recursionquota.max,
isc_result_totext(result));
}
ns_client_killoldestquery(client);
@@ -3289,8 +3750,7 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
else
peeraddr = NULL;
result = dns_resolver_createfetch2(client->view->resolver,
- client->query.qname,
- qtype, qdomain, nameservers,
+ qname, qtype, qdomain, nameservers,
NULL, peeraddr, client->message->id,
client->query.fetchoptions,
client->task,
@@ -3313,6 +3773,696 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
return (result);
}
+static inline void
+rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep,
+ dns_rdataset_t **rdatasetp)
+{
+ if (nodep != NULL && *nodep != NULL) {
+ REQUIRE(dbp != NULL && *dbp != NULL);
+ dns_db_detachnode(*dbp, nodep);
+ }
+ if (dbp != NULL && *dbp != NULL)
+ dns_db_detach(dbp);
+ if (zonep != NULL && *zonep != NULL)
+ dns_zone_detach(zonep);
+ if (rdatasetp != NULL && *rdatasetp != NULL &&
+ dns_rdataset_isassociated(*rdatasetp))
+ dns_rdataset_disassociate(*rdatasetp);
+}
+
+static inline isc_result_t
+rpz_ready(ns_client_t *client, dns_zone_t **zonep, dns_db_t **dbp,
+ dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp)
+{
+ REQUIRE(rdatasetp != NULL);
+
+ rpz_clean(zonep, dbp, nodep, rdatasetp);
+ if (*rdatasetp == NULL) {
+ *rdatasetp = query_newrdataset(client);
+ if (*rdatasetp == NULL)
+ return (DNS_R_SERVFAIL);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+static void
+rpz_st_clear(ns_client_t *client) {
+ dns_rpz_st_t *st = client->query.rpz_st;
+
+ rpz_clean(&st->m.zone, &st->m.db, &st->m.node, NULL);
+ if (st->m.rdataset != NULL)
+ query_putrdataset(client, &st->m.rdataset);
+
+ rpz_clean(NULL, &st->ns.db, NULL, NULL);
+ if (st->ns.ns_rdataset != NULL)
+ query_putrdataset(client, &st->ns.ns_rdataset);
+ if (st->ns.r_rdataset != NULL)
+ query_putrdataset(client, &st->ns.r_rdataset);
+
+ rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL);
+ if (st->q.rdataset != NULL)
+ query_putrdataset(client, &st->q.rdataset);
+ if (st->q.sigrdataset != NULL)
+ query_putrdataset(client, &st->q.sigrdataset);
+ st->state = 0;
+}
+
+/*
+ * Get NS, A, or AAAA rrset for rpz nsdname or nsip checking.
+ */
+static isc_result_t
+rpz_ns_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
+ dns_db_t **dbp, dns_dbversion_t *version,
+ dns_rdataset_t **rdatasetp, isc_boolean_t resuming)
+{
+ dns_rpz_st_t *st;
+ isc_boolean_t is_zone;
+ dns_dbnode_t *node;
+ dns_fixedname_t fixed;
+ dns_name_t *found;
+ isc_result_t result;
+
+ st = client->query.rpz_st;
+ if ((st->state & DNS_RPZ_RECURSING) != 0) {
+ INSIST(st->ns.r_type == type);
+ INSIST(dns_name_equal(name, st->r_name));
+ INSIST(*rdatasetp == NULL ||
+ !dns_rdataset_isassociated(*rdatasetp));
+ st->state &= ~DNS_RPZ_RECURSING;
+ *dbp = st->ns.db;
+ st->ns.db = NULL;
+ if (*rdatasetp != NULL)
+ query_putrdataset(client, rdatasetp);
+ *rdatasetp = st->ns.r_rdataset;
+ st->ns.r_rdataset = NULL;
+ result = st->ns.r_result;
+ if (result == DNS_R_DELEGATION) {
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL,
+ DNS_RPZ_TYPE_NSIP, name,
+ "rpz_ns_find() ", result);
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ result = DNS_R_SERVFAIL;
+ }
+ return (result);
+ }
+
+ result = rpz_ready(client, NULL, NULL, NULL, rdatasetp);
+ if (result != ISC_R_SUCCESS) {
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ return (result);
+ }
+ if (*dbp != NULL) {
+ is_zone = ISC_FALSE;
+ } else {
+ dns_zone_t *zone;
+
+ version = NULL;
+ zone = NULL;
+ result = query_getdb(client, name, type, 0, &zone, dbp,
+ &version, &is_zone);
+ if (result != ISC_R_SUCCESS) {
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL,
+ DNS_RPZ_TYPE_NSIP, name, "NS getdb() ",
+ result);
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ return (result);
+ }
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ }
+
+ node = NULL;
+ dns_fixedname_init(&fixed);
+ found = dns_fixedname_name(&fixed);
+ result = dns_db_find(*dbp, name, version, type, 0, client->now, &node,
+ found, *rdatasetp, NULL);
+ if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) {
+ /*
+ * Try the cache if we're authoritative for an
+ * ancestor but not the domain itself.
+ */
+ rpz_clean(NULL, dbp, &node, rdatasetp);
+ version = NULL;
+ dns_db_attach(client->view->cachedb, dbp);
+ result = dns_db_find(*dbp, name, version, dns_rdatatype_ns,
+ 0, client->now, &node, found,
+ *rdatasetp, NULL);
+ }
+ rpz_clean(NULL, dbp, &node, NULL);
+ if (result == DNS_R_DELEGATION) {
+ /*
+ * Recurse to get NS rrset or A or AAAA rrset for an NS name.
+ */
+ rpz_clean(NULL, NULL, NULL, rdatasetp);
+ dns_name_copy(name, st->r_name, NULL);
+ result = query_recurse(client, type, st->r_name, NULL, NULL,
+ resuming);
+ if (result == ISC_R_SUCCESS) {
+ st->state |= DNS_RPZ_RECURSING;
+ result = DNS_R_DELEGATION;
+ }
+ }
+ return (result);
+}
+
+/*
+ * Check the IP address in an A or AAAA rdataset against
+ * the IP or NSIP response policy rules of a view.
+ */
+static isc_result_t
+rpz_rewrite_ip(ns_client_t *client, dns_rdataset_t *rdataset,
+ dns_rpz_type_t rpz_type)
+{
+ dns_rpz_st_t *st;
+ dns_dbversion_t *version;
+ dns_zone_t *zone;
+ dns_db_t *db;
+ dns_rpz_zone_t *new_rpz;
+ isc_result_t result;
+
+ st = client->query.rpz_st;
+ if (st->m.rdataset == NULL) {
+ st->m.rdataset = query_newrdataset(client);
+ if (st->m.rdataset == NULL)
+ return (DNS_R_SERVFAIL);
+ }
+ zone = NULL;
+ db = NULL;
+ for (new_rpz = ISC_LIST_HEAD(client->view->rpz_zones);
+ new_rpz != NULL;
+ new_rpz = ISC_LIST_NEXT(new_rpz, link)) {
+ version = NULL;
+
+ /*
+ * Find the database for this policy zone to get its
+ * radix tree.
+ */
+ result = rpz_getdb(client, rpz_type, &new_rpz->origin,
+ &zone, &db, &version);
+ if (result != ISC_R_SUCCESS) {
+ rpz_clean(&zone, &db, NULL, NULL);
+ continue;
+ }
+ /*
+ * Look for a better (e.g. longer prefix) hit for an IP address
+ * in this rdataset in this radix tree than than the previous
+ * hit, if any. Note the domain name and quality of the
+ * best hit.
+ */
+ result = dns_db_rpz_findips(new_rpz, rpz_type, zone, db,
+ version, rdataset, st);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ rpz_clean(&zone, &db, NULL, NULL);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+rpz_rewrite_nsip(ns_client_t *client, dns_rdatatype_t type, dns_name_t *name,
+ dns_db_t **dbp, dns_dbversion_t *version,
+ dns_rdataset_t **rdatasetp, isc_boolean_t resuming)
+{
+ isc_result_t result;
+
+ result = rpz_ns_find(client, name, type, dbp, version, rdatasetp,
+ resuming);
+ switch (result) {
+ case ISC_R_SUCCESS:
+ result = rpz_rewrite_ip(client, *rdatasetp, DNS_RPZ_TYPE_NSIP);
+ break;
+ case DNS_R_EMPTYNAME:
+ case DNS_R_EMPTYWILD:
+ case DNS_R_NXDOMAIN:
+ case DNS_R_NCACHENXDOMAIN:
+ case DNS_R_NXRRSET:
+ case DNS_R_NCACHENXRRSET:
+ result = ISC_R_SUCCESS;
+ break;
+ case DNS_R_DELEGATION:
+ case DNS_R_DUPLICATE:
+ case DNS_R_DROP:
+ break;
+ default:
+ if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) {
+ client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR;
+ rpz_fail_log(client, ISC_LOG_WARNING, DNS_RPZ_TYPE_NSIP,
+ name, "NS address rewrite nsip ", result);
+ }
+ break;
+ }
+ return (result);
+}
+
+/*
+ * Get the rrset from a response policy zone.
+ */
+static isc_result_t
+rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
+ dns_name_t *sname, dns_rpz_type_t rpz_type, dns_zone_t **zonep,
+ dns_db_t **dbp, dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
+ dns_rpz_policy_t *policyp)
+{
+ dns_dbversion_t *version;
+ dns_rpz_policy_t policy;
+ dns_fixedname_t fixed;
+ dns_name_t *found;
+ isc_result_t result;
+
+ result = rpz_ready(client, zonep, dbp, nodep, rdatasetp);
+ if (result != ISC_R_SUCCESS) {
+ *policyp = DNS_RPZ_POLICY_ERROR;
+ return (result);
+ }
+
+ /*
+ * Try to get either a CNAME or the type of record demanded by the
+ * request from the policy zone.
+ */
+ version = NULL;
+ result = rpz_getdb(client, rpz_type, qnamef, zonep, dbp, &version);
+ if (result != ISC_R_SUCCESS) {
+ *policyp = DNS_RPZ_POLICY_MISS;
+ return (DNS_R_NXDOMAIN);
+ }
+
+ dns_fixedname_init(&fixed);
+ found = dns_fixedname_name(&fixed);
+ result = dns_db_find(*dbp, qnamef, version, dns_rdatatype_any, 0,
+ client->now, nodep, found, *rdatasetp, NULL);
+ if (result == ISC_R_SUCCESS) {
+ dns_rdatasetiter_t *rdsiter;
+
+ rdsiter = NULL;
+ result = dns_db_allrdatasets(*dbp, *nodep, version, 0,
+ &rdsiter);
+ if (result != ISC_R_SUCCESS) {
+ dns_db_detachnode(*dbp, nodep);
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, rpz_type,
+ qnamef, "allrdatasets()", result);
+ *policyp = DNS_RPZ_POLICY_ERROR;
+ return (DNS_R_SERVFAIL);
+ }
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, *rdatasetp);
+ if ((*rdatasetp)->type == dns_rdatatype_cname ||
+ (*rdatasetp)->type == qtype)
+ break;
+ dns_rdataset_disassociate(*rdatasetp);
+ }
+ dns_rdatasetiter_destroy(&rdsiter);
+ if (result != ISC_R_SUCCESS) {
+ if (result != ISC_R_NOMORE) {
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL,
+ rpz_type, qnamef, "rdatasetiter",
+ result);
+ *policyp = DNS_RPZ_POLICY_ERROR;
+ return (DNS_R_SERVFAIL);
+ }
+ /*
+ * Ask again to get the right DNS_R_DNAME/NXRRSET/...
+ * result if there is neither a CNAME nor target type.
+ */
+ if (dns_rdataset_isassociated(*rdatasetp))
+ dns_rdataset_disassociate(*rdatasetp);
+ dns_db_detachnode(*dbp, nodep);
+
+ if (qtype == dns_rdatatype_rrsig ||
+ qtype == dns_rdatatype_sig)
+ result = DNS_R_NXRRSET;
+ else
+ result = dns_db_find(*dbp, qnamef, version,
+ qtype, 0, client->now,
+ nodep, found, *rdatasetp,
+ NULL);
+ }
+ }
+ switch (result) {
+ case ISC_R_SUCCESS:
+ if ((*rdatasetp)->type != dns_rdatatype_cname) {
+ policy = DNS_RPZ_POLICY_RECORD;
+ } else {
+ policy = dns_rpz_decode_cname(*rdatasetp, sname);
+ if (policy == DNS_RPZ_POLICY_RECORD &&
+ qtype != dns_rdatatype_cname &&
+ qtype != dns_rdatatype_any)
+ result = DNS_R_CNAME;
+ }
+ break;
+ case DNS_R_DNAME:
+ /*
+ * DNAME policy RRs have very few if any uses that are not
+ * better served with simple wildcards. Making the work would
+ * require complications to get the number of labels matched
+ * in the name or the found name itself to the main DNS_R_DNAME
+ * case in query_find(). So fall through to treat them as NODATA.
+ */
+ case DNS_R_NXRRSET:
+ policy = DNS_RPZ_POLICY_NODATA;
+ break;
+ case DNS_R_NXDOMAIN:
+ case DNS_R_EMPTYNAME:
+ /*
+ * If we don't get a qname hit,
+ * see if it is worth looking for other types.
+ */
+ dns_db_rpz_enabled(*dbp, client->query.rpz_st);
+ dns_db_detach(dbp);
+ dns_zone_detach(zonep);
+ policy = DNS_RPZ_POLICY_MISS;
+ break;
+ default:
+ dns_db_detach(dbp);
+ dns_zone_detach(zonep);
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, rpz_type, qnamef,
+ "", result);
+ policy = DNS_RPZ_POLICY_ERROR;
+ result = DNS_R_SERVFAIL;
+ break;
+ }
+
+ *policyp = policy;
+ return (result);
+}
+
+/*
+ * Build and look for a QNAME or NSDNAME owner name in a response policy zone.
+ */
+static isc_result_t
+rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
+ dns_rpz_type_t rpz_type, dns_rdataset_t **rdatasetp)
+{
+ dns_rpz_st_t *st;
+ dns_rpz_zone_t *rpz;
+ dns_fixedname_t prefixf, rpz_qnamef;
+ dns_name_t *prefix, *suffix, *rpz_qname;
+ dns_zone_t *zone;
+ dns_db_t *db;
+ dns_dbnode_t *node;
+ dns_rpz_policy_t policy;
+ unsigned int labels;
+ isc_result_t result;
+
+ st = client->query.rpz_st;
+ zone = NULL;
+ db = NULL;
+ node = NULL;
+
+ for (rpz = ISC_LIST_HEAD(client->view->rpz_zones);
+ rpz != NULL;
+ rpz = ISC_LIST_NEXT(rpz, link)) {
+ /*
+ * Construct the rule's owner name.
+ */
+ dns_fixedname_init(&prefixf);
+ prefix = dns_fixedname_name(&prefixf);
+ dns_name_split(qname, 1, prefix, NULL);
+ if (rpz_type == DNS_RPZ_TYPE_NSDNAME)
+ suffix = &rpz->nsdname;
+ else
+ suffix = &rpz->origin;
+ dns_fixedname_init(&rpz_qnamef);
+ rpz_qname = dns_fixedname_name(&rpz_qnamef);
+ for (;;) {
+ result = dns_name_concatenate(prefix, suffix,
+ rpz_qname, NULL);
+ if (result == ISC_R_SUCCESS)
+ break;
+ INSIST(result == DNS_R_NAMETOOLONG);
+ labels = dns_name_countlabels(prefix);
+ if (labels < 2) {
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL,
+ rpz_type, suffix,
+ "concatentate() ", result);
+ return (ISC_R_SUCCESS);
+ }
+ if (labels+1 == dns_name_countlabels(qname)) {
+ rpz_fail_log(client, DNS_RPZ_DEBUG_LEVEL1,
+ rpz_type, suffix,
+ "concatentate() ", result);
+ }
+ dns_name_split(prefix, labels - 1, NULL, prefix);
+ }
+
+ /*
+ * See if the qname rule (or RR) exists.
+ */
+ result = rpz_find(client, qtype, rpz_qname, qname, rpz_type,
+ &zone, &db, &node, rdatasetp, &policy);
+ switch (result) {
+ case DNS_R_NXDOMAIN:
+ case DNS_R_EMPTYNAME:
+ break;
+ case DNS_R_SERVFAIL:
+ rpz_clean(&zone, &db, &node, rdatasetp);
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ return (DNS_R_SERVFAIL);
+ default:
+ /*
+ * when more than one name or address hits a rule,
+ * prefer the first set of names (qname or NS),
+ * the first policy zone, and the smallest name
+ */
+ if (st->m.type == rpz_type &&
+ rpz->num > st->m.rpz->num &&
+ 0 <= dns_name_compare(rpz_qname, st->qname))
+ continue;
+ rpz_clean(&st->m.zone, &st->m.db, &st->m.node,
+ &st->m.rdataset);
+ st->m.rpz = rpz;
+ st->m.type = rpz_type;
+ st->m.prefix = 0;
+ st->m.policy = policy;
+ st->m.result = result;
+ dns_name_copy(rpz_qname, st->qname, NULL);
+ if (dns_rdataset_isassociated(*rdatasetp)) {
+ dns_rdataset_t *trdataset;
+
+ trdataset = st->m.rdataset;
+ st->m.rdataset = *rdatasetp;
+ *rdatasetp = trdataset;
+ st->m.ttl = st->m.rdataset->ttl;
+ } else {
+ st->m.ttl = DNS_RPZ_TTL_DEFAULT;
+ }
+ st->m.node = node;
+ node = NULL;
+ st->m.db = db;
+ db = NULL;
+ st->m.zone = zone;
+ zone = NULL;
+ }
+ }
+
+ rpz_clean(&zone, &db, &node, rdatasetp);
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * Look for response policy zone NSIP and NSDNAME rewriting.
+ */
+static isc_result_t
+rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype,
+ isc_boolean_t resuming)
+{
+ dns_rpz_st_t *st;
+ dns_db_t *ipdb;
+ dns_rdataset_t *rdataset;
+ dns_fixedname_t nsnamef;
+ dns_name_t *nsname;
+ dns_dbversion_t *version;
+ isc_result_t result;
+
+ ipdb = NULL;
+ rdataset = NULL;
+
+ st = client->query.rpz_st;
+ if (st == NULL) {
+ st = isc_mem_get(client->mctx, sizeof(*st));
+ if (st == NULL)
+ return (ISC_R_NOMEMORY);
+ st->state = 0;
+ memset(&st->m, 0, sizeof(st->m));
+ memset(&st->ns, 0, sizeof(st->ns));
+ memset(&st->q, 0, sizeof(st->q));
+ dns_fixedname_init(&st->_qnamef);
+ dns_fixedname_init(&st->_r_namef);
+ dns_fixedname_init(&st->_fnamef);
+ st->qname = dns_fixedname_name(&st->_qnamef);
+ st->r_name = dns_fixedname_name(&st->_r_namef);
+ st->fname = dns_fixedname_name(&st->_fnamef);
+ client->query.rpz_st = st;
+ }
+ if ((st->state & DNS_RPZ_DONE_QNAME) == 0) {
+ st->state = DNS_RPZ_DONE_QNAME;
+ st->m.type = DNS_RPZ_TYPE_BAD;
+ st->m.policy = DNS_RPZ_POLICY_MISS;
+
+ /*
+ * Check rules for the name if this it the first time,
+ * i.e. we've not been recursing.
+ */
+ result = DNS_R_SERVFAIL;
+ st->state &= ~(DNS_RPZ_HAVE_IP | DNS_RPZ_HAVE_NSIPv4 |
+ DNS_RPZ_HAVE_NSIPv6 | DNS_RPZ_HAD_NSDNAME);
+ result = rpz_rewrite_name(client, qtype, client->query.qname,
+ DNS_RPZ_TYPE_QNAME, &rdataset);
+ if (st->m.policy != DNS_RPZ_POLICY_MISS)
+ goto cleanup;
+ if ((st->state & (DNS_RPZ_HAVE_NSIPv4 | DNS_RPZ_HAVE_NSIPv6 |
+ DNS_RPZ_HAD_NSDNAME)) == 0)
+ goto cleanup;
+ st->ns.label = dns_name_countlabels(client->query.qname);
+ }
+
+ dns_fixedname_init(&nsnamef);
+ dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef));
+ while (st->ns.label > 1 && st->m.policy == DNS_RPZ_POLICY_MISS) {
+ if (st->ns.label == dns_name_countlabels(client->query.qname)) {
+ nsname = client->query.qname;
+ } else {
+ nsname = dns_fixedname_name(&nsnamef);
+ dns_name_split(client->query.qname, st->ns.label,
+ NULL, nsname);
+ }
+ if (st->ns.ns_rdataset == NULL ||
+ !dns_rdataset_isassociated(st->ns.ns_rdataset)) {
+ dns_db_t *db = NULL;
+ result = rpz_ns_find(client, nsname, dns_rdatatype_ns,
+ &db, NULL, &st->ns.ns_rdataset,
+ resuming);
+ if (db != NULL)
+ dns_db_detach(&db);
+ if (result != ISC_R_SUCCESS) {
+ if (result == DNS_R_DELEGATION)
+ goto cleanup;
+ if (result == DNS_R_EMPTYNAME ||
+ result == DNS_R_NXRRSET ||
+ result == DNS_R_EMPTYWILD ||
+ result == DNS_R_NXDOMAIN ||
+ result == DNS_R_NCACHENXDOMAIN ||
+ result == DNS_R_NCACHENXRRSET ||
+ result == DNS_R_CNAME ||
+ result == DNS_R_DNAME) {
+ rpz_fail_log(client,
+ DNS_RPZ_DEBUG_LEVEL2,
+ DNS_RPZ_TYPE_NSIP, nsname,
+ "NS db_find() ", result);
+ dns_rdataset_disassociate(st->ns.
+ ns_rdataset);
+ st->ns.label--;
+ continue;
+ }
+ if (st->m.policy != DNS_RPZ_POLICY_ERROR) {
+ rpz_fail_log(client, DNS_RPZ_INFO_LEVEL,
+ DNS_RPZ_TYPE_NSIP, nsname,
+ "NS db_find() ", result);
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ }
+ goto cleanup;
+ }
+ result = dns_rdataset_first(st->ns.ns_rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+ /*
+ * Check all NS names.
+ */
+ do {
+ dns_rdata_ns_t ns;
+ dns_rdata_t nsrdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(st->ns.ns_rdataset, &nsrdata);
+ result = dns_rdata_tostruct(&nsrdata, &ns, NULL);
+ dns_rdata_reset(&nsrdata);
+ if (result != ISC_R_SUCCESS) {
+ rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL,
+ DNS_RPZ_TYPE_NSIP, nsname,
+ "rdata_tostruct() ", result);
+ st->m.policy = DNS_RPZ_POLICY_ERROR;
+ goto cleanup;
+ }
+ if ((st->state & DNS_RPZ_HAD_NSDNAME) != 0) {
+ result = rpz_rewrite_name(client, qtype,
+ &ns.name,
+ DNS_RPZ_TYPE_NSDNAME,
+ &rdataset);
+ if (result != ISC_R_SUCCESS) {
+ dns_rdata_freestruct(&ns);
+ goto cleanup;
+ }
+ }
+ /*
+ * Check all IP addresses for this NS name, but don't
+ * bother without NSIP rules or with a NSDNAME hit.
+ */
+ version = NULL;
+ if ((st->state & DNS_RPZ_HAVE_NSIPv4) != 0 &&
+ st->m.type != DNS_RPZ_TYPE_NSDNAME &&
+ (st->state & DNS_RPZ_DONE_A) == 0) {
+ result = rpz_rewrite_nsip(client,
+ dns_rdatatype_a,
+ &ns.name, &ipdb,
+ version, &rdataset,
+ resuming);
+ if (result == ISC_R_SUCCESS)
+ st->state |= DNS_RPZ_DONE_A;
+ }
+ if (result == ISC_R_SUCCESS &&
+ (st->state & DNS_RPZ_HAVE_NSIPv6) != 0 &&
+ st->m.type != DNS_RPZ_TYPE_NSDNAME) {
+ result = rpz_rewrite_nsip(client,
+ dns_rdatatype_aaaa,
+ &ns.name, &ipdb, version,
+ &rdataset, resuming);
+ }
+ dns_rdata_freestruct(&ns);
+ if (ipdb != NULL)
+ dns_db_detach(&ipdb);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ st->state &= ~DNS_RPZ_DONE_A;
+ result = dns_rdataset_next(st->ns.ns_rdataset);
+ } while (result == ISC_R_SUCCESS);
+ dns_rdataset_disassociate(st->ns.ns_rdataset);
+ st->ns.label--;
+ }
+
+ /*
+ * Use the best, if any, hit.
+ */
+ result = ISC_R_SUCCESS;
+
+cleanup:
+ if (st->m.policy != DNS_RPZ_POLICY_MISS &&
+ st->m.policy != DNS_RPZ_POLICY_NO_OP &&
+ st->m.policy != DNS_RPZ_POLICY_ERROR &&
+ st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN)
+ st->m.policy = st->m.rpz->policy;
+ if (st->m.policy == DNS_RPZ_POLICY_NO_OP)
+ rpz_log(client);
+ if (st->m.policy == DNS_RPZ_POLICY_MISS ||
+ st->m.policy == DNS_RPZ_POLICY_NO_OP ||
+ st->m.policy == DNS_RPZ_POLICY_ERROR)
+ rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset);
+ if (st->m.policy != DNS_RPZ_POLICY_MISS)
+ st->state |= DNS_RPZ_REWRITTEN;
+ if (st->m.policy == DNS_RPZ_POLICY_ERROR) {
+ st->m.type = DNS_RPZ_TYPE_BAD;
+ result = DNS_R_SERVFAIL;
+ }
+ if (rdataset != NULL)
+ query_putrdataset(client, &rdataset);
+ if ((st->state & DNS_RPZ_RECURSING) == 0) {
+ rpz_clean(NULL, &st->ns.db, NULL, &st->ns.ns_rdataset);
+ }
+
+ return (result);
+}
+
#define MAX_RESTARTS 16
#define QUERY_ERROR(r) \
@@ -3698,6 +4848,99 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
return;
}
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+static isc_boolean_t
+is_v4_client(ns_client_t *client) {
+ if (isc_sockaddr_pf(&client->peeraddr) == AF_INET)
+ return (ISC_TRUE);
+ if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 &&
+ IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr))
+ return (ISC_TRUE);
+ return (ISC_FALSE);
+}
+#endif
+
+static isc_uint32_t
+dns64_ttl(dns_db_t *db, dns_dbversion_t *version) {
+ dns_dbnode_t *node = NULL;
+ dns_rdata_soa_t soa;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_t rdataset;
+ isc_result_t result;
+ isc_uint32_t ttl = ISC_UINT32_MAX;
+
+ result = dns_db_getoriginnode(db, &node);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_rdataset_init(&rdataset);
+ result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
+ 0, 0, &rdataset, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_rdataset_first(&rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ dns_rdataset_current(&rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &soa, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ ttl = ISC_MIN(rdataset.ttl, soa.minimum);
+
+cleanup:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ return (ttl);
+}
+
+static isc_boolean_t
+dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
+ dns_rdataset_t *sigrdataset)
+{
+ isc_netaddr_t netaddr;
+ dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64);
+ unsigned int flags = 0;
+ unsigned int i, count;
+ isc_boolean_t *aaaaok;
+
+ INSIST(client->query.dns64_aaaaok == NULL);
+ INSIST(client->query.dns64_aaaaoklen == 0);
+ INSIST(client->query.dns64_aaaa == NULL);
+ INSIST(client->query.dns64_sigaaaa == NULL);
+
+ if (dns64 == NULL)
+ return (ISC_TRUE);
+
+ if (RECURSIONOK(client))
+ flags |= DNS_DNS64_RECURSIVE;
+
+ if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
+ flags |= DNS_DNS64_DNSSEC;
+
+ count = dns_rdataset_count(rdataset);
+ aaaaok = isc_mem_get(client->mctx, sizeof(isc_boolean_t) * count);
+
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+ if (dns_dns64_aaaaok(dns64, &netaddr, client->signer,
+ &ns_g_server->aclenv, flags, rdataset,
+ aaaaok, count)) {
+ for (i = 0; i < count; i++) {
+ if (aaaaok != NULL && !aaaaok[i]) {
+ client->query.dns64_aaaaok = aaaaok;
+ client->query.dns64_aaaaoklen = count;
+ break;
+ }
+ }
+ if (i == count)
+ isc_mem_put(client->mctx, aaaaok,
+ sizeof(isc_boolean_t) * count);
+ return (ISC_TRUE);
+ }
+ isc_mem_put(client->mctx, aaaaok, sizeof(isc_boolean_t) * count);
+ return (ISC_FALSE);
+}
+
/*
* Do the bulk of query processing for the current query of 'client'.
* If 'event' is non-NULL, we are returning from recursion and 'qtype'
@@ -3716,6 +4959,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdatasetiter_t *rdsiter;
isc_boolean_t want_restart, authoritative, is_zone, need_wildcardproof;
+ isc_boolean_t is_staticstub_zone;
unsigned int n, nlabels;
dns_namereln_t namereln;
int order;
@@ -3731,8 +4975,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
unsigned int options;
isc_boolean_t empty_wild;
dns_rdataset_t *noqname;
+ dns_rpz_st_t *rpz_st;
isc_boolean_t resuming;
int line = -1;
+ isc_boolean_t dns64_exclude, dns64;
CTRACE("query_find");
@@ -3758,28 +5004,67 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
zone = NULL;
need_wildcardproof = ISC_FALSE;
empty_wild = ISC_FALSE;
+ dns64_exclude = dns64 = ISC_FALSE;
options = 0;
resuming = ISC_FALSE;
is_zone = ISC_FALSE;
+ is_staticstub_zone = ISC_FALSE;
if (event != NULL) {
/*
* We're returning from recursion. Restore the query context
* and resume.
*/
-
want_restart = ISC_FALSE;
- authoritative = ISC_FALSE;
- qtype = event->qtype;
+ rpz_st = client->query.rpz_st;
+ if (rpz_st != NULL &&
+ (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
+ is_zone = rpz_st->q.is_zone;
+ authoritative = rpz_st->q.authoritative;
+ zone = rpz_st->q.zone;
+ rpz_st->q.zone = NULL;
+ node = rpz_st->q.node;
+ rpz_st->q.node = NULL;
+ db = rpz_st->q.db;
+ rpz_st->q.db = NULL;
+ rdataset = rpz_st->q.rdataset;
+ rpz_st->q.rdataset = NULL;
+ sigrdataset = rpz_st->q.sigrdataset;
+ rpz_st->q.sigrdataset = NULL;
+ qtype = rpz_st->q.qtype;
+
+ if (event->node != NULL)
+ dns_db_detachnode(db, &event->node);
+ rpz_st->ns.db = event->db;
+ rpz_st->ns.r_type = event->qtype;
+ rpz_st->ns.r_rdataset = event->rdataset;
+ if (event->sigrdataset != NULL &&
+ dns_rdataset_isassociated(event->sigrdataset))
+ dns_rdataset_disassociate(event->sigrdataset);
+ } else {
+ authoritative = ISC_FALSE;
+
+ qtype = event->qtype;
+ db = event->db;
+ node = event->node;
+ rdataset = event->rdataset;
+ sigrdataset = event->sigrdataset;
+ }
+
if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig)
type = dns_rdatatype_any;
else
type = qtype;
- db = event->db;
- node = event->node;
- rdataset = event->rdataset;
- sigrdataset = event->sigrdataset;
+
+ if (DNS64(client)) {
+ client->query.attributes &= ~NS_QUERYATTR_DNS64;
+ dns64 = ISC_TRUE;
+ }
+ if (DNS64EXCLUDE(client)) {
+ client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE;
+ dns64_exclude = ISC_TRUE;
+ }
/*
* We'll need some resources...
@@ -3794,16 +5079,26 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
- tname = dns_fixedname_name(&event->foundname);
+ if (rpz_st != NULL &&
+ (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
+ tname = rpz_st->fname;
+ } else {
+ tname = dns_fixedname_name(&event->foundname);
+ }
result = dns_name_copy(tname, fname, NULL);
if (result != ISC_R_SUCCESS) {
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
-
- result = event->result;
+ if (rpz_st != NULL &&
+ (rpz_st->state & DNS_RPZ_RECURSING) != 0) {
+ rpz_st->ns.r_result = event->result;
+ result = rpz_st->q.result;
+ isc_event_free(ISC_EVENT_PTR(&event));
+ } else {
+ result = event->result;
+ }
resuming = ISC_TRUE;
-
goto resume;
}
@@ -3902,8 +5197,12 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
goto cleanup;
}
- if (is_zone)
+ is_staticstub_zone = ISC_FALSE;
+ if (is_zone && zone != NULL) {
authoritative = ISC_TRUE;
+ if (dns_zone_gettype(zone) == dns_zone_staticstub)
+ is_staticstub_zone = ISC_TRUE;
+ }
if (event == NULL && client->query.restarts == 0) {
if (is_zone) {
@@ -3956,6 +5255,119 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
resume:
CTRACE("query_find: resume");
+
+ if (!ISC_LIST_EMPTY(client->view->rpz_zones) &&
+ RECURSIONOK(client) && !RECURSING(client) &&
+ result != DNS_R_DELEGATION && result != ISC_R_NOTFOUND &&
+ (client->query.rpz_st == NULL ||
+ (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) &&
+ !dns_name_equal(client->query.qname, dns_rootname)) {
+ isc_result_t rresult;
+
+ rresult = rpz_rewrite(client, qtype, resuming);
+ rpz_st = client->query.rpz_st;
+ switch (rresult) {
+ case ISC_R_SUCCESS:
+ break;
+ case DNS_R_DELEGATION:
+ /*
+ * recursing for NS names or addresses,
+ * so save the main query state
+ */
+ rpz_st->q.qtype = qtype;
+ rpz_st->q.is_zone = is_zone;
+ rpz_st->q.authoritative = authoritative;
+ rpz_st->q.zone = zone;
+ zone = NULL;
+ rpz_st->q.db = db;
+ db = NULL;
+ rpz_st->q.node = node;
+ node = NULL;
+ rpz_st->q.rdataset = rdataset;
+ rdataset = NULL;
+ rpz_st->q.sigrdataset = sigrdataset;
+ sigrdataset = NULL;
+ dns_name_copy(fname, rpz_st->fname, NULL);
+ rpz_st->q.result = result;
+ client->query.attributes |= NS_QUERYATTR_RECURSING;
+ result = ISC_R_SUCCESS;
+ goto cleanup;
+ default:
+ RECURSE_ERROR(rresult);
+ goto cleanup;
+ }
+ if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS &&
+ rpz_st->m.policy != DNS_RPZ_POLICY_NO_OP) {
+ result = dns_name_copy(client->query.qname, fname,
+ NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ finish_rewrite:
+ rpz_clean(&zone, &db, &node, NULL);
+ if (rpz_st->m.rdataset != NULL) {
+ if (rdataset != NULL)
+ query_putrdataset(client, &rdataset);
+ rdataset = rpz_st->m.rdataset;
+ rpz_st->m.rdataset = NULL;
+ } else if (rdataset != NULL &&
+ dns_rdataset_isassociated(rdataset)) {
+ dns_rdataset_disassociate(rdataset);
+ }
+ node = rpz_st->m.node;
+ rpz_st->m.node = NULL;
+ db = rpz_st->m.db;
+ rpz_st->m.db = NULL;
+ zone = rpz_st->m.zone;
+ rpz_st->m.zone = NULL;
+
+ result = rpz_st->m.result;
+ switch (rpz_st->m.policy) {
+ case DNS_RPZ_POLICY_NXDOMAIN:
+ result = DNS_R_NXDOMAIN;
+ break;
+ case DNS_RPZ_POLICY_NODATA:
+ result = DNS_R_NXRRSET;
+ break;
+ case DNS_RPZ_POLICY_RECORD:
+ if (type == dns_rdatatype_any &&
+ result != DNS_R_CNAME &&
+ dns_rdataset_isassociated(rdataset))
+ dns_rdataset_disassociate(rdataset);
+ break;
+ case DNS_RPZ_POLICY_CNAME:
+ result = dns_name_copy(&rpz_st->m.rpz->cname,
+ fname, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ query_keepname(client, fname, dbuf);
+ result = query_add_cname(client,
+ client->query.qname,
+ fname,
+ dns_trust_authanswer,
+ rpz_st->m.ttl);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ ns_client_qnamereplace(client, fname);
+ fname = NULL;
+ client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC;
+ rpz_log(client);
+ want_restart = ISC_TRUE;
+ goto cleanup;
+ default:
+ INSIST(0);
+ }
+
+ /*
+ * Turn off DNSSEC because the results of a
+ * response policy zone cannot verify.
+ */
+ client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC;
+ if (sigrdataset != NULL &&
+ dns_rdataset_isassociated(sigrdataset))
+ dns_rdataset_disassociate(sigrdataset);
+ is_zone = ISC_TRUE;
+ rpz_log(client);
+ }
+ }
+
switch (result) {
case ISC_R_SUCCESS:
/*
@@ -4008,11 +5420,18 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
*/
if (RECURSIONOK(client)) {
result = query_recurse(client, qtype,
+ client->query.qname,
NULL, NULL, resuming);
- if (result == ISC_R_SUCCESS)
+ if (result == ISC_R_SUCCESS) {
client->query.attributes |=
NS_QUERYATTR_RECURSING;
- else
+ if (dns64)
+ client->query.attributes |=
+ NS_QUERYATTR_DNS64;
+ if (dns64_exclude)
+ client->query.attributes |=
+ NS_QUERYATTR_DNS64EXCLUDE;
+ } else
RECURSE_ERROR(result);
goto cleanup;
} else {
@@ -4143,12 +5562,22 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
}
} else {
if (zfname != NULL &&
- !dns_name_issubdomain(fname, zfname)) {
+ (!dns_name_issubdomain(fname, zfname) ||
+ (is_staticstub_zone &&
+ dns_name_equal(fname, zfname)))) {
/*
- * We've already got a delegation from
- * authoritative data, and it is better
- * than what we found in the cache. Use
- * it instead of the cache delegation.
+ * In the following cases use "authoritative"
+ * data instead of the cache delegation:
+ * 1. We've already got a delegation from
+ * authoritative data, and it is better
+ * than what we found in the cache.
+ * 2. The query name matches the origin name
+ * of a static-stub zone. This needs to be
+ * considered for the case where the NS of
+ * the static-stub zone and the cached NS
+ * are different. We still need to contact
+ * the nameservers configured in the
+ * static-stub zone.
*/
query_releasename(client, &fname);
fname = zfname;
@@ -4183,15 +5612,31 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
*/
if (dns_rdatatype_atparent(type))
result = query_recurse(client, qtype,
- NULL, NULL,
- resuming);
+ client->query.qname,
+ NULL, NULL, resuming);
+ else if (dns64)
+ result = query_recurse(client,
+ dns_rdatatype_a,
+ client->query.qname,
+ NULL, NULL, resuming);
else
result = query_recurse(client, qtype,
- fname, rdataset,
- resuming);
- if (result == ISC_R_SUCCESS)
+ client->query.qname,
+ fname, rdataset,
+ resuming);
+
+ if (result == ISC_R_SUCCESS) {
client->query.attributes |=
NS_QUERYATTR_RECURSING;
+ if (dns64)
+ client->query.attributes |=
+ NS_QUERYATTR_DNS64;
+ if (dns64_exclude)
+ client->query.attributes |=
+ NS_QUERYATTR_DNS64EXCLUDE;
+ } else if (result == DNS_R_DUPLICATE ||
+ result == DNS_R_DROP)
+ QUERY_ERROR(result);
else
RECURSE_ERROR(result);
} else {
@@ -4231,11 +5676,75 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
}
}
goto cleanup;
+
case DNS_R_EMPTYNAME:
- result = DNS_R_NXRRSET;
- /* FALLTHROUGH */
case DNS_R_NXRRSET:
+ nxrrset:
INSIST(is_zone);
+
+#ifdef dns64_bis_return_excluded_addresses
+ if (dns64)
+#else
+ if (dns64 && !dns64_exclude)
+#endif
+ {
+ /*
+ * Restore the answers from the previous AAAA lookup.
+ */
+ if (rdataset != NULL)
+ query_putrdataset(client, &rdataset);
+ if (sigrdataset != NULL)
+ query_putrdataset(client, &sigrdataset);
+ rdataset = client->query.dns64_aaaa;
+ sigrdataset = client->query.dns64_sigaaaa;
+ if (fname == NULL) {
+ dbuf = query_getnamebuf(client);
+ if (dbuf == NULL) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ fname = query_newname(client, dbuf, &b);
+ if (fname == NULL) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ }
+ dns_name_copy(client->query.qname, fname, NULL);
+ client->query.dns64_aaaa = NULL;
+ client->query.dns64_sigaaaa = NULL;
+ dns64 = ISC_FALSE;
+#ifdef dns64_bis_return_excluded_addresses
+ /*
+ * Resume the diverted processing of the AAAA response?
+ */
+ if (dns64_excluded)
+ break;
+#endif
+ } else if (result == DNS_R_NXRRSET &&
+ !ISC_LIST_EMPTY(client->view->dns64) &&
+ client->message->rdclass == dns_rdataclass_in &&
+ qtype == dns_rdatatype_aaaa)
+ {
+ /*
+ * Look to see if there are A records for this
+ * name.
+ */
+ INSIST(client->query.dns64_aaaa == NULL);
+ INSIST(client->query.dns64_sigaaaa == NULL);
+ client->query.dns64_aaaa = rdataset;
+ client->query.dns64_sigaaaa = sigrdataset;
+ client->query.dns64_ttl = dns64_ttl(db, version);
+ query_releasename(client, &fname);
+ dns_db_detachnode(db, &node);
+ rdataset = NULL;
+ sigrdataset = NULL;
+ type = qtype = dns_rdatatype_a;
+ dns64 = ISC_TRUE;
+ goto db_find;
+ }
+
+ result = DNS_R_NXRRSET;
+
/*
* Look for a NSEC3 record if we don't have a NSEC record.
*/
@@ -4258,10 +5767,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* instead? If so add the nearest to the
* closest provable encloser.
*/
- if (found &&
- dns_rdataset_isassociated(rdataset) &&
- !dns_name_equal(qname, found))
- {
+ if (dns_rdataset_isassociated(rdataset) &&
+ !dns_name_equal(qname, found)) {
unsigned int count;
unsigned int skip;
@@ -4328,7 +5835,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
/*
* Add SOA.
*/
- result = query_addsoa(client, db, version, ISC_FALSE,
+ result = query_addsoa(client, db, version, ISC_UINT32_MAX,
dns_rdataset_isassociated(rdataset));
if (result != ISC_R_SUCCESS) {
QUERY_ERROR(result);
@@ -4377,10 +5884,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
zone != NULL &&
#endif
dns_zone_getzeronosoattl(zone))
- result = query_addsoa(client, db, version, ISC_TRUE,
+ result = query_addsoa(client, db, version, 0,
dns_rdataset_isassociated(rdataset));
else
- result = query_addsoa(client, db, version, ISC_FALSE,
+ result = query_addsoa(client, db, version,
+ ISC_UINT32_MAX,
dns_rdataset_isassociated(rdataset));
if (result != ISC_R_SUCCESS) {
QUERY_ERROR(result);
@@ -4411,6 +5919,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
case DNS_R_NCACHENXDOMAIN:
case DNS_R_NCACHENXRRSET:
+ ncache_nxrrset:
INSIST(!is_zone);
authoritative = ISC_FALSE;
/*
@@ -4426,6 +5935,74 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
client->message->rdclass == dns_rdataclass_in &&
dns_name_countlabels(fname) == 7)
warn_rfc1918(client, fname, rdataset);
+
+#ifdef dns64_bis_return_excluded_addresses
+ if (dns64)
+#else
+ if (dns64 && !dns64_exclude)
+#endif
+ {
+ /*
+ * Restore the answers from the previous AAAA lookup.
+ */
+ if (rdataset != NULL)
+ query_putrdataset(client, &rdataset);
+ if (sigrdataset != NULL)
+ query_putrdataset(client, &sigrdataset);
+ rdataset = client->query.dns64_aaaa;
+ sigrdataset = client->query.dns64_sigaaaa;
+ if (fname == NULL) {
+ dbuf = query_getnamebuf(client);
+ if (dbuf == NULL) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ fname = query_newname(client, dbuf, &b);
+ if (fname == NULL) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ }
+ dns_name_copy(client->query.qname, fname, NULL);
+ client->query.dns64_aaaa = NULL;
+ client->query.dns64_sigaaaa = NULL;
+ dns64 = ISC_FALSE;
+#ifdef dns64_bis_return_excluded_addresses
+ if (dns64_excluded)
+ break;
+#endif
+ } else if (result == DNS_R_NCACHENXRRSET &&
+ !ISC_LIST_EMPTY(client->view->dns64) &&
+ client->message->rdclass == dns_rdataclass_in &&
+ qtype == dns_rdatatype_aaaa)
+ {
+ /*
+ * Look to see if there are A records for this
+ * name.
+ */
+ INSIST(client->query.dns64_aaaa == NULL);
+ INSIST(client->query.dns64_sigaaaa == NULL);
+ client->query.dns64_aaaa = rdataset;
+ client->query.dns64_sigaaaa = sigrdataset;
+ /*
+ * If the ttl is zero we need to workout if we have just
+ * decremented to zero or if there was no negative cache
+ * ttl in the answer.
+ */
+ if (rdataset->ttl != 0)
+ client->query.dns64_ttl = rdataset->ttl;
+ else if (dns_rdataset_first(rdataset) == ISC_R_SUCCESS)
+ client->query.dns64_ttl = 0;
+ query_releasename(client, &fname);
+ dns_db_detachnode(db, &node);
+ rdataset = NULL;
+ sigrdataset = NULL;
+ fname = NULL;
+ type = qtype = dns_rdatatype_a;
+ dns64 = ISC_TRUE;
+ goto db_find;
+ }
+
/*
* We don't call query_addrrset() because we don't need any
* of its extra features (and things would probably break!).
@@ -4562,11 +6139,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_message_puttempname(client->message, &tname);
goto cleanup;
}
- dns_name_init(tname, NULL);
dns_name_clone(&dname.dname, tname);
dns_rdata_freestruct(&dname);
/*
- * Construct the new qname.
+ * Construct the new qname consisting of
+ * <found name prefix>.<dname target>
*/
dns_fixedname_init(&fixed);
prefix = dns_fixedname_name(&fixed);
@@ -4583,8 +6160,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
goto cleanup;
}
result = dns_name_concatenate(prefix, tname, fname, NULL);
+ dns_message_puttempname(client->message, &tname);
if (result != ISC_R_SUCCESS) {
- dns_message_puttempname(client->message, &tname);
if (result == ISC_R_NOSPACE) {
/*
* RFC2672, section 4.1, subsection 3c says
@@ -4597,11 +6174,12 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
}
query_keepname(client, fname, dbuf);
/*
- * Synthesize a CNAME for this DNAME.
+ * Synthesize a CNAME consisting of
+ * <old qname> <dname ttl> CNAME <new qname>
+ * with <dname trust value>
*
- * We want to synthesize a CNAME since if we don't
- * then older software that doesn't understand DNAME
- * will not chain like it should.
+ * Synthesize a CNAME so old old clients that don't understand
+ * DNAME can chain.
*
* We do not try to synthesize a signature because we hope
* that security aware servers will understand DNAME. Also,
@@ -4609,12 +6187,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* on-the-fly is costly, and not really legitimate anyway
* since the synthesized CNAME is NOT in the zone.
*/
- dns_name_init(tname, NULL);
- (void)query_addcnamelike(client, client->query.qname, fname,
- trdataset, &tname,
- dns_rdatatype_cname);
- if (tname != NULL)
- dns_message_puttempname(client->message, &tname);
+ result = query_add_cname(client, client->query.qname, fname,
+ trdataset->trust, trdataset->ttl);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
/*
* Switch to the new qname and restart.
*/
@@ -4641,6 +6217,28 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
}
if (type == dns_rdatatype_any) {
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ isc_boolean_t have_aaaa, have_a, have_sig, filter_aaaa;
+
+ /*
+ * The filter-aaaa-on-v4 option should
+ * suppress AAAAs for IPv4 clients if there is an A.
+ * If we are not authoritative, assume there is a A
+ * even in if it is not in our cache. This assumption could
+ * be wrong but it is a good bet.
+ */
+ have_aaaa = ISC_FALSE;
+ have_a = !authoritative;
+ have_sig = ISC_FALSE;
+ if (client->view->v4_aaaa != dns_v4_aaaa_ok &&
+ is_v4_client(client) &&
+ ns_client_checkaclsilent(client, NULL,
+ client->view->v4_aaaa_acl,
+ ISC_TRUE) == ISC_R_SUCCESS)
+ filter_aaaa = ISC_TRUE;
+ else
+ filter_aaaa = ISC_FALSE;
+#endif
/*
* XXXRTH Need to handle zonecuts with special case
* code.
@@ -4652,6 +6250,54 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
+
+ /*
+ * Check all A and AAAA records in all response policy
+ * IP address zones
+ */
+ rpz_st = client->query.rpz_st;
+ if (rpz_st != NULL &&
+ (rpz_st->state & DNS_RPZ_DONE_QNAME) != 0 &&
+ (rpz_st->state & DNS_RPZ_REWRITTEN) == 0 &&
+ RECURSIONOK(client) && !RECURSING(client) &&
+ (rpz_st->state & DNS_RPZ_HAVE_IP) != 0) {
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, rdataset);
+ if (rdataset->type == dns_rdatatype_a ||
+ rdataset->type == dns_rdatatype_aaaa)
+ result = rpz_rewrite_ip(client,
+ rdataset,
+ DNS_RPZ_TYPE_IP);
+ dns_rdataset_disassociate(rdataset);
+ if (result != ISC_R_SUCCESS)
+ break;
+ }
+ if (result != ISC_R_NOMORE) {
+ dns_rdatasetiter_destroy(&rdsiter);
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ switch (rpz_st->m.policy) {
+ case DNS_RPZ_POLICY_MISS:
+ break;
+ case DNS_RPZ_POLICY_NO_OP:
+ rpz_log(client);
+ rpz_st->state |= DNS_RPZ_REWRITTEN;
+ break;
+ case DNS_RPZ_POLICY_NXDOMAIN:
+ case DNS_RPZ_POLICY_NODATA:
+ case DNS_RPZ_POLICY_RECORD:
+ case DNS_RPZ_POLICY_CNAME:
+ dns_rdatasetiter_destroy(&rdsiter);
+ rpz_st->state |= DNS_RPZ_REWRITTEN;
+ goto finish_rewrite;
+ default:
+ INSIST(0);
+ }
+ }
+
/*
* Calling query_addrrset() with a non-NULL dbuf is going
* to either keep or release the name. We don't want it to
@@ -4668,6 +6314,18 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
result = dns_rdatasetiter_first(rdsiter);
while (result == ISC_R_SUCCESS) {
dns_rdatasetiter_current(rdsiter, rdataset);
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ /*
+ * Notice the presence of A and AAAAs so
+ * that AAAAs can be hidden from IPv4 clients.
+ */
+ if (filter_aaaa) {
+ if (rdataset->type == dns_rdatatype_aaaa)
+ have_aaaa = ISC_TRUE;
+ else if (rdataset->type == dns_rdatatype_a)
+ have_a = ISC_TRUE;
+ }
+#endif
if (is_zone && qtype == dns_rdatatype_any &&
!dns_db_issecure(db) &&
dns_rdatatype_isdnssec(rdataset->type)) {
@@ -4679,6 +6337,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_rdataset_disassociate(rdataset);
} else if ((qtype == dns_rdatatype_any ||
rdataset->type == qtype) && rdataset->type != 0) {
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ if (dns_rdatatype_isdnssec(rdataset->type))
+ have_sig = ISC_TRUE;
+#endif
if (NOQNAME(rdataset) && WANTDNSSEC(client))
noqname = rdataset;
else
@@ -4709,6 +6371,16 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
result = dns_rdatasetiter_next(rdsiter);
}
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ /*
+ * Filter AAAAs if there is an A and there is no signature
+ * or we are supposed to break DNSSEC.
+ */
+ if (filter_aaaa && have_aaaa && have_a &&
+ (!have_sig || !WANTDNSSEC(client) ||
+ client->view->v4_aaaa == dns_v4_aaaa_break_dnssec))
+ client->attributes |= NS_CLIENTATTR_FILTER_AAAA;
+#endif
if (fname != NULL)
dns_message_puttempname(client->message, &fname);
@@ -4742,10 +6414,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_rdatasetiter_destroy(&rdsiter);
if (RECURSIONOK(client)) {
result = query_recurse(client,
- qtype,
- NULL,
- NULL,
- resuming);
+ qtype,
+ client->query.qname,
+ NULL, NULL,
+ resuming);
if (result == ISC_R_SUCCESS)
client->query.attributes |=
NS_QUERYATTR_RECURSING;
@@ -4763,7 +6435,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* Add SOA.
*/
result = query_addsoa(client, db, version,
- ISC_FALSE, ISC_FALSE);
+ ISC_UINT32_MAX,
+ ISC_FALSE);
if (result == ISC_R_SUCCESS)
result = ISC_R_NOMORE;
} else {
@@ -4783,6 +6456,162 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* This is the "normal" case -- an ordinary question to which
* we know the answer.
*/
+
+ /*
+ * Check all A and AAAA records in all response policy
+ * IP address zones
+ */
+ rpz_st = client->query.rpz_st;
+ if (rpz_st != NULL &&
+ (rpz_st->state & DNS_RPZ_DONE_QNAME) != 0 &&
+ (rpz_st->state & DNS_RPZ_REWRITTEN) == 0 &&
+ RECURSIONOK(client) && !RECURSING(client) &&
+ (rpz_st->state & DNS_RPZ_HAVE_IP) != 0 &&
+ (qtype == dns_rdatatype_aaaa || qtype == dns_rdatatype_a)) {
+ result = rpz_rewrite_ip(client, rdataset,
+ DNS_RPZ_TYPE_IP);
+ if (result != ISC_R_SUCCESS) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ /*
+ * After a hit in the radix tree for the policy domain,
+ * either stop trying to rewrite (DNS_RPZ_POLICY_NO_OP)
+ * or restart to ask the ordinary database of the
+ * policy zone for the DNS record corresponding to the
+ * record in the radix tree.
+ */
+ switch (rpz_st->m.policy) {
+ case DNS_RPZ_POLICY_MISS:
+ break;
+ case DNS_RPZ_POLICY_NO_OP:
+ rpz_log(client);
+ rpz_st->state |= DNS_RPZ_REWRITTEN;
+ break;
+ case DNS_RPZ_POLICY_NXDOMAIN:
+ case DNS_RPZ_POLICY_NODATA:
+ case DNS_RPZ_POLICY_RECORD:
+ case DNS_RPZ_POLICY_CNAME:
+ rpz_st->state |= DNS_RPZ_REWRITTEN;
+ goto finish_rewrite;
+ default:
+ INSIST(0);
+ }
+ }
+
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ /*
+ * Optionally hide AAAAs from IPv4 clients if there is an A.
+ * We add the AAAAs now, but might refuse to render them later
+ * after DNSSEC is figured out.
+ * This could be more efficient, but the whole idea is
+ * so fundamentally wrong, unavoidably inaccurate, and
+ * unneeded that it is best to keep it as short as possible.
+ */
+ if (client->view->v4_aaaa != dns_v4_aaaa_ok &&
+ is_v4_client(client) &&
+ ns_client_checkaclsilent(client, NULL,
+ client->view->v4_aaaa_acl,
+ ISC_TRUE) == ISC_R_SUCCESS &&
+ (!WANTDNSSEC(client) ||
+ sigrdataset == NULL ||
+ !dns_rdataset_isassociated(sigrdataset) ||
+ client->view->v4_aaaa == dns_v4_aaaa_break_dnssec)) {
+ if (qtype == dns_rdatatype_aaaa) {
+ trdataset = query_newrdataset(client);
+ result = dns_db_findrdataset(db, node, version,
+ dns_rdatatype_a, 0,
+ client->now,
+ trdataset, NULL);
+ if (dns_rdataset_isassociated(trdataset))
+ dns_rdataset_disassociate(trdataset);
+ query_putrdataset(client, &trdataset);
+
+ /*
+ * We have an AAAA but the A is not in our cache.
+ * Assume any result other than DNS_R_DELEGATION
+ * or ISC_R_NOTFOUND means there is no A and
+ * so AAAAs are ok.
+ * Assume there is no A if we can't recurse
+ * for this client, although that could be
+ * the wrong answer. What else can we do?
+ * Besides, that we have the AAAA and are using
+ * this mechanism suggests that we care more
+ * about As than AAAAs and would have cached
+ * the A if it existed.
+ */
+ if (result == ISC_R_SUCCESS) {
+ client->attributes |=
+ NS_CLIENTATTR_FILTER_AAAA;
+
+ } else if (authoritative ||
+ !RECURSIONOK(client) ||
+ (result != DNS_R_DELEGATION &&
+ result != ISC_R_NOTFOUND)) {
+ client->attributes &=
+ ~NS_CLIENTATTR_FILTER_AAAA;
+ } else {
+ /*
+ * This is an ugly kludge to recurse
+ * for the A and discard the result.
+ *
+ * Continue to add the AAAA now.
+ * We'll make a note to not render it
+ * if the recursion for the A succeeds.
+ */
+ result = query_recurse(client,
+ dns_rdatatype_a,
+ client->query.qname,
+ NULL, NULL, resuming);
+ if (result == ISC_R_SUCCESS) {
+ client->attributes |=
+ NS_CLIENTATTR_FILTER_AAAA_RC;
+ client->query.attributes |=
+ NS_QUERYATTR_RECURSING;
+ }
+ }
+
+ } else if (qtype == dns_rdatatype_a &&
+ (client->attributes &
+ NS_CLIENTATTR_FILTER_AAAA_RC) != 0) {
+ client->attributes &=
+ ~NS_CLIENTATTR_FILTER_AAAA_RC;
+ client->attributes |=
+ NS_CLIENTATTR_FILTER_AAAA;
+ dns_rdataset_disassociate(rdataset);
+ if (sigrdataset != NULL &&
+ dns_rdataset_isassociated(sigrdataset))
+ dns_rdataset_disassociate(sigrdataset);
+ goto cleanup;
+ }
+ }
+#endif
+ /*
+ * Check to see if the AAAA RRset has non-excluded addresses
+ * in it. If not look for a A RRset.
+ */
+ INSIST(client->query.dns64_aaaaok == NULL);
+
+ if (qtype == dns_rdatatype_aaaa && !dns64_exclude &&
+ !ISC_LIST_EMPTY(client->view->dns64) &&
+ client->message->rdclass == dns_rdataclass_in &&
+ !dns64_aaaaok(client, rdataset, sigrdataset)) {
+ /*
+ * Look to see if there are A records for this
+ * name.
+ */
+ client->query.dns64_aaaa = rdataset;
+ client->query.dns64_sigaaaa = sigrdataset;
+ client->query.dns64_ttl = rdataset->ttl;
+ query_releasename(client, &fname);
+ dns_db_detachnode(db, &node);
+ rdataset = NULL;
+ sigrdataset = NULL;
+ type = qtype = dns_rdatatype_a;
+ dns64_exclude = dns64 = ISC_TRUE;
+ goto db_find;
+ }
+
if (sigrdataset != NULL)
sigrdatasetp = &sigrdataset;
else
@@ -4798,8 +6627,43 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_name_equal(client->query.qname, dns_rootname))
client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL;
- query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf,
- DNS_SECTION_ANSWER);
+ if (dns64) {
+ qtype = type = dns_rdatatype_aaaa;
+ result = query_dns64(client, &fname, rdataset,
+ sigrdataset, dbuf,
+ DNS_SECTION_ANSWER);
+ dns_rdataset_disassociate(rdataset);
+ dns_message_puttemprdataset(client->message, &rdataset);
+ if (result == ISC_R_NOMORE) {
+#ifndef dns64_bis_return_excluded_addresses
+ if (dns64_exclude) {
+ if (!is_zone)
+ goto cleanup;
+ /*
+ * Add a fake SOA record.
+ */
+ result = query_addsoa(client, db,
+ version, 600,
+ ISC_FALSE);
+ goto cleanup;
+ }
+#endif
+ if (is_zone)
+ goto nxrrset;
+ else
+ goto ncache_nxrrset;
+ } else if (result != ISC_R_SUCCESS) {
+ eresult = result;
+ goto cleanup;
+ }
+ } else if (client->query.dns64_aaaaok != NULL) {
+ query_filter64(client, &fname, rdataset, dbuf,
+ DNS_SECTION_ANSWER);
+ query_putrdataset(client, &rdataset);
+ } else
+ query_addrrset(client, &fname, &rdataset,
+ sigrdatasetp, dbuf, DNS_SECTION_ANSWER);
+
if (noqname != NULL)
query_addnoqnameproof(client, noqname);
/*
@@ -4842,6 +6706,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
/*
* General cleanup.
*/
+ rpz_st = client->query.rpz_st;
+ if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0)
+ rpz_clean(&rpz_st->m.zone, &rpz_st->m.db, &rpz_st->m.node,
+ &rpz_st->m.rdataset);
if (rdataset != NULL)
query_putrdataset(client, &rdataset);
if (sigrdataset != NULL)
@@ -4949,6 +6817,7 @@ log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
char namebuf[DNS_NAME_FORMATSIZE];
char typename[DNS_RDATATYPE_FORMATSIZE];
char classname[DNS_RDATACLASS_FORMATSIZE];
+ char onbuf[ISC_NETADDR_FORMATSIZE];
dns_rdataset_t *rdataset;
int level = ISC_LOG_INFO;
@@ -4960,14 +6829,18 @@ log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
dns_rdataclass_format(rdataset->rdclass, classname, sizeof(classname));
dns_rdatatype_format(rdataset->type, typename, sizeof(typename));
+ isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf));
ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
- level, "query: %s %s %s %s%s%s%s%s", namebuf, classname,
- typename, WANTRECURSION(client) ? "+" : "-",
+ level, "query: %s %s %s %s%s%s%s%s%s (%s)", namebuf,
+ classname, typename, WANTRECURSION(client) ? "+" : "-",
(client->signer != NULL) ? "S": "",
(client->opt != NULL) ? "E" : "",
+ ((client->attributes & NS_CLIENTATTR_TCP) != 0) ?
+ "T" : "",
((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "",
- ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "");
+ ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "",
+ onbuf);
}
static inline void
diff --git a/bin/named/server.c b/bin/named/server.c
index bc7fc17c3296..5bbf94b9b604 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.c,v 1.520.12.21 2011-01-14 23:45:49 tbox Exp $ */
+/* $Id: server.c,v 1.599.8.4 2011-02-16 19:46:12 each Exp $ */
/*! \file */
@@ -23,6 +23,10 @@
#include <stdlib.h>
#include <unistd.h>
+#include <limits.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <isc/app.h>
#include <isc/base64.h>
@@ -36,7 +40,9 @@
#include <isc/portset.h>
#include <isc/print.h>
#include <isc/resource.h>
+#include <isc/sha2.h>
#include <isc/socket.h>
+#include <isc/stat.h>
#include <isc/stats.h>
#include <isc/stdio.h>
#include <isc/string.h>
@@ -57,9 +63,11 @@
#ifdef DLZ
#include <dns/dlz.h>
#endif
+#include <dns/dns64.h>
#include <dns/forward.h>
#include <dns/journal.h>
#include <dns/keytable.h>
+#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/master.h>
#include <dns/masterdump.h>
@@ -102,6 +110,10 @@
#include <stdlib.h>
#endif
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
/*%
* Check an operation for failure. Assumes that the function
* using it has a 'result' variable and a 'cleanup' label.
@@ -143,6 +155,14 @@
fatal(msg, result); \
} while (0) \
+/*%
+ * Maximum ADB size for views that share a cache. Use this limit to suppress
+ * the total of memory footprint, which should be the main reason for sharing
+ * a cache. Only effective when a finite max-cache-size is specified.
+ * This is currently defined to be 8MB.
+ */
+#define MAX_ADB_SIZE_FOR_CACHESHARE 8388608
+
struct ns_dispatch {
isc_sockaddr_t addr;
unsigned int dispatchgen;
@@ -150,6 +170,14 @@ struct ns_dispatch {
ISC_LINK(struct ns_dispatch) link;
};
+struct ns_cache {
+ dns_cache_t *cache;
+ dns_view_t *primaryview;
+ isc_boolean_t needflush;
+ isc_boolean_t adbsizeadjusted;
+ ISC_LINK(ns_cache_t) link;
+};
+
struct dumpcontext {
isc_mem_t *mctx;
isc_boolean_t dumpcache;
@@ -176,6 +204,17 @@ struct zonelistentry {
ISC_LINK(struct zonelistentry) link;
};
+/*%
+ * Configuration context to retain for each view that allows
+ * new zones to be added at runtime
+ */
+struct cfg_context {
+ isc_mem_t * mctx;
+ cfg_obj_t * config;
+ cfg_parser_t * parser;
+ cfg_aclconfctx_t actx;
+};
+
/*
* These zones should not leak onto the Internet.
*/
@@ -230,8 +269,8 @@ static const struct {
{ NULL, ISC_FALSE }
};
-static void
-fatal(const char *msg, isc_result_t result);
+ISC_PLATFORM_NORETURN_PRE static void
+fatal(const char *msg, isc_result_t result) ISC_PLATFORM_NORETURN_POST;
static void
ns_server_reload(isc_task_t *task, isc_event_t *event);
@@ -256,19 +295,25 @@ configure_alternates(const cfg_obj_t *config, dns_view_t *view,
static isc_result_t
configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
- cfg_aclconfctx_t *aclconf);
+ cfg_aclconfctx_t *aclconf, isc_boolean_t added);
+
+static isc_result_t
+add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx);
static void
end_reserved_dispatches(ns_server_t *server, isc_boolean_t all);
+static void
+cfgctx_destroy(void **cfgp);
+
/*%
* Configure a single view ACL at '*aclp'. Get its configuration from
* 'vconfig' (for per-view configuration) and maybe from 'config'
*/
static isc_result_t
configure_view_acl(const cfg_obj_t *vconfig, const cfg_obj_t *config,
- const char *aclname, cfg_aclconfctx_t *actx,
- isc_mem_t *mctx, dns_acl_t **aclp)
+ const char *aclname, const char *acltuplename,
+ cfg_aclconfctx_t *actx, isc_mem_t *mctx, dns_acl_t **aclp)
{
isc_result_t result;
const cfg_obj_t *maps[3];
@@ -294,13 +339,21 @@ configure_view_acl(const cfg_obj_t *vconfig, const cfg_obj_t *config,
*/
return (ISC_R_SUCCESS);
+ if (acltuplename != NULL) {
+ /*
+ * If the ACL is given in an optional tuple, retrieve it.
+ * The parser should have ensured that a valid object be
+ * returned.
+ */
+ aclobj = cfg_tuple_get(aclobj, acltuplename);
+ }
+
result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx,
actx, mctx, 0, aclp);
return (result);
}
-
/*%
* Configure a sortlist at '*aclp'. Essentially the same as
* configure_view_acl() except it calls cfg_acl_fromconfig with a
@@ -345,8 +398,88 @@ configure_view_sortlist(const cfg_obj_t *vconfig, const cfg_obj_t *config,
}
static isc_result_t
-configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
- dns_keytable_t *keytable, isc_mem_t *mctx)
+configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
+ const char *confname, const char *conftuplename,
+ isc_mem_t *mctx, dns_rbt_t **rbtp)
+{
+ isc_result_t result;
+ const cfg_obj_t *maps[3];
+ const cfg_obj_t *obj = NULL;
+ const cfg_listelt_t *element;
+ int i = 0;
+ dns_fixedname_t fixed;
+ dns_name_t *name;
+ isc_buffer_t b;
+ const char *str;
+ const cfg_obj_t *nameobj;
+
+ if (*rbtp != NULL)
+ dns_rbt_destroy(rbtp);
+ if (vconfig != NULL)
+ maps[i++] = cfg_tuple_get(vconfig, "options");
+ if (config != NULL) {
+ const cfg_obj_t *options = NULL;
+ (void)cfg_map_get(config, "options", &options);
+ if (options != NULL)
+ maps[i++] = options;
+ }
+ maps[i] = NULL;
+
+ (void)ns_config_get(maps, confname, &obj);
+ if (obj == NULL)
+ /*
+ * No value available. *rbtp == NULL.
+ */
+ return (ISC_R_SUCCESS);
+
+ if (conftuplename != NULL) {
+ obj = cfg_tuple_get(obj, conftuplename);
+ if (cfg_obj_isvoid(obj))
+ return (ISC_R_SUCCESS);
+ }
+
+ result = dns_rbt_create(mctx, NULL, NULL, rbtp);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+ for (element = cfg_list_first(obj);
+ element != NULL;
+ element = cfg_list_next(element)) {
+ nameobj = cfg_listelt_value(element);
+ str = cfg_obj_asstring(nameobj);
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
+ /*
+ * We don't need the node data, but need to set dummy data to
+ * avoid a partial match with an empty node. For example, if
+ * we have foo.example.com and bar.example.com, we'd get a match
+ * for baz.example.com, which is not the expected result.
+ * We simply use (void *)1 as the dummy data.
+ */
+ result = dns_rbt_addname(*rbtp, name, (void *)1);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(nameobj, ns_g_lctx, ISC_LOG_ERROR,
+ "failed to add %s for %s: %s",
+ str, confname, isc_result_totext(result));
+ goto cleanup;
+ }
+
+ }
+
+ return (result);
+
+ cleanup:
+ dns_rbt_destroy(rbtp);
+ return (result);
+
+}
+
+static isc_result_t
+dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key,
+ isc_boolean_t managed, dst_key_t **target, isc_mem_t *mctx)
{
dns_rdataclass_t viewclass;
dns_rdata_dnskey_t keystruct;
@@ -363,12 +496,28 @@ configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
isc_result_t result;
dst_key_t *dstkey = NULL;
+ INSIST(target != NULL && *target == NULL);
+
flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol"));
alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm"));
keyname = dns_fixedname_name(&fkeyname);
keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
+ if (managed) {
+ const char *initmethod;
+ initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init"));
+
+ if (strcasecmp(initmethod, "initial-key") != 0) {
+ cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
+ "managed key '%s': "
+ "invalid initialization method '%s'",
+ keynamestr, initmethod);
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+ }
+
if (vconfig == NULL)
viewclass = dns_rdataclass_in;
else {
@@ -408,7 +557,8 @@ configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
keystruct.algorithm == DST_ALG_RSAMD5) &&
r.length > 1 && r.base[0] == 1 && r.base[1] == 3)
cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
- "trusted key '%s' has a weak exponent",
+ "%s key '%s' has a weak exponent",
+ managed ? "managed" : "trusted",
keynamestr);
CHECK(dns_rdata_fromstruct(NULL,
@@ -418,25 +568,28 @@ configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
dns_fixedname_init(&fkeyname);
isc_buffer_init(&namebuf, keynamestr, strlen(keynamestr));
isc_buffer_add(&namebuf, strlen(keynamestr));
- CHECK(dns_name_fromtext(keyname, &namebuf,
- dns_rootname, ISC_FALSE,
- NULL));
+ CHECK(dns_name_fromtext(keyname, &namebuf, dns_rootname, 0, NULL));
CHECK(dst_key_fromdns(keyname, viewclass, &rrdatabuf,
mctx, &dstkey));
- CHECK(dns_keytable_add(keytable, &dstkey));
- INSIST(dstkey == NULL);
+ *target = dstkey;
return (ISC_R_SUCCESS);
cleanup:
if (result == DST_R_NOCRYPTO) {
cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
- "ignoring trusted key for '%s': no crypto support",
+ "ignoring %s key for '%s': no crypto support",
+ managed ? "managed" : "trusted",
keynamestr);
- result = ISC_R_SUCCESS;
+ } else if (result == DST_R_UNSUPPORTEDALG) {
+ cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
+ "skipping %s key for '%s': %s",
+ managed ? "managed" : "trusted",
+ keynamestr, isc_result_totext(result));
} else {
cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
- "configuring trusted key for '%s': %s",
+ "configuring %s key for '%s': %s",
+ managed ? "managed" : "trusted",
keynamestr, isc_result_totext(result));
result = ISC_R_FAILURE;
}
@@ -447,63 +600,215 @@ configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
return (result);
}
+static isc_result_t
+load_view_keys(const cfg_obj_t *keys, const cfg_obj_t *vconfig,
+ dns_view_t *view, isc_boolean_t managed,
+ dns_name_t *keyname, isc_mem_t *mctx)
+{
+ const cfg_listelt_t *elt, *elt2;
+ const cfg_obj_t *key, *keylist;
+ dst_key_t *dstkey = NULL;
+ isc_result_t result;
+ dns_keytable_t *secroots = NULL;
+
+ CHECK(dns_view_getsecroots(view, &secroots));
+
+ for (elt = cfg_list_first(keys);
+ elt != NULL;
+ elt = cfg_list_next(elt)) {
+ keylist = cfg_listelt_value(elt);
+
+ for (elt2 = cfg_list_first(keylist);
+ elt2 != NULL;
+ elt2 = cfg_list_next(elt2)) {
+ key = cfg_listelt_value(elt2);
+ result = dstkey_fromconfig(vconfig, key, managed,
+ &dstkey, mctx);
+ if (result == DST_R_UNSUPPORTEDALG) {
+ result = ISC_R_SUCCESS;
+ continue;
+ }
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /*
+ * If keyname was specified, we only add that key.
+ */
+ if (keyname != NULL &&
+ !dns_name_equal(keyname, dst_key_name(dstkey)))
+ {
+ dst_key_free(&dstkey);
+ continue;
+ }
+
+ CHECK(dns_keytable_add(secroots, managed, &dstkey));
+ }
+ }
+
+ cleanup:
+ if (dstkey != NULL)
+ dst_key_free(&dstkey);
+ if (secroots != NULL)
+ dns_keytable_detach(&secroots);
+ if (result == DST_R_NOCRYPTO)
+ result = ISC_R_SUCCESS;
+ return (result);
+}
+
/*%
- * Configure DNSSEC keys for a view. Currently used only for
- * the security roots.
+ * Configure DNSSEC keys for a view.
*
* The per-view configuration values and the server-global defaults are read
- * from 'vconfig' and 'config'. The variable to be configured is '*target'.
+ * from 'vconfig' and 'config'.
*/
static isc_result_t
-configure_view_dnsseckeys(const cfg_obj_t *vconfig, const cfg_obj_t *config,
- isc_mem_t *mctx, dns_keytable_t **target)
+configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
+ const cfg_obj_t *config, const cfg_obj_t *bindkeys,
+ isc_boolean_t auto_dlv, isc_boolean_t auto_root,
+ isc_mem_t *mctx)
{
- isc_result_t result;
- const cfg_obj_t *keys = NULL;
+ isc_result_t result = ISC_R_SUCCESS;
+ const cfg_obj_t *view_keys = NULL;
+ const cfg_obj_t *global_keys = NULL;
+ const cfg_obj_t *view_managed_keys = NULL;
+ const cfg_obj_t *global_managed_keys = NULL;
+ const cfg_obj_t *maps[4];
const cfg_obj_t *voptions = NULL;
- const cfg_listelt_t *element, *element2;
- const cfg_obj_t *keylist;
- const cfg_obj_t *key;
- dns_keytable_t *keytable = NULL;
+ const cfg_obj_t *options = NULL;
+ const cfg_obj_t *obj = NULL;
+ const char *directory;
+ int i = 0;
- CHECK(dns_keytable_create(mctx, &keytable));
+ /* We don't need trust anchors for the _bind view */
+ if (strcmp(view->name, "_bind") == 0 &&
+ view->rdclass == dns_rdataclass_chaos) {
+ return (ISC_R_SUCCESS);
+ }
- if (vconfig != NULL)
+ if (vconfig != NULL) {
voptions = cfg_tuple_get(vconfig, "options");
+ if (voptions != NULL) {
+ (void) cfg_map_get(voptions, "trusted-keys",
+ &view_keys);
+ (void) cfg_map_get(voptions, "managed-keys",
+ &view_managed_keys);
+ maps[i++] = voptions;
+ }
+ }
- keys = NULL;
- if (voptions != NULL)
- (void)cfg_map_get(voptions, "trusted-keys", &keys);
- if (keys == NULL)
- (void)cfg_map_get(config, "trusted-keys", &keys);
+ if (config != NULL) {
+ (void)cfg_map_get(config, "trusted-keys", &global_keys);
+ (void)cfg_map_get(config, "managed-keys", &global_managed_keys);
+ (void)cfg_map_get(config, "options", &options);
+ if (options != NULL) {
+ maps[i++] = options;
+ }
+ }
- for (element = cfg_list_first(keys);
- element != NULL;
- element = cfg_list_next(element))
- {
- keylist = cfg_listelt_value(element);
- for (element2 = cfg_list_first(keylist);
- element2 != NULL;
- element2 = cfg_list_next(element2))
- {
- key = cfg_listelt_value(element2);
- CHECK(configure_view_dnsseckey(vconfig, key,
- keytable, mctx));
+ maps[i++] = ns_g_defaults;
+ maps[i] = NULL;
+
+ result = dns_view_initsecroots(view, mctx);
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "couldn't create keytable");
+ return (ISC_R_UNEXPECTED);
+ }
+
+ if (auto_dlv && view->rdclass == dns_rdataclass_in) {
+ const cfg_obj_t *builtin_keys = NULL;
+ const cfg_obj_t *builtin_managed_keys = NULL;
+
+ isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "using built-in DLV key for view %s",
+ view->name);
+
+ /*
+ * If bind.keys exists, it overrides the managed-keys
+ * clause hard-coded in ns_g_config.
+ */
+ if (bindkeys != NULL) {
+ (void)cfg_map_get(bindkeys, "trusted-keys",
+ &builtin_keys);
+ (void)cfg_map_get(bindkeys, "managed-keys",
+ &builtin_managed_keys);
+ } else {
+ (void)cfg_map_get(ns_g_config, "trusted-keys",
+ &builtin_keys);
+ (void)cfg_map_get(ns_g_config, "managed-keys",
+ &builtin_managed_keys);
}
+
+ if (builtin_keys != NULL)
+ CHECK(load_view_keys(builtin_keys, vconfig, view,
+ ISC_FALSE, view->dlv, mctx));
+ if (builtin_managed_keys != NULL)
+ CHECK(load_view_keys(builtin_managed_keys, vconfig,
+ view, ISC_TRUE, view->dlv, mctx));
}
- dns_keytable_detach(target);
- *target = keytable; /* Transfer ownership. */
- keytable = NULL;
- result = ISC_R_SUCCESS;
+ if (auto_root && view->rdclass == dns_rdataclass_in) {
+ const cfg_obj_t *builtin_keys = NULL;
+ const cfg_obj_t *builtin_managed_keys = NULL;
- cleanup:
+ isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "using built-in root key for view %s",
+ view->name);
+
+ /*
+ * If bind.keys exists, it overrides the managed-keys
+ * clause hard-coded in ns_g_config.
+ */
+ if (bindkeys != NULL) {
+ (void)cfg_map_get(bindkeys, "trusted-keys",
+ &builtin_keys);
+ (void)cfg_map_get(bindkeys, "managed-keys",
+ &builtin_managed_keys);
+ } else {
+ (void)cfg_map_get(ns_g_config, "trusted-keys",
+ &builtin_keys);
+ (void)cfg_map_get(ns_g_config, "managed-keys",
+ &builtin_managed_keys);
+ }
+
+ if (builtin_keys != NULL)
+ CHECK(load_view_keys(builtin_keys, vconfig, view,
+ ISC_FALSE, dns_rootname, mctx));
+ if (builtin_managed_keys != NULL)
+ CHECK(load_view_keys(builtin_managed_keys, vconfig,
+ view, ISC_TRUE, dns_rootname,
+ mctx));
+ }
+
+ CHECK(load_view_keys(view_keys, vconfig, view, ISC_FALSE,
+ NULL, mctx));
+ CHECK(load_view_keys(view_managed_keys, vconfig, view, ISC_TRUE,
+ NULL, mctx));
+
+ if (view->rdclass == dns_rdataclass_in) {
+ CHECK(load_view_keys(global_keys, vconfig, view, ISC_FALSE,
+ NULL, mctx));
+ CHECK(load_view_keys(global_managed_keys, vconfig, view,
+ ISC_TRUE, NULL, mctx));
+ }
+
+ /*
+ * Add key zone for managed-keys.
+ */
+ obj = NULL;
+ (void)ns_config_get(maps, "managed-keys-directory", &obj);
+ directory = obj != NULL ? cfg_obj_asstring(obj) : NULL;
+ CHECK(add_keydata_zone(view, directory, ns_g_mctx));
+
+ cleanup:
return (result);
}
static isc_result_t
-mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver)
-{
+mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver) {
const cfg_listelt_t *element;
const cfg_obj_t *obj;
const char *str;
@@ -523,8 +828,7 @@ mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver)
str = cfg_obj_asstring(cfg_tuple_get(obj, "name"));
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- CHECK(dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
value = cfg_obj_asboolean(cfg_tuple_get(obj, "value"));
CHECK(dns_resolver_setmustbesecure(resolver, name, value));
}
@@ -684,7 +988,7 @@ configure_order(dns_order_t *order, const cfg_obj_t *ent) {
isc_buffer_add(&b, strlen(str));
dns_fixedname_init(&fixed);
result = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
@@ -868,7 +1172,7 @@ disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) {
str = cfg_obj_asstring(cfg_tuple_get(disabled, "name"));
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- CHECK(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
algorithms = cfg_tuple_get(disabled, "algorithms");
for (element = cfg_list_first(algorithms);
@@ -921,7 +1225,7 @@ on_disable_list(const cfg_obj_t *disablelist, dns_name_t *zonename) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(name, &b, dns_rootname,
- ISC_TRUE, NULL);
+ 0, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (dns_name_equal(name, zonename))
return (ISC_TRUE);
@@ -979,6 +1283,20 @@ setquerystats(dns_zone_t *zone, isc_mem_t *mctx, isc_boolean_t on) {
return (ISC_R_SUCCESS);
}
+static ns_cache_t *
+cachelist_find(ns_cachelist_t *cachelist, const char *cachename) {
+ ns_cache_t *nsc;
+
+ for (nsc = ISC_LIST_HEAD(*cachelist);
+ nsc != NULL;
+ nsc = ISC_LIST_NEXT(nsc, link)) {
+ if (strcmp(dns_cache_getname(nsc->cache), cachename) == 0)
+ return (nsc);
+ }
+
+ return (NULL);
+}
+
static isc_boolean_t
cache_reusable(dns_view_t *originview, dns_view_t *view,
isc_boolean_t new_zero_no_soattl)
@@ -996,6 +1314,238 @@ cache_reusable(dns_view_t *originview, dns_view_t *view,
return (ISC_TRUE);
}
+static isc_boolean_t
+cache_sharable(dns_view_t *originview, dns_view_t *view,
+ isc_boolean_t new_zero_no_soattl,
+ unsigned int new_cleaning_interval,
+ isc_uint32_t new_max_cache_size)
+{
+ /*
+ * If the cache cannot even reused for the same view, it cannot be
+ * shared with other views.
+ */
+ if (!cache_reusable(originview, view, new_zero_no_soattl))
+ return (ISC_FALSE);
+
+ /*
+ * Check other cache related parameters that must be consistent among
+ * the sharing views.
+ */
+ if (dns_cache_getcleaninginterval(originview->cache) !=
+ new_cleaning_interval ||
+ dns_cache_getcachesize(originview->cache) != new_max_cache_size) {
+ return (ISC_FALSE);
+ }
+
+ return (ISC_TRUE);
+}
+
+#ifdef DLZ
+/*
+ * Callback from DLZ configure when the driver sets up a writeable zone
+ */
+static isc_result_t
+dlzconfigure_callback(dns_view_t *view, dns_zone_t *zone) {
+ dns_name_t *origin = dns_zone_getorigin(zone);
+ dns_rdataclass_t zclass = view->rdclass;
+ isc_result_t result;
+
+ result = dns_zonemgr_managezone(ns_g_server->zonemgr, zone);
+ if (result != ISC_R_SUCCESS)
+ return result;
+ dns_zone_setstats(zone, ns_g_server->zonestats);
+
+ return ns_zone_configure_writeable_dlz(view->dlzdatabase,
+ zone, zclass, origin);
+}
+#endif
+
+static isc_result_t
+dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na,
+ unsigned int prefixlen, const char *server,
+ const char *contact)
+{
+ char *cp;
+ char reverse[48+sizeof("ip6.arpa.")];
+ const char *dns64_dbtype[4] = { "_builtin", "dns64", ".", "." };
+ const char *sep = ": view ";
+ const char *viewname = view->name;
+ const unsigned char *s6;
+ dns_fixedname_t fixed;
+ dns_name_t *name;
+ dns_zone_t *zone = NULL;
+ int dns64_dbtypec = 4;
+ isc_buffer_t b;
+ isc_result_t result;
+
+ REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 ||
+ prefixlen == 56 || prefixlen == 64 || prefixlen == 96);
+
+ if (!strcmp(viewname, "_default")) {
+ sep = "";
+ viewname = "";
+ }
+
+ /*
+ * Construct the reverse name of the zone.
+ */
+ cp = reverse;
+ s6 = na->type.in6.s6_addr;
+ while (prefixlen > 0) {
+ prefixlen -= 8;
+ sprintf(cp, "%x.%x.", s6[prefixlen/8] & 0xf,
+ (s6[prefixlen/8] >> 4) & 0xf);
+ cp += 4;
+ }
+ strcat(cp, "ip6.arpa.");
+
+ /*
+ * Create the actual zone.
+ */
+ if (server != NULL)
+ dns64_dbtype[2] = server;
+ if (contact != NULL)
+ dns64_dbtype[3] = contact;
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+ isc_buffer_init(&b, reverse, strlen(reverse));
+ isc_buffer_add(&b, strlen(reverse));
+ CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
+ CHECK(dns_zone_create(&zone, mctx));
+ CHECK(dns_zone_setorigin(zone, name));
+ dns_zone_setview(zone, view);
+ CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
+ dns_zone_setclass(zone, view->rdclass);
+ dns_zone_settype(zone, dns_zone_master);
+ dns_zone_setstats(zone, ns_g_server->zonestats);
+ CHECK(dns_zone_setdbtype(zone, dns64_dbtypec, dns64_dbtype));
+ if (view->queryacl != NULL)
+ dns_zone_setqueryacl(zone, view->queryacl);
+ if (view->queryonacl != NULL)
+ dns_zone_setqueryonacl(zone, view->queryonacl);
+ dns_zone_setdialup(zone, dns_dialuptype_no);
+ dns_zone_setnotifytype(zone, dns_notifytype_no);
+ dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, ISC_TRUE);
+ CHECK(setquerystats(zone, mctx, ISC_FALSE)); /* XXXMPA */
+ CHECK(dns_view_addzone(view, zone));
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_INFO, "dns64 reverse zone%s%s: %s", sep,
+ viewname, reverse);
+
+cleanup:
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ return (result);
+}
+
+static isc_result_t
+configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
+ const cfg_obj_t *rpz_obj, *policy_obj;
+ const char *str;
+ dns_fixedname_t fixed;
+ dns_name_t *origin;
+ dns_rpz_zone_t *old, *new;
+ dns_zone_t *zone = NULL;
+ isc_result_t result;
+ unsigned int l1, l2;
+
+ new = isc_mem_get(view->mctx, sizeof(*new));
+ if (new == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+
+ memset(new, 0, sizeof(*new));
+ dns_name_init(&new->nsdname, NULL);
+ dns_name_init(&new->origin, NULL);
+ dns_name_init(&new->cname, NULL);
+ ISC_LIST_INITANDAPPEND(view->rpz_zones, new, link);
+
+ rpz_obj = cfg_listelt_value(element);
+ policy_obj = cfg_tuple_get(rpz_obj, "policy");
+ if (cfg_obj_isvoid(policy_obj)) {
+ new->policy = DNS_RPZ_POLICY_GIVEN;
+ } else {
+ str = cfg_obj_asstring(policy_obj);
+ new->policy = dns_rpz_str2policy(str);
+ INSIST(new->policy != DNS_RPZ_POLICY_ERROR);
+ }
+
+ dns_fixedname_init(&fixed);
+ origin = dns_fixedname_name(&fixed);
+ str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "name"));
+ result = dns_name_fromstring(origin, str, DNS_NAME_DOWNCASE, NULL);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "invalid zone '%s'", str);
+ goto cleanup;
+ }
+
+ result = dns_name_fromstring2(&new->nsdname, DNS_RPZ_NSDNAME_ZONE,
+ origin, DNS_NAME_DOWNCASE, view->mctx);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "invalid zone '%s'", str);
+ goto cleanup;
+ }
+
+ /*
+ * The origin is part of 'nsdname' so we don't need to keep it
+ * seperately.
+ */
+ l1 = dns_name_countlabels(&new->nsdname);
+ l2 = dns_name_countlabels(origin);
+ dns_name_getlabelsequence(&new->nsdname, l1 - l2, l2, &new->origin);
+
+ /*
+ * Are we configured to with the reponse policy zone?
+ */
+ result = dns_view_findzone(view, &new->origin, &zone);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "unknown zone '%s'", str);
+ goto cleanup;
+ }
+
+ if (dns_zone_gettype(zone) != dns_zone_master &&
+ dns_zone_gettype(zone) != dns_zone_slave) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "zone '%s' is neither master nor slave", str);
+ dns_zone_detach(&zone);
+ result = DNS_R_NOTMASTER;
+ goto cleanup;
+ }
+ dns_zone_detach(&zone);
+
+ for (old = ISC_LIST_HEAD(view->rpz_zones);
+ old != new;
+ old = ISC_LIST_NEXT(old, link)) {
+ ++new->num;
+ if (dns_name_equal(&old->origin, &new->origin)) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "duplicate '%s'", str);
+ result = DNS_R_DUPLICATE;
+ goto cleanup;
+ }
+ }
+
+ if (new->policy == DNS_RPZ_POLICY_CNAME) {
+ str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "cname"));
+ result = dns_name_fromstring(&new->cname, str, 0, view->mctx);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
+ "invalid cname '%s'", str);
+ goto cleanup;
+ }
+ }
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ dns_rpz_view_destroy(view);
+ return (result);
+}
+
/*
* Configure 'view' according to 'vconfig', taking defaults from 'config'
* where values are missing in 'vconfig'.
@@ -1004,12 +1554,15 @@ cache_reusable(dns_view_t *originview, dns_view_t *view,
* global defaults in 'config' used exclusively.
*/
static isc_result_t
-configure_view(dns_view_t *view, const cfg_obj_t *config,
- const cfg_obj_t *vconfig, isc_mem_t *mctx,
- cfg_aclconfctx_t *actx, isc_boolean_t need_hints)
+configure_view(dns_view_t *view, cfg_parser_t* parser,
+ cfg_obj_t *config, cfg_obj_t *vconfig,
+ ns_cachelist_t *cachelist, const cfg_obj_t *bindkeys,
+ isc_mem_t *mctx, cfg_aclconfctx_t *actx,
+ isc_boolean_t need_hints)
{
const cfg_obj_t *maps[4];
const cfg_obj_t *cfgmaps[3];
+ const cfg_obj_t *optionmaps[3];
const cfg_obj_t *options = NULL;
const cfg_obj_t *voptions = NULL;
const cfg_obj_t *forwardtype;
@@ -1028,17 +1581,20 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_cache_t *cache = NULL;
isc_result_t result;
isc_uint32_t max_adb_size;
+ unsigned int cleaning_interval;
isc_uint32_t max_cache_size;
isc_uint32_t max_acache_size;
isc_uint32_t lame_ttl;
- dns_tsig_keyring_t *ring;
+ dns_tsig_keyring_t *ring = NULL;
dns_view_t *pview = NULL; /* Production view */
isc_mem_t *cmctx;
dns_dispatch_t *dispatch4 = NULL;
dns_dispatch_t *dispatch6 = NULL;
isc_boolean_t reused_cache = ISC_FALSE;
- int i;
+ isc_boolean_t shared_cache = ISC_FALSE;
+ int i = 0, j = 0, k = 0;
const char *str;
+ const char *cachename = NULL;
dns_order_t *order = NULL;
isc_uint32_t udpsize;
unsigned int resopts = 0;
@@ -1052,7 +1608,14 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
const cfg_obj_t *disablelist = NULL;
isc_stats_t *resstats = NULL;
dns_stats_t *resquerystats = NULL;
+ isc_boolean_t auto_dlv = ISC_FALSE;
+ isc_boolean_t auto_root = ISC_FALSE;
+ ns_cache_t *nsc;
isc_boolean_t zero_no_soattl;
+ cfg_parser_t *newzones_parser = NULL;
+ cfg_obj_t *nzfconf = NULL;
+ dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL;
+ unsigned int query_timeout;
REQUIRE(DNS_VIEW_VALID(view));
@@ -1061,22 +1624,28 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
if (config != NULL)
(void)cfg_map_get(config, "options", &options);
- i = 0;
+ /*
+ * maps: view options, options, defaults
+ * cfgmaps: view options, config
+ * optionmaps: view options, options
+ */
if (vconfig != NULL) {
voptions = cfg_tuple_get(vconfig, "options");
maps[i++] = voptions;
+ optionmaps[j++] = voptions;
+ cfgmaps[k++] = voptions;
}
- if (options != NULL)
+ if (options != NULL) {
maps[i++] = options;
+ optionmaps[j++] = options;
+ }
+
maps[i++] = ns_g_defaults;
maps[i] = NULL;
-
- i = 0;
- if (voptions != NULL)
- cfgmaps[i++] = voptions;
+ optionmaps[j] = NULL;
if (config != NULL)
- cfgmaps[i++] = config;
- cfgmaps[i] = NULL;
+ cfgmaps[k++] = config;
+ cfgmaps[k] = NULL;
if (!strcmp(viewname, "_default")) {
sep = "";
@@ -1137,12 +1706,12 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_acache_setcachesize(view->acache, max_acache_size);
}
- CHECK(configure_view_acl(vconfig, config, "allow-query", actx,
+ CHECK(configure_view_acl(vconfig, config, "allow-query", NULL, actx,
ns_g_mctx, &view->queryacl));
-
if (view->queryacl == NULL) {
- CHECK(configure_view_acl(NULL, ns_g_config, "allow-query", actx,
- ns_g_mctx, &view->queryacl));
+ CHECK(configure_view_acl(NULL, ns_g_config, "allow-query",
+ NULL, actx, ns_g_mctx,
+ &view->queryacl));
}
/*
@@ -1159,7 +1728,62 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
{
const cfg_obj_t *zconfig = cfg_listelt_value(element);
CHECK(configure_zone(config, zconfig, vconfig, mctx, view,
- actx));
+ actx, ISC_FALSE));
+ }
+
+ /*
+ * Are we allowing zones to be added and deleted dynamically?
+ */
+ obj = NULL;
+ result = ns_config_get(maps, "allow-new-zones", &obj);
+ if (result == ISC_R_SUCCESS) {
+ isc_boolean_t allow = cfg_obj_asboolean(obj);
+ struct cfg_context *cfg = NULL;
+ if (allow) {
+ cfg = isc_mem_get(view->mctx, sizeof(*cfg));
+ if (cfg == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ memset(cfg, 0, sizeof(*cfg));
+ isc_mem_attach(view->mctx, &cfg->mctx);
+ if (config != NULL)
+ cfg_obj_attach(config, &cfg->config);
+ cfg_parser_attach(parser, &cfg->parser);
+ cfg_aclconfctx_clone(actx, &cfg->actx);
+ }
+ dns_view_setnewzones(view, allow, cfg, cfgctx_destroy);
+ }
+
+ /*
+ * If we're allowing added zones, then load zone configuration
+ * from the newzone file for zones that were added during previous
+ * runs.
+ */
+ if (view->new_zone_file != NULL) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "loading additional zones for view '%s'",
+ view->name);
+
+ CHECK(cfg_parser_create(view->mctx, ns_g_lctx,
+ &newzones_parser));
+ result = cfg_parse_file(newzones_parser, view->new_zone_file,
+ &cfg_type_newzones, &nzfconf);
+ if (result == ISC_R_SUCCESS) {
+ zonelist = NULL;
+ cfg_map_get(nzfconf, "zone", &zonelist);
+ for (element = cfg_list_first(zonelist);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const cfg_obj_t *zconfig =
+ cfg_listelt_value(element);
+ CHECK(configure_zone(config, zconfig, vconfig,
+ mctx, view, actx,
+ ISC_TRUE));
+ }
+ }
}
#ifdef DLZ
@@ -1197,6 +1821,14 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
isc_mem_put(mctx, dlzargv, dlzargc * sizeof(*dlzargv));
if (result != ISC_R_SUCCESS)
goto cleanup;
+
+ /*
+ * If the dlz backend supports configuration,
+ * then call its configure method now.
+ */
+ result = dns_dlzconfigure(view, dlzconfigure_callback);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
}
}
#endif
@@ -1205,6 +1837,32 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* Obtain configuration parameters that affect the decision of whether
* we can reuse/share an existing cache.
*/
+ obj = NULL;
+ result = ns_config_get(maps, "cleaning-interval", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ cleaning_interval = cfg_obj_asuint32(obj) * 60;
+
+ obj = NULL;
+ result = ns_config_get(maps, "max-cache-size", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ if (cfg_obj_isstring(obj)) {
+ str = cfg_obj_asstring(obj);
+ INSIST(strcasecmp(str, "unlimited") == 0);
+ max_cache_size = ISC_UINT32_MAX;
+ } else {
+ isc_resourcevalue_t value;
+ value = cfg_obj_asuint64(obj);
+ if (value > ISC_UINT32_MAX) {
+ cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
+ "'max-cache-size "
+ "%" ISC_PRINT_QUADFORMAT "d' is too large",
+ value);
+ result = ISC_R_RANGE;
+ goto cleanup;
+ }
+ max_cache_size = (isc_uint32_t)value;
+ }
+
/* Check-names. */
obj = NULL;
result = ns_checknames_get(maps, "response", &obj);
@@ -1229,6 +1887,109 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
zero_no_soattl = cfg_obj_asboolean(obj);
obj = NULL;
+ result = ns_config_get(maps, "dns64", &obj);
+ if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") &&
+ strcmp(view->name, "_meta")) {
+ const cfg_listelt_t *element;
+ isc_netaddr_t na, suffix, *sp;
+ unsigned int prefixlen;
+ const char *server, *contact;
+ const cfg_obj_t *myobj;
+
+ myobj = NULL;
+ result = ns_config_get(maps, "dns64-server", &myobj);
+ if (result == ISC_R_SUCCESS)
+ server = cfg_obj_asstring(myobj);
+ else
+ server = NULL;
+
+ myobj = NULL;
+ result = ns_config_get(maps, "dns64-contact", &myobj);
+ if (result == ISC_R_SUCCESS)
+ contact = cfg_obj_asstring(myobj);
+ else
+ contact = NULL;
+
+ for (element = cfg_list_first(obj);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const cfg_obj_t *map = cfg_listelt_value(element);
+ dns_dns64_t *dns64 = NULL;
+ unsigned int dns64options = 0;
+
+ cfg_obj_asnetprefix(cfg_map_getname(map), &na,
+ &prefixlen);
+
+ obj = NULL;
+ (void)cfg_map_get(map, "suffix", &obj);
+ if (obj != NULL) {
+ sp = &suffix;
+ isc_netaddr_fromsockaddr(sp,
+ cfg_obj_assockaddr(obj));
+ } else
+ sp = NULL;
+
+ clients = mapped = excluded = NULL;
+ obj = NULL;
+ (void)cfg_map_get(map, "clients", &obj);
+ if (obj != NULL) {
+ result = cfg_acl_fromconfig(obj, config,
+ ns_g_lctx, actx,
+ mctx, 0, &clients);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+ obj = NULL;
+ (void)cfg_map_get(map, "mapped", &obj);
+ if (obj != NULL) {
+ result = cfg_acl_fromconfig(obj, config,
+ ns_g_lctx, actx,
+ mctx, 0, &mapped);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+ obj = NULL;
+ (void)cfg_map_get(map, "exclude", &obj);
+ if (obj != NULL) {
+ result = cfg_acl_fromconfig(obj, config,
+ ns_g_lctx, actx,
+ mctx, 0, &excluded);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ obj = NULL;
+ (void)cfg_map_get(map, "recursive-only", &obj);
+ if (obj != NULL && cfg_obj_asboolean(obj))
+ dns64options |= DNS_DNS64_RECURSIVE_ONLY;
+
+ obj = NULL;
+ (void)cfg_map_get(map, "break-dnssec", &obj);
+ if (obj != NULL && cfg_obj_asboolean(obj))
+ dns64options |= DNS_DNS64_BREAK_DNSSEC;
+
+ result = dns_dns64_create(mctx, &na, prefixlen, sp,
+ clients, mapped, excluded,
+ dns64options, &dns64);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_dns64_append(&view->dns64, dns64);
+ view->dns64cnt++;
+ result = dns64_reverse(view, mctx, &na, prefixlen,
+ server, contact);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ if (clients != NULL)
+ dns_acl_detach(&clients);
+ if (mapped != NULL)
+ dns_acl_detach(&mapped);
+ if (excluded != NULL)
+ dns_acl_detach(&excluded);
+ }
+ }
+
+ obj = NULL;
result = ns_config_get(maps, "dnssec-accept-expired", &obj);
INSIST(result == ISC_R_SUCCESS);
view->acceptexpired = cfg_obj_asboolean(obj);
@@ -1236,7 +1997,13 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
obj = NULL;
result = ns_config_get(maps, "dnssec-validation", &obj);
INSIST(result == ISC_R_SUCCESS);
- view->enablevalidation = cfg_obj_asboolean(obj);
+ if (cfg_obj_isboolean(obj)) {
+ view->enablevalidation = cfg_obj_asboolean(obj);
+ } else {
+ /* If dnssec-validation is not boolean, it must be "auto" */
+ view->enablevalidation = ISC_TRUE;
+ auto_root = ISC_TRUE;
+ }
obj = NULL;
result = ns_config_get(maps, "max-cache-ttl", &obj);
@@ -1251,53 +2018,113 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
view->maxncachettl = 7 * 24 * 3600;
/*
- * Configure the view's cache. Try to reuse an existing
- * cache if possible, otherwise create a new cache.
- * Note that the ADB is not preserved in either case.
- * When a matching view is found, the associated statistics are
- * also retrieved and reused.
+ * Configure the view's cache.
+ *
+ * First, check to see if there are any attach-cache options. If yes,
+ * attempt to lookup an existing cache at attach it to the view. If
+ * there is not one, then try to reuse an existing cache if possible;
+ * otherwise create a new cache.
*
- * XXX Determining when it is safe to reuse a cache is tricky.
+ * Note that the ADB is not preserved or shared in either case.
+ *
+ * When a matching view is found, the associated statistics are also
+ * retrieved and reused.
+ *
+ * XXX Determining when it is safe to reuse or share a cache is tricky.
* When the view's configuration changes, the cached data may become
* invalid because it reflects our old view of the world. We check
- * some of the configuration parameters that could invalidate the cache,
- * but there are other configuration options that should be checked.
- * For example, if a view uses a forwarder, changes in the forwarder
- * configuration may invalidate the cache. At the moment, it's the
- * administrator's responsibility to ensure these configuration options
- * don't invalidate reusing.
+ * some of the configuration parameters that could invalidate the cache
+ * or otherwise make it unsharable, but there are other configuration
+ * options that should be checked. For example, if a view uses a
+ * forwarder, changes in the forwarder configuration may invalidate
+ * the cache. At the moment, it's the administrator's responsibility to
+ * ensure these configuration options don't invalidate reusing/sharing.
*/
- result = dns_viewlist_find(&ns_g_server->viewlist,
- view->name, view->rdclass,
- &pview);
- if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
- goto cleanup;
- if (pview != NULL) {
- if (cache_reusable(pview, view, zero_no_soattl)) {
- INSIST(pview->cache != NULL);
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
- NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(3),
- "reusing existing cache");
- reused_cache = ISC_TRUE;
- dns_cache_attach(pview->cache, &cache);
- } else {
+ obj = NULL;
+ result = ns_config_get(maps, "attach-cache", &obj);
+ if (result == ISC_R_SUCCESS)
+ cachename = cfg_obj_asstring(obj);
+ else
+ cachename = view->name;
+ cache = NULL;
+ nsc = cachelist_find(cachelist, cachename);
+ if (nsc != NULL) {
+ if (!cache_sharable(nsc->primaryview, view, zero_no_soattl,
+ cleaning_interval, max_cache_size)) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
- NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1),
- "cache cannot be reused for view %s "
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "views %s and %s can't share the cache "
"due to configuration parameter mismatch",
- view->name);
+ nsc->primaryview->name, view->name);
+ result = ISC_R_FAILURE;
+ goto cleanup;
}
- dns_view_getresstats(pview, &resstats);
- dns_view_getresquerystats(pview, &resquerystats);
- dns_view_detach(&pview);
- }
- if (cache == NULL) {
- CHECK(isc_mem_create(0, 0, &cmctx));
- CHECK(dns_cache_create(cmctx, ns_g_taskmgr, ns_g_timermgr,
- view->rdclass, "rbt", 0, NULL, &cache));
- isc_mem_setname(cmctx, "cache", NULL);
+ dns_cache_attach(nsc->cache, &cache);
+ shared_cache = ISC_TRUE;
+ } else {
+ if (strcmp(cachename, view->name) == 0) {
+ result = dns_viewlist_find(&ns_g_server->viewlist,
+ cachename, view->rdclass,
+ &pview);
+ if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
+ goto cleanup;
+ if (pview != NULL) {
+ if (!cache_reusable(pview, view,
+ zero_no_soattl)) {
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER,
+ ISC_LOG_DEBUG(1),
+ "cache cannot be reused "
+ "for view %s due to "
+ "configuration parameter "
+ "mismatch", view->name);
+ } else {
+ INSIST(pview->cache != NULL);
+ isc_log_write(ns_g_lctx,
+ NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER,
+ ISC_LOG_DEBUG(3),
+ "reusing existing cache");
+ reused_cache = ISC_TRUE;
+ dns_cache_attach(pview->cache, &cache);
+ }
+ dns_view_getresstats(pview, &resstats);
+ dns_view_getresquerystats(pview,
+ &resquerystats);
+ dns_view_detach(&pview);
+ }
+ }
+ if (cache == NULL) {
+ /*
+ * Create a cache with the desired name. This normally
+ * equals the view name, but may also be a forward
+ * reference to a view that share the cache with this
+ * view but is not yet configured. If it is not the
+ * view name but not a forward reference either, then it
+ * is simply a named cache that is not shared.
+ */
+ CHECK(isc_mem_create(0, 0, &cmctx));
+ isc_mem_setname(cmctx, "cache", NULL);
+ CHECK(dns_cache_create2(cmctx, ns_g_taskmgr,
+ ns_g_timermgr, view->rdclass,
+ cachename, "rbt", 0, NULL,
+ &cache));
+ }
+ nsc = isc_mem_get(mctx, sizeof(*nsc));
+ if (nsc == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ nsc->cache = NULL;
+ dns_cache_attach(cache, &nsc->cache);
+ nsc->primaryview = view;
+ nsc->needflush = ISC_FALSE;
+ nsc->adbsizeadjusted = ISC_FALSE;
+ ISC_LINK_INIT(nsc, link);
+ ISC_LIST_APPEND(*cachelist, nsc, link);
}
- dns_view_setcache(view, cache);
+ dns_view_setcache2(view, cache, shared_cache);
/*
* cache-file cannot be inherited if views are present, but this
@@ -1307,35 +2134,11 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
result = ns_config_get(maps, "cache-file", &obj);
if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0) {
CHECK(dns_cache_setfilename(cache, cfg_obj_asstring(obj)));
- if (!reused_cache)
+ if (!reused_cache && !shared_cache)
CHECK(dns_cache_load(cache));
}
- obj = NULL;
- result = ns_config_get(maps, "cleaning-interval", &obj);
- INSIST(result == ISC_R_SUCCESS);
- dns_cache_setcleaninginterval(cache, cfg_obj_asuint32(obj) * 60);
-
- obj = NULL;
- result = ns_config_get(maps, "max-cache-size", &obj);
- INSIST(result == ISC_R_SUCCESS);
- if (cfg_obj_isstring(obj)) {
- str = cfg_obj_asstring(obj);
- INSIST(strcasecmp(str, "unlimited") == 0);
- max_cache_size = ISC_UINT32_MAX;
- } else {
- isc_resourcevalue_t value;
- value = cfg_obj_asuint64(obj);
- if (value > ISC_UINT32_MAX) {
- cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
- "'max-cache-size "
- "%" ISC_PRINT_QUADFORMAT "d' is too large",
- value);
- result = ISC_R_RANGE;
- goto cleanup;
- }
- max_cache_size = (isc_uint32_t)value;
- }
+ dns_cache_setcleaninginterval(cache, cleaning_interval);
dns_cache_setcachesize(cache, max_cache_size);
dns_cache_detach(&cache);
@@ -1373,13 +2176,23 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_view_setresquerystats(view, resquerystats);
/*
- * Set the ADB cache size to 1/8th of the max-cache-size.
+ * Set the ADB cache size to 1/8th of the max-cache-size or
+ * MAX_ADB_SIZE_FOR_CACHESHARE when the cache is shared.
*/
max_adb_size = 0;
if (max_cache_size != 0) {
max_adb_size = max_cache_size / 8;
if (max_adb_size == 0)
max_adb_size = 1; /* Force minimum. */
+ if (view != nsc->primaryview &&
+ max_adb_size > MAX_ADB_SIZE_FOR_CACHESHARE) {
+ max_adb_size = MAX_ADB_SIZE_FOR_CACHESHARE;
+ if (!nsc->adbsizeadjusted) {
+ dns_adb_setadbsize(nsc->primaryview->adb,
+ MAX_ADB_SIZE_FOR_CACHESHARE);
+ nsc->adbsizeadjusted = ISC_TRUE;
+ }
+ }
}
dns_adb_setadbsize(view->adb, max_adb_size);
@@ -1395,6 +2208,18 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_resolver_setlamettl(view->resolver, lame_ttl);
/*
+ * Set the resolver's query timeout.
+ */
+ obj = NULL;
+ result = ns_config_get(maps, "resolver-query-timeout", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ query_timeout = cfg_obj_asuint32(obj);
+ dns_resolver_settimeout(view->resolver, query_timeout);
+
+ /* Specify whether to use 0-TTL for negative response for SOA query */
+ dns_resolver_setzeronosoattl(view->resolver, zero_no_soattl);
+
+ /*
* Set the resolver's EDNS UDP size.
*/
obj = NULL;
@@ -1484,9 +2309,29 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
/*
* Configure the view's TSIG keys.
*/
- ring = NULL;
CHECK(ns_tsigkeyring_fromconfig(config, vconfig, view->mctx, &ring));
+ if (ns_g_server->sessionkey != NULL) {
+ CHECK(dns_tsigkeyring_add(ring, ns_g_server->session_keyname,
+ ns_g_server->sessionkey));
+ }
dns_view_setkeyring(view, ring);
+ dns_tsigkeyring_detach(&ring);
+
+ /*
+ * See if we can re-use a dynamic key ring.
+ */
+ result = dns_viewlist_find(&ns_g_server->viewlist, view->name,
+ view->rdclass, &pview);
+ if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
+ goto cleanup;
+ if (pview != NULL) {
+ dns_view_getdynamickeyring(pview, &ring);
+ if (ring != NULL)
+ dns_view_setdynamickeyring(view, ring);
+ dns_tsigkeyring_detach(&ring);
+ dns_view_detach(&pview);
+ } else
+ dns_view_restorekeyring(view);
/*
* Configure the view's peer list.
@@ -1543,10 +2388,10 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
/*
* Configure the "match-clients" and "match-destinations" ACL.
*/
- CHECK(configure_view_acl(vconfig, config, "match-clients", actx,
+ CHECK(configure_view_acl(vconfig, config, "match-clients", NULL, actx,
ns_g_mctx, &view->matchclients));
- CHECK(configure_view_acl(vconfig, config, "match-destinations", actx,
- ns_g_mctx, &view->matchdestinations));
+ CHECK(configure_view_acl(vconfig, config, "match-destinations", NULL,
+ actx, ns_g_mctx, &view->matchdestinations));
/*
* Configure the "match-recursive-only" option.
@@ -1618,20 +2463,20 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* "allow-recursion", and "allow-recursion-on" acls if
* configured in named.conf.
*/
- CHECK(configure_view_acl(vconfig, config, "allow-query-cache",
+ CHECK(configure_view_acl(vconfig, config, "allow-query-cache", NULL,
actx, ns_g_mctx, &view->cacheacl));
- CHECK(configure_view_acl(vconfig, config, "allow-query-cache-on",
+ CHECK(configure_view_acl(vconfig, config, "allow-query-cache-on", NULL,
actx, ns_g_mctx, &view->cacheonacl));
if (view->cacheonacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-query-cache-on", actx,
+ "allow-query-cache-on", NULL, actx,
ns_g_mctx, &view->cacheonacl));
if (strcmp(view->name, "_bind") != 0) {
CHECK(configure_view_acl(vconfig, config, "allow-recursion",
- actx, ns_g_mctx,
+ NULL, actx, ns_g_mctx,
&view->recursionacl));
CHECK(configure_view_acl(vconfig, config, "allow-recursion-on",
- actx, ns_g_mctx,
+ NULL, actx, ns_g_mctx,
&view->recursiononacl));
}
@@ -1643,8 +2488,14 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
*/
if (view->cacheacl == NULL && view->recursionacl != NULL)
dns_acl_attach(view->recursionacl, &view->cacheacl);
+ /*
+ * XXXEACH: This call to configure_view_acl() is redundant. We
+ * are leaving it as it is because we are making a minimal change
+ * for a patch release. In the future this should be changed to
+ * dns_acl_attach(view->queryacl, &view->cacheacl).
+ */
if (view->cacheacl == NULL && view->recursion)
- CHECK(configure_view_acl(vconfig, config, "allow-query",
+ CHECK(configure_view_acl(vconfig, config, "allow-query", NULL,
actx, ns_g_mctx, &view->cacheacl));
if (view->recursion &&
view->recursionacl == NULL && view->cacheacl != NULL)
@@ -1656,24 +2507,44 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
*/
if (view->recursionacl == NULL && view->recursion)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-recursion",
+ "allow-recursion", NULL,
actx, ns_g_mctx,
&view->recursionacl));
if (view->recursiononacl == NULL && view->recursion)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-recursion-on",
+ "allow-recursion-on", NULL,
actx, ns_g_mctx,
&view->recursiononacl));
if (view->cacheacl == NULL) {
if (view->recursion)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-query-cache", actx,
- ns_g_mctx, &view->cacheacl));
+ "allow-query-cache", NULL,
+ actx, ns_g_mctx,
+ &view->cacheacl));
else
- CHECK(dns_acl_none(ns_g_mctx, &view->cacheacl));
+ CHECK(dns_acl_none(mctx, &view->cacheacl));
}
/*
+ * Filter setting on addresses in the answer section.
+ */
+ CHECK(configure_view_acl(vconfig, config, "deny-answer-addresses",
+ "acl", actx, ns_g_mctx, &view->denyansweracl));
+ CHECK(configure_view_nametable(vconfig, config, "deny-answer-addresses",
+ "except-from", ns_g_mctx,
+ &view->answeracl_exclude));
+
+ /*
+ * Filter setting on names (CNAME/DNAME targets) in the answer section.
+ */
+ CHECK(configure_view_nametable(vconfig, config, "deny-answer-aliases",
+ "name", ns_g_mctx,
+ &view->denyanswernames));
+ CHECK(configure_view_nametable(vconfig, config, "deny-answer-aliases",
+ "except-from", ns_g_mctx,
+ &view->answernames_exclude));
+
+ /*
* Configure sortlist, if set
*/
CHECK(configure_view_sortlist(vconfig, config, actx, ns_g_mctx,
@@ -1686,19 +2557,19 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
*/
if (view->notifyacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-notify", actx,
+ "allow-notify", NULL, actx,
ns_g_mctx, &view->notifyacl));
if (view->transferacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-transfer", actx,
+ "allow-transfer", NULL, actx,
ns_g_mctx, &view->transferacl));
if (view->updateacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-update", actx,
+ "allow-update", NULL, actx,
ns_g_mctx, &view->updateacl));
if (view->upfwdacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
- "allow-update-forwarding", actx,
+ "allow-update-forwarding", NULL, actx,
ns_g_mctx, &view->upfwdacl));
obj = NULL;
@@ -1728,13 +2599,47 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
cfg_obj_asuint32(obj),
max_clients_per_query);
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ obj = NULL;
+ result = ns_config_get(maps, "filter-aaaa-on-v4", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ if (cfg_obj_isboolean(obj)) {
+ if (cfg_obj_asboolean(obj))
+ view->v4_aaaa = dns_v4_aaaa_filter;
+ else
+ view->v4_aaaa = dns_v4_aaaa_ok;
+ } else {
+ const char *v4_aaaastr = cfg_obj_asstring(obj);
+ if (strcasecmp(v4_aaaastr, "break-dnssec") == 0)
+ view->v4_aaaa = dns_v4_aaaa_break_dnssec;
+ else
+ INSIST(0);
+ }
+ CHECK(configure_view_acl(vconfig, config, "filter-aaaa", NULL,
+ actx, ns_g_mctx, &view->v4_aaaa_acl));
+#endif
+
obj = NULL;
result = ns_config_get(maps, "dnssec-enable", &obj);
INSIST(result == ISC_R_SUCCESS);
view->enablednssec = cfg_obj_asboolean(obj);
obj = NULL;
- result = ns_config_get(maps, "dnssec-lookaside", &obj);
+ result = ns_config_get(optionmaps, "dnssec-lookaside", &obj);
+ if (result == ISC_R_SUCCESS) {
+ /* If set to "auto", use the version from the defaults */
+ const cfg_obj_t *dlvobj;
+ dlvobj = cfg_listelt_value(cfg_list_first(obj));
+ if (!strcmp(cfg_obj_asstring(cfg_tuple_get(dlvobj, "domain")),
+ "auto") &&
+ cfg_obj_isvoid(cfg_tuple_get(dlvobj, "trust-anchor"))) {
+ auto_dlv = ISC_TRUE;
+ obj = NULL;
+ result = cfg_map_get(ns_g_defaults,
+ "dnssec-lookaside", &obj);
+ }
+ }
+
if (result == ISC_R_SUCCESS) {
for (element = cfg_list_first(obj);
element != NULL;
@@ -1745,31 +2650,13 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_name_t *dlv;
obj = cfg_listelt_value(element);
-#if 0
- dns_fixedname_t fixed;
- dns_name_t *name;
-
- /*
- * When we support multiple dnssec-lookaside
- * entries this is how to find the domain to be
- * checked. XXXMPA
- */
- dns_fixedname_init(&fixed);
- name = dns_fixedname_name(&fixed);
- str = cfg_obj_asstring(cfg_tuple_get(obj,
- "domain"));
- isc_buffer_init(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- CHECK(dns_name_fromtext(name, &b, dns_rootname,
- ISC_TRUE, NULL));
-#endif
str = cfg_obj_asstring(cfg_tuple_get(obj,
"trust-anchor"));
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
dlv = dns_fixedname_name(&view->dlv_fixed);
CHECK(dns_name_fromtext(dlv, &b, dns_rootname,
- ISC_TRUE, NULL));
+ DNS_NAME_DOWNCASE, NULL));
view->dlv = dns_fixedname_name(&view->dlv_fixed);
}
} else
@@ -1779,8 +2666,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* For now, there is only one kind of trusted keys, the
* "security roots".
*/
- CHECK(configure_view_dnsseckeys(vconfig, config, mctx,
- &view->secroots));
+ CHECK(configure_view_dnsseckeys(view, vconfig, config, bindkeys,
+ auto_dlv, auto_root, mctx));
dns_resolver_resetmustbesecure(view->resolver);
obj = NULL;
result = ns_config_get(maps, "dnssec-must-be-secure", &obj);
@@ -1821,7 +2708,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
CHECK(dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL));
+ 0, NULL));
CHECK(dns_view_excludedelegationonly(view,
name));
}
@@ -1874,8 +2761,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
str = cfg_obj_asstring(obj);
isc_buffer_init(&buffer, str, strlen(str));
isc_buffer_add(&buffer, strlen(str));
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
isc_buffer_init(&buffer, server, sizeof(server) - 1);
CHECK(dns_name_totext(name, ISC_FALSE, &buffer));
server[isc_buffer_usedlength(&buffer)] = 0;
@@ -1889,8 +2776,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
str = cfg_obj_asstring(obj);
isc_buffer_init(&buffer, str, strlen(str));
isc_buffer_add(&buffer, strlen(str));
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
isc_buffer_init(&buffer, contact, sizeof(contact) - 1);
CHECK(dns_name_totext(name, ISC_FALSE, &buffer));
contact[isc_buffer_usedlength(&buffer)] = 0;
@@ -1916,8 +2803,8 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
/*
* Look for zone on drop list.
*/
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
if (disablelist != NULL &&
on_disable_list(disablelist, name))
continue;
@@ -2012,9 +2899,40 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
}
}
+ /*
+ * Make the list of response policy zone names for views that
+ * are used for real lookups and so care about hints.
+ */
+ zonelist = NULL;
+ if (view->rdclass == dns_rdataclass_in && need_hints) {
+ obj = NULL;
+ result = ns_config_get(maps, "response-policy", &obj);
+ if (result == ISC_R_SUCCESS)
+ cfg_map_get(obj, "zone", &zonelist);
+ }
+ if (zonelist != NULL) {
+
+ for (element = cfg_list_first(zonelist);
+ element != NULL;
+ element = cfg_list_next(element)) {
+ result = configure_rpz(view, element);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_rpz_set_need(ISC_TRUE);
+ }
+ }
+
result = ISC_R_SUCCESS;
cleanup:
+ if (clients != NULL)
+ dns_acl_detach(&clients);
+ if (mapped != NULL)
+ dns_acl_detach(&mapped);
+ if (excluded != NULL)
+ dns_acl_detach(&excluded);
+ if (ring != NULL)
+ dns_tsigkeyring_detach(&ring);
if (zone != NULL)
dns_zone_detach(&zone);
if (dispatch4 != NULL)
@@ -2033,6 +2951,12 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
if (cache != NULL)
dns_cache_detach(&cache);
+ if (newzones_parser != NULL) {
+ if (nzfconf != NULL)
+ cfg_obj_destroy(newzones_parser, &nzfconf);
+ cfg_parser_destroy(&newzones_parser);
+ }
+
return (result);
}
@@ -2105,8 +3029,8 @@ configure_alternates(const cfg_obj_t *config, dns_view_t *view,
isc_buffer_add(&buffer, strlen(str));
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
- CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
+ NULL));
portobj = cfg_tuple_get(alternate, "port");
if (cfg_obj_isuint32(portobj)) {
@@ -2286,7 +3210,7 @@ create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
static isc_result_t
configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
- cfg_aclconfctx_t *aclconf)
+ cfg_aclconfctx_t *aclconf, isc_boolean_t added)
{
dns_view_t *pview = NULL; /* Production view */
dns_zone_t *zone = NULL; /* New or reused zone */
@@ -2319,7 +3243,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
isc_buffer_add(&buffer, strlen(zname));
dns_fixedname_init(&fixorigin);
CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin),
- &buffer, dns_rootname, ISC_FALSE, NULL));
+ &buffer, dns_rootname, 0, NULL));
origin = dns_fixedname_name(&fixorigin);
CHECK(ns_config_getclass(cfg_tuple_get(zconfig, "class"),
@@ -2349,7 +3273,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
ztypestr = cfg_obj_asstring(typeobj);
/*
- * "hints zones" aren't zones. If we've got one,
+ * "hints zones" aren't zones. If we've got one,
* configure it and return.
*/
if (strcasecmp(ztypestr, "hint") == 0) {
@@ -2500,6 +3424,11 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
}
/*
+ * Mark whether the zone was originally added at runtime or not
+ */
+ dns_zone_setadded(zone, added);
+
+ /*
* Configure the zone.
*/
CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, zone));
@@ -2519,6 +3448,95 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
}
/*
+ * Configure built-in zone for storing managed-key data.
+ */
+
+#define KEYZONE "managed-keys.bind"
+#define MKEYS ".mkeys"
+
+static isc_result_t
+add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) {
+ isc_result_t result;
+ dns_view_t *pview = NULL;
+ dns_zone_t *zone = NULL;
+ dns_acl_t *none = NULL;
+ char filename[PATH_MAX];
+ char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(MKEYS)];
+ int n;
+
+ REQUIRE(view != NULL);
+
+ /* See if we can re-use an existing keydata zone. */
+ result = dns_viewlist_find(&ns_g_server->viewlist,
+ view->name, view->rdclass,
+ &pview);
+ if (result != ISC_R_NOTFOUND &&
+ result != ISC_R_SUCCESS)
+ return (result);
+
+ if (pview != NULL && pview->managed_keys != NULL) {
+ dns_zone_attach(pview->managed_keys, &view->managed_keys);
+ dns_zone_setview(pview->managed_keys, view);
+ dns_view_detach(&pview);
+ return (ISC_R_SUCCESS);
+ }
+
+ /* No existing keydata zone was found; create one */
+ CHECK(dns_zone_create(&zone, mctx));
+ CHECK(dns_zone_setorigin(zone, dns_rootname));
+
+ isc_sha256_data((void *)view->name, strlen(view->name), buffer);
+ strcat(buffer, MKEYS);
+ n = snprintf(filename, sizeof(filename), "%s%s%s",
+ directory ? directory : "", directory ? "/" : "",
+ strcmp(view->name, "_default") == 0 ? KEYZONE : buffer);
+ if (n < 0 || (size_t)n >= sizeof(filename)) {
+ result = (n < 0) ? ISC_R_FAILURE : ISC_R_NOSPACE;
+ goto cleanup;
+ }
+ CHECK(dns_zone_setfile(zone, filename));
+
+ dns_zone_setview(zone, view);
+ dns_zone_settype(zone, dns_zone_key);
+ dns_zone_setclass(zone, view->rdclass);
+
+ CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
+
+ if (view->acache != NULL)
+ dns_zone_setacache(zone, view->acache);
+
+ CHECK(dns_acl_none(mctx, &none));
+ dns_zone_setqueryacl(zone, none);
+ dns_zone_setqueryonacl(zone, none);
+ dns_acl_detach(&none);
+
+ dns_zone_setdialup(zone, dns_dialuptype_no);
+ dns_zone_setnotifytype(zone, dns_notifytype_no);
+ dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, ISC_TRUE);
+ dns_zone_setjournalsize(zone, 0);
+
+ dns_zone_setstats(zone, ns_g_server->zonestats);
+ CHECK(setquerystats(zone, mctx, ISC_FALSE));
+
+ if (view->managed_keys != NULL)
+ dns_zone_detach(&view->managed_keys);
+ dns_zone_attach(zone, &view->managed_keys);
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "set up managed keys zone for view %s, file '%s'",
+ view->name, filename);
+
+cleanup:
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ if (none != NULL)
+ dns_acl_detach(&none);
+
+ return (result);
+}
+
+/*
* Configure a single server quota.
*/
static void
@@ -2914,13 +3932,226 @@ removed(dns_zone_t *zone, void *uap) {
return (ISC_R_SUCCESS);
}
+static void
+cleanup_session_key(ns_server_t *server, isc_mem_t *mctx) {
+ if (server->session_keyfile != NULL) {
+ isc_file_remove(server->session_keyfile);
+ isc_mem_free(mctx, server->session_keyfile);
+ server->session_keyfile = NULL;
+ }
+
+ if (server->session_keyname != NULL) {
+ if (dns_name_dynamic(server->session_keyname))
+ dns_name_free(server->session_keyname, mctx);
+ isc_mem_put(mctx, server->session_keyname, sizeof(dns_name_t));
+ server->session_keyname = NULL;
+ }
+
+ if (server->sessionkey != NULL)
+ dns_tsigkey_detach(&server->sessionkey);
+
+ server->session_keyalg = DST_ALG_UNKNOWN;
+ server->session_keybits = 0;
+}
+
+static isc_result_t
+generate_session_key(const char *filename, const char *keynamestr,
+ dns_name_t *keyname, const char *algstr,
+ dns_name_t *algname, unsigned int algtype,
+ isc_uint16_t bits, isc_mem_t *mctx,
+ dns_tsigkey_t **tsigkeyp)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ dst_key_t *key = NULL;
+ isc_buffer_t key_txtbuffer;
+ isc_buffer_t key_rawbuffer;
+ char key_txtsecret[256];
+ char key_rawsecret[64];
+ isc_region_t key_rawregion;
+ isc_stdtime_t now;
+ dns_tsigkey_t *tsigkey = NULL;
+ FILE *fp = NULL;
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "generating session key for dynamic DNS");
+
+ /* generate key */
+ result = dst_key_generate(keyname, algtype, bits, 1, 0,
+ DNS_KEYPROTO_ANY, dns_rdataclass_in,
+ mctx, &key);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * Dump the key to the buffer for later use. Should be done before
+ * we transfer the ownership of key to tsigkey.
+ */
+ isc_buffer_init(&key_rawbuffer, &key_rawsecret, sizeof(key_rawsecret));
+ CHECK(dst_key_tobuffer(key, &key_rawbuffer));
+
+ isc_buffer_usedregion(&key_rawbuffer, &key_rawregion);
+ isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret));
+ CHECK(isc_base64_totext(&key_rawregion, -1, "", &key_txtbuffer));
+
+ /* Store the key in tsigkey. */
+ isc_stdtime_get(&now);
+ CHECK(dns_tsigkey_createfromkey(dst_key_name(key), algname, key,
+ ISC_FALSE, NULL, now, now, mctx, NULL,
+ &tsigkey));
+
+ /* Dump the key to the key file. */
+ fp = ns_os_openfile(filename, S_IRUSR|S_IWUSR, ISC_TRUE);
+ if (fp == NULL) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "could not create %s", filename);
+ result = ISC_R_NOPERM;
+ goto cleanup;
+ }
+
+ fprintf(fp, "key \"%s\" {\n"
+ "\talgorithm %s;\n"
+ "\tsecret \"%.*s\";\n};\n", keynamestr, algstr,
+ (int) isc_buffer_usedlength(&key_txtbuffer),
+ (char*) isc_buffer_base(&key_txtbuffer));
+
+ RUNTIME_CHECK(isc_stdio_flush(fp) == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc_stdio_close(fp) == ISC_R_SUCCESS);
+
+ dst_key_free(&key);
+
+ *tsigkeyp = tsigkey;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "failed to generate session key "
+ "for dynamic DNS: %s", isc_result_totext(result));
+ if (tsigkey != NULL)
+ dns_tsigkey_detach(&tsigkey);
+ if (key != NULL)
+ dst_key_free(&key);
+
+ return (result);
+}
+
+static isc_result_t
+configure_session_key(const cfg_obj_t **maps, ns_server_t *server,
+ isc_mem_t *mctx)
+{
+ const char *keyfile, *keynamestr, *algstr;
+ unsigned int algtype;
+ dns_fixedname_t fname;
+ dns_name_t *keyname, *algname;
+ isc_buffer_t buffer;
+ isc_uint16_t bits;
+ const cfg_obj_t *obj;
+ isc_boolean_t need_deleteold = ISC_FALSE;
+ isc_boolean_t need_createnew = ISC_FALSE;
+ isc_result_t result;
+
+ obj = NULL;
+ result = ns_config_get(maps, "session-keyfile", &obj);
+ if (result == ISC_R_SUCCESS) {
+ if (cfg_obj_isvoid(obj))
+ keyfile = NULL; /* disable it */
+ else
+ keyfile = cfg_obj_asstring(obj);
+ } else
+ keyfile = ns_g_defaultsessionkeyfile;
+
+ obj = NULL;
+ result = ns_config_get(maps, "session-keyname", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ keynamestr = cfg_obj_asstring(obj);
+ dns_fixedname_init(&fname);
+ isc_buffer_init(&buffer, keynamestr, strlen(keynamestr));
+ isc_buffer_add(&buffer, strlen(keynamestr));
+ keyname = dns_fixedname_name(&fname);
+ result = dns_name_fromtext(keyname, &buffer, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ obj = NULL;
+ result = ns_config_get(maps, "session-keyalg", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ algstr = cfg_obj_asstring(obj);
+ algname = NULL;
+ result = ns_config_getkeyalgorithm2(algstr, &algname, &algtype, &bits);
+ if (result != ISC_R_SUCCESS) {
+ const char *s = " (keeping current key)";
+
+ cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "session-keyalg: "
+ "unsupported or unknown algorithm '%s'%s",
+ algstr,
+ server->session_keyfile != NULL ? s : "");
+ return (result);
+ }
+
+ /* See if we need to (re)generate a new key. */
+ if (keyfile == NULL) {
+ if (server->session_keyfile != NULL)
+ need_deleteold = ISC_TRUE;
+ } else if (server->session_keyfile == NULL)
+ need_createnew = ISC_TRUE;
+ else if (strcmp(keyfile, server->session_keyfile) != 0 ||
+ !dns_name_equal(server->session_keyname, keyname) ||
+ server->session_keyalg != algtype ||
+ server->session_keybits != bits) {
+ need_deleteold = ISC_TRUE;
+ need_createnew = ISC_TRUE;
+ }
+
+ if (need_deleteold) {
+ INSIST(server->session_keyfile != NULL);
+ INSIST(server->session_keyname != NULL);
+ INSIST(server->sessionkey != NULL);
+
+ cleanup_session_key(server, mctx);
+ }
+
+ if (need_createnew) {
+ INSIST(server->sessionkey == NULL);
+ INSIST(server->session_keyfile == NULL);
+ INSIST(server->session_keyname == NULL);
+ INSIST(server->session_keyalg == DST_ALG_UNKNOWN);
+ INSIST(server->session_keybits == 0);
+
+ server->session_keyname = isc_mem_get(mctx, sizeof(dns_name_t));
+ if (server->session_keyname == NULL)
+ goto cleanup;
+ dns_name_init(server->session_keyname, NULL);
+ CHECK(dns_name_dup(keyname, mctx, server->session_keyname));
+
+ server->session_keyfile = isc_mem_strdup(mctx, keyfile);
+ if (server->session_keyfile == NULL)
+ goto cleanup;
+
+ server->session_keyalg = algtype;
+ server->session_keybits = bits;
+
+ CHECK(generate_session_key(keyfile, keynamestr, keyname, algstr,
+ algname, algtype, bits, mctx,
+ &server->sessionkey));
+ }
+
+ return (result);
+
+ cleanup:
+ cleanup_session_key(server, mctx);
+ return (result);
+}
+
static isc_result_t
load_configuration(const char *filename, ns_server_t *server,
isc_boolean_t first_time)
{
cfg_aclconfctx_t aclconfctx;
- cfg_obj_t *config;
- cfg_parser_t *parser = NULL;
+ cfg_obj_t *config = NULL, *bindkeys = NULL;
+ cfg_parser_t *conf_parser = NULL, *bindkeys_parser = NULL;
const cfg_listelt_t *element;
const cfg_obj_t *builtin_views;
const cfg_obj_t *maps[3];
@@ -2931,7 +4162,7 @@ load_configuration(const char *filename, ns_server_t *server,
dns_view_t *view = NULL;
dns_view_t *view_next;
dns_viewlist_t tmpviewlist;
- dns_viewlist_t viewlist;
+ dns_viewlist_t viewlist, builtin_viewlist;
in_port_t listen_port, udpport_low, udpport_high;
int i;
isc_interval_t interval;
@@ -2943,10 +4174,14 @@ load_configuration(const char *filename, ns_server_t *server,
isc_uint32_t interface_interval;
isc_uint32_t reserved;
isc_uint32_t udpsize;
+ ns_cachelist_t cachelist, tmpcachelist;
unsigned int maxsocks;
+ ns_cache_t *nsc;
cfg_aclconfctx_init(&aclconfctx);
ISC_LIST_INIT(viewlist);
+ ISC_LIST_INIT(builtin_viewlist);
+ ISC_LIST_INIT(cachelist);
/* Ensure exclusive access to configuration data. */
result = isc_task_beginexclusive(server->task);
@@ -2958,8 +4193,7 @@ load_configuration(const char *filename, ns_server_t *server,
if (first_time) {
CHECK(ns_config_parsedefaults(ns_g_parser, &ns_g_config));
RUNTIME_CHECK(cfg_map_get(ns_g_config, "options",
- &ns_g_defaults) ==
- ISC_R_SUCCESS);
+ &ns_g_defaults) == ISC_R_SUCCESS);
}
/*
@@ -2976,10 +4210,10 @@ load_configuration(const char *filename, ns_server_t *server,
NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO, "loading configuration from '%s'",
filename);
- CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser));
- cfg_parser_setcallback(parser, directory_callback, NULL);
- result = cfg_parse_file(parser, filename, &cfg_type_namedconf,
- &config);
+ CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &conf_parser));
+ cfg_parser_setcallback(conf_parser, directory_callback, NULL);
+ result = cfg_parse_file(conf_parser, filename,
+ &cfg_type_namedconf, &config);
}
/*
@@ -2994,10 +4228,10 @@ load_configuration(const char *filename, ns_server_t *server,
NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO, "loading configuration from '%s'",
lwresd_g_resolvconffile);
- if (parser != NULL)
- cfg_parser_destroy(&parser);
- CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser));
- result = ns_lwresd_parseeresolvconf(ns_g_mctx, parser,
+ if (conf_parser != NULL)
+ cfg_parser_destroy(&conf_parser);
+ CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &conf_parser));
+ result = ns_lwresd_parseeresolvconf(ns_g_mctx, conf_parser,
&config);
}
CHECK(result);
@@ -3019,13 +4253,38 @@ load_configuration(const char *filename, ns_server_t *server,
maps[i++] = NULL;
/*
+ * If bind.keys exists, load it. If "dnssec-lookaside auto"
+ * is turned on, the keys found there will be used as default
+ * trust anchors.
+ */
+ obj = NULL;
+ result = ns_config_get(maps, "bindkeys-file", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ CHECKM(setstring(server, &server->bindkeysfile,
+ cfg_obj_asstring(obj)), "strdup");
+
+ if (access(server->bindkeysfile, R_OK) == 0) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "reading built-in trusted "
+ "keys from file '%s'", server->bindkeysfile);
+
+ CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx,
+ &bindkeys_parser));
+
+ result = cfg_parse_file(bindkeys_parser, server->bindkeysfile,
+ &cfg_type_bindkeys, &bindkeys);
+ CHECK(result);
+ }
+
+ /*
* Set process limits, which (usually) needs to be done as root.
*/
set_limits(maps);
/*
* Check if max number of open sockets that the system allows is
- * sufficiently large. Failing this condition is not necessarily fatal,
+ * sufficiently large. Failing this condition is not necessarily fatal,
* but may cause subsequent runtime failures for a busy recursive
* server.
*/
@@ -3078,7 +4337,7 @@ load_configuration(const char *filename, ns_server_t *server,
else
isc_quota_soft(&server->recursionquota, 0);
- CHECK(configure_view_acl(NULL, config, "blackhole", &aclconfctx,
+ CHECK(configure_view_acl(NULL, config, "blackhole", NULL, &aclconfctx,
ns_g_mctx, &server->blackholeacl));
if (server->blackholeacl != NULL)
dns_dispatchmgr_setblackhole(ns_g_dispatchmgr,
@@ -3318,6 +4577,31 @@ load_configuration(const char *filename, ns_server_t *server,
&interval, ISC_FALSE));
/*
+ * Write the PID file.
+ */
+ obj = NULL;
+ if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS)
+ if (cfg_obj_isvoid(obj))
+ ns_os_writepidfile(NULL, first_time);
+ else
+ ns_os_writepidfile(cfg_obj_asstring(obj), first_time);
+ else if (ns_g_lwresdonly)
+ ns_os_writepidfile(lwresd_g_defaultpidfile, first_time);
+ else
+ ns_os_writepidfile(ns_g_defaultpidfile, first_time);
+
+ /*
+ * Configure the server-wide session key. This must be done before
+ * configure views because zone configuration may need to know
+ * session-keyname.
+ *
+ * Failure of session key generation isn't fatal at this time; if it
+ * turns out that a session key is really needed but doesn't exist,
+ * we'll treat it as a fatal error then.
+ */
+ (void)configure_session_key(maps, server, ns_g_mctx);
+
+ /*
* Configure and freeze all explicit views. Explicit
* views that have zones were already created at parsing
* time, but views with no zones must be created here.
@@ -3328,12 +4612,13 @@ load_configuration(const char *filename, ns_server_t *server,
element != NULL;
element = cfg_list_next(element))
{
- const cfg_obj_t *vconfig = cfg_listelt_value(element);
+ cfg_obj_t *vconfig = cfg_listelt_value(element);
view = NULL;
CHECK(create_view(vconfig, &viewlist, &view));
INSIST(view != NULL);
- CHECK(configure_view(view, config, vconfig,
+ CHECK(configure_view(view, conf_parser, config, vconfig,
+ &cachelist, bindkeys,
ns_g_mctx, &aclconfctx, ISC_TRUE));
dns_view_freeze(view);
dns_view_detach(&view);
@@ -3351,15 +4636,15 @@ load_configuration(const char *filename, ns_server_t *server,
* In either case, we need to configure and freeze it.
*/
CHECK(create_view(NULL, &viewlist, &view));
- CHECK(configure_view(view, config, NULL, ns_g_mctx,
- &aclconfctx, ISC_TRUE));
+ CHECK(configure_view(view, conf_parser, config, NULL,
+ &cachelist, bindkeys,
+ ns_g_mctx, &aclconfctx, ISC_TRUE));
dns_view_freeze(view);
dns_view_detach(&view);
}
/*
- * Create (or recreate) the built-in views. Currently
- * there is only one, the _bind view.
+ * Create (or recreate) the built-in views.
*/
builtin_views = NULL;
RUNTIME_CHECK(cfg_map_get(ns_g_config, "view",
@@ -3368,25 +4653,38 @@ load_configuration(const char *filename, ns_server_t *server,
element != NULL;
element = cfg_list_next(element))
{
- const cfg_obj_t *vconfig = cfg_listelt_value(element);
- CHECK(create_view(vconfig, &viewlist, &view));
- CHECK(configure_view(view, config, vconfig, ns_g_mctx,
- &aclconfctx, ISC_FALSE));
+ cfg_obj_t *vconfig = cfg_listelt_value(element);
+
+ CHECK(create_view(vconfig, &builtin_viewlist, &view));
+ CHECK(configure_view(view, conf_parser, config, vconfig,
+ &cachelist, bindkeys,
+ ns_g_mctx, &aclconfctx, ISC_FALSE));
dns_view_freeze(view);
dns_view_detach(&view);
view = NULL;
}
- /*
- * Swap our new view list with the production one.
- */
+ /* Now combine the two viewlists into one */
+ ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link);
+
+ /* Swap our new view list with the production one. */
tmpviewlist = server->viewlist;
server->viewlist = viewlist;
viewlist = tmpviewlist;
- /*
- * Load the TKEY information from the configuration.
- */
+ /* Make the view list available to each of the views */
+ view = ISC_LIST_HEAD(server->viewlist);
+ while (view != NULL) {
+ view->viewlist = &server->viewlist;
+ view = ISC_LIST_NEXT(view, link);
+ }
+
+ /* Swap our new cache list with the production one. */
+ tmpcachelist = server->cachelist;
+ server->cachelist = cachelist;
+ cachelist = tmpcachelist;
+
+ /* Load the TKEY information from the configuration. */
if (options != NULL) {
dns_tkeyctx_t *t = NULL;
CHECKM(ns_tkeyctx_fromconfig(options, ns_g_mctx, ns_g_entropy,
@@ -3551,16 +4849,6 @@ load_configuration(const char *filename, ns_server_t *server,
}
}
- obj = NULL;
- if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS)
- if (cfg_obj_isvoid(obj))
- ns_os_writepidfile(NULL, first_time);
- else
- ns_os_writepidfile(cfg_obj_asstring(obj), first_time);
- else if (ns_g_lwresdonly)
- ns_os_writepidfile(lwresd_g_defaultpidfile, first_time);
- else
- ns_os_writepidfile(ns_g_defaultpidfile, first_time);
obj = NULL;
if (options != NULL &&
@@ -3591,6 +4879,12 @@ load_configuration(const char *filename, ns_server_t *server,
"strdup");
obj = NULL;
+ result = ns_config_get(maps, "secroots-file", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ CHECKM(setstring(server, &server->secrootsfile, cfg_obj_asstring(obj)),
+ "strdup");
+
+ obj = NULL;
result = ns_config_get(maps, "recursing-file", &obj);
INSIST(result == ISC_R_SUCCESS);
CHECKM(setstring(server, &server->recfile, cfg_obj_asstring(obj)),
@@ -3647,12 +4941,18 @@ load_configuration(const char *filename, ns_server_t *server,
if (v6portset != NULL)
isc_portset_destroy(ns_g_mctx, &v6portset);
- cfg_aclconfctx_destroy(&aclconfctx);
+ cfg_aclconfctx_clear(&aclconfctx);
- if (parser != NULL) {
+ if (conf_parser != NULL) {
if (config != NULL)
- cfg_obj_destroy(parser, &config);
- cfg_parser_destroy(&parser);
+ cfg_obj_destroy(conf_parser, &config);
+ cfg_parser_destroy(&conf_parser);
+ }
+
+ if (bindkeys_parser != NULL) {
+ if (bindkeys != NULL)
+ cfg_obj_destroy(bindkeys_parser, &bindkeys);
+ cfg_parser_destroy(&bindkeys_parser);
}
if (view != NULL)
@@ -3675,6 +4975,13 @@ load_configuration(const char *filename, ns_server_t *server,
dns_view_detach(&view);
}
+ /* Same cleanup for cache list. */
+ while ((nsc = ISC_LIST_HEAD(cachelist)) != NULL) {
+ ISC_LIST_UNLINK(cachelist, nsc, link);
+ dns_cache_detach(&nsc->cache);
+ isc_mem_put(server->mctx, nsc, sizeof(*nsc));
+ }
+
/*
* Adjust the listening interfaces in accordance with the source
* addresses specified in views and zones.
@@ -3708,6 +5015,8 @@ load_zones(ns_server_t *server, isc_boolean_t stop) {
view = ISC_LIST_NEXT(view, link))
{
CHECK(dns_view_load(view, stop));
+ if (view->managed_keys != NULL)
+ CHECK(dns_zone_load(view->managed_keys));
}
/*
@@ -3737,11 +5046,14 @@ load_new_zones(ns_server_t *server, isc_boolean_t stop) {
view = ISC_LIST_NEXT(view, link))
{
CHECK(dns_view_loadnew(view, stop));
+
+ /* Load managed-keys data */
+ if (view->managed_keys != NULL)
+ CHECK(dns_zone_loadnew(view->managed_keys));
}
+
/*
- * Force zone maintenance. Do this after loading
- * so that we know when we need to force AXFR of
- * slave zones whose master files are missing.
+ * Resume zone XFRs.
*/
dns_zonemgr_resumexfrs(server->zonemgr);
cleanup:
@@ -3820,6 +5132,7 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_view_t *view, *view_next;
ns_server_t *server = (ns_server_t *)event->ev_arg;
isc_boolean_t flush = server->flushonshutdown;
+ ns_cache_t *nsc;
UNUSED(task);
INSIST(task == server->task);
@@ -3834,6 +5147,7 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
ns_statschannels_shutdown(server);
ns_controls_shutdown(server->controls);
end_reserved_dispatches(server, ISC_TRUE);
+ cleanup_session_key(server, server->mctx);
cfg_obj_destroy(ns_g_parser, &ns_g_config);
cfg_parser_destroy(&ns_g_parser);
@@ -3849,6 +5163,12 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_view_detach(&view);
}
+ while ((nsc = ISC_LIST_HEAD(server->cachelist)) != NULL) {
+ ISC_LIST_UNLINK(server->cachelist, nsc, link);
+ dns_cache_detach(&nsc->cache);
+ isc_mem_put(server->mctx, nsc, sizeof(*nsc));
+ }
+
isc_timer_detach(&server->interface_timer);
isc_timer_detach(&server->heartbeat_timer);
isc_timer_detach(&server->pps_timer);
@@ -3860,6 +5180,11 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_zonemgr_shutdown(server->zonemgr);
+ if (ns_g_sessionkey != NULL) {
+ dns_tsigkey_detach(&ns_g_sessionkey);
+ dns_name_free(&ns_g_sessionkeyname, server->mctx);
+ }
+
if (server->blackholeacl != NULL)
dns_acl_detach(&server->blackholeacl);
@@ -3918,7 +5243,8 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
ISC_R_NOMEMORY : ISC_R_SUCCESS,
"allocating reload event");
- CHECKFATAL(dst_lib_init(ns_g_mctx, ns_g_entropy, ISC_ENTROPY_GOODONLY),
+ CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy,
+ ns_g_engine, ISC_ENTROPY_GOODONLY),
"initializing DST");
server->tkeyctx = NULL;
@@ -3963,10 +5289,20 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
"isc_stats_create");
isc_socketmgr_setstats(ns_g_socketmgr, server->sockstats);
+ server->bindkeysfile = isc_mem_strdup(server->mctx, "bind.keys");
+ CHECKFATAL(server->bindkeysfile == NULL ? ISC_R_NOMEMORY :
+ ISC_R_SUCCESS,
+ "isc_mem_strdup");
+
server->dumpfile = isc_mem_strdup(server->mctx, "named_dump.db");
CHECKFATAL(server->dumpfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
"isc_mem_strdup");
+ server->secrootsfile = isc_mem_strdup(server->mctx, "named.secroots");
+ CHECKFATAL(server->secrootsfile == NULL ? ISC_R_NOMEMORY :
+ ISC_R_SUCCESS,
+ "isc_mem_strdup");
+
server->recfile = isc_mem_strdup(server->mctx, "named.recursing");
CHECKFATAL(server->recfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
"isc_mem_strdup");
@@ -4008,6 +5344,14 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
ISC_LIST_INIT(server->statschannels);
+ ISC_LIST_INIT(server->cachelist);
+
+ server->sessionkey = NULL;
+ server->session_keyfile = NULL;
+ server->session_keyname = NULL;
+ server->session_keyalg = DST_ALG_UNKNOWN;
+ server->session_keybits = 0;
+
server->magic = NS_SERVER_MAGIC;
*serverp = server;
}
@@ -4027,7 +5371,9 @@ ns_server_destroy(ns_server_t **serverp) {
isc_stats_detach(&server->sockstats);
isc_mem_free(server->mctx, server->statsfile);
+ isc_mem_free(server->mctx, server->bindkeysfile);
isc_mem_free(server->mctx, server->dumpfile);
+ isc_mem_free(server->mctx, server->secrootsfile);
isc_mem_free(server->mctx, server->recfile);
if (server->version != NULL)
@@ -4047,6 +5393,7 @@ ns_server_destroy(ns_server_t **serverp) {
isc_event_free(&server->reload_event);
INSIST(ISC_LIST_EMPTY(server->viewlist));
+ INSIST(ISC_LIST_EMPTY(server->cachelist));
dns_aclenv_destroy(&server->aclenv);
@@ -4278,7 +5625,9 @@ next_token(char **stringp, const char *delim) {
* set '*zonep' to NULL.
*/
static isc_result_t
-zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) {
+zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep,
+ const char **zonename)
+{
char *input, *ptr;
const char *zonetxt;
char *classtxt;
@@ -4302,6 +5651,8 @@ zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) {
zonetxt = next_token(&input, " \t");
if (zonetxt == NULL)
return (ISC_R_SUCCESS);
+ if (zonename)
+ *zonename = zonetxt;
/* Look for the optional class name. */
classtxt = next_token(&input, " \t");
@@ -4314,7 +5665,7 @@ zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) {
isc_buffer_add(&buf, strlen(zonetxt));
dns_fixedname_init(&name);
result = dns_name_fromtext(dns_fixedname_name(&name),
- &buf, dns_rootname, ISC_FALSE, NULL);
+ &buf, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
goto fail1;
@@ -4362,7 +5713,7 @@ ns_server_retransfercommand(ns_server_t *server, char *args) {
dns_zone_t *zone = NULL;
dns_zonetype_t type;
- result = zone_from_args(server, args, &zone);
+ result = zone_from_args(server, args, &zone, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL)
@@ -4386,7 +5737,7 @@ ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
dns_zonetype_t type;
const char *msg = NULL;
- result = zone_from_args(server, args, &zone);
+ result = zone_from_args(server, args, &zone, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL) {
@@ -4446,7 +5797,7 @@ ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text) {
dns_zone_t *zone = NULL;
const unsigned char msg[] = "zone notify queued";
- result = zone_from_args(server, args, &zone);
+ result = zone_from_args(server, args, &zone, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL)
@@ -4471,7 +5822,7 @@ ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
const unsigned char msg2[] = "not a slave or stub zone";
dns_zonetype_t type;
- result = zone_from_args(server, args, &zone);
+ result = zone_from_args(server, args, &zone, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL)
@@ -4710,15 +6061,23 @@ dumpdone(void *arg, isc_result_t result) {
nextview:
fprintf(dctx->fp, ";\n; Start view %s\n;\n", dctx->view->view->name);
resume:
- if (dctx->zone == NULL && dctx->cache == NULL && dctx->dumpcache) {
+ if (dctx->dumpcache && dns_view_iscacheshared(dctx->view->view)) {
+ fprintf(dctx->fp,
+ ";\n; Cache of view '%s' is shared as '%s'\n",
+ dctx->view->view->name,
+ dns_cache_getname(dctx->view->view->cache));
+ } else if (dctx->zone == NULL && dctx->cache == NULL &&
+ dctx->dumpcache)
+ {
style = &dns_master_style_cache;
/* start cache dump */
if (dctx->view->view->cachedb != NULL)
dns_db_attach(dctx->view->view->cachedb, &dctx->cache);
if (dctx->cache != NULL) {
-
- fprintf(dctx->fp, ";\n; Cache dump of view '%s'\n;\n",
- dctx->view->view->name);
+ fprintf(dctx->fp,
+ ";\n; Cache dump of view '%s' (cache %s)\n;\n",
+ dctx->view->view->name,
+ dns_cache_getname(dctx->view->view->cache));
result = dns_master_dumptostreaminc(dctx->mctx,
dctx->cache, NULL,
style, dctx->fp,
@@ -4880,6 +6239,68 @@ ns_server_dumpdb(ns_server_t *server, char *args) {
}
isc_result_t
+ns_server_dumpsecroots(ns_server_t *server, char *args) {
+ dns_view_t *view;
+ dns_keytable_t *secroots = NULL;
+ isc_result_t result;
+ char *ptr;
+ FILE *fp = NULL;
+ isc_time_t now;
+ char tbuf[64];
+
+ /* Skip the command name. */
+ ptr = next_token(&args, " \t");
+ if (ptr == NULL)
+ return (ISC_R_UNEXPECTEDEND);
+ ptr = next_token(&args, " \t");
+
+ CHECKMF(isc_stdio_open(server->secrootsfile, "w", &fp),
+ "could not open secroots dump file", server->secrootsfile);
+ TIME_NOW(&now);
+ isc_time_formattimestamp(&now, tbuf, sizeof(tbuf));
+ fprintf(fp, "%s\n", tbuf);
+
+ nextview:
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link))
+ {
+ if (ptr != NULL && strcmp(view->name, ptr) != 0)
+ continue;
+ if (secroots != NULL)
+ dns_keytable_detach(&secroots);
+ result = dns_view_getsecroots(view, &secroots);
+ if (result == ISC_R_NOTFOUND) {
+ result = ISC_R_SUCCESS;
+ continue;
+ }
+ fprintf(fp, "\n Start view %s\n\n", view->name);
+ CHECK(dns_keytable_dump(secroots, fp));
+ }
+ if (ptr != NULL) {
+ ptr = next_token(&args, " \t");
+ if (ptr != NULL)
+ goto nextview;
+ }
+
+ cleanup:
+ if (secroots != NULL)
+ dns_keytable_detach(&secroots);
+ if (fp != NULL)
+ (void)isc_stdio_close(fp);
+ if (result == ISC_R_SUCCESS)
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "dumpsecroots complete");
+ else
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "dumpsecroots failed: %s",
+ dns_result_totext(result));
+ return (result);
+}
+
+isc_result_t
ns_server_dumprecursing(ns_server_t *server) {
FILE *fp = NULL;
isc_result_t result;
@@ -4997,6 +6418,7 @@ ns_server_flushcache(ns_server_t *server, char *args) {
isc_boolean_t flushed;
isc_boolean_t found;
isc_result_t result;
+ ns_cache_t *nsc;
/* Skip the command name. */
ptr = next_token(&args, " \t");
@@ -5010,22 +6432,96 @@ ns_server_flushcache(ns_server_t *server, char *args) {
RUNTIME_CHECK(result == ISC_R_SUCCESS);
flushed = ISC_TRUE;
found = ISC_FALSE;
- for (view = ISC_LIST_HEAD(server->viewlist);
- view != NULL;
- view = ISC_LIST_NEXT(view, link))
- {
- if (viewname != NULL && strcasecmp(viewname, view->name) != 0)
- continue;
+
+ /*
+ * Flushing a cache is tricky when caches are shared by multiple views.
+ * We first identify which caches should be flushed in the local cache
+ * list, flush these caches, and then update other views that refer to
+ * the flushed cache DB.
+ */
+ if (viewname != NULL) {
+ /*
+ * Mark caches that need to be flushed. This is an O(#view^2)
+ * operation in the very worst case, but should be normally
+ * much more lightweight because only a few (most typically just
+ * one) views will match.
+ */
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link))
+ {
+ if (strcasecmp(viewname, view->name) != 0)
+ continue;
+ found = ISC_TRUE;
+ for (nsc = ISC_LIST_HEAD(server->cachelist);
+ nsc != NULL;
+ nsc = ISC_LIST_NEXT(nsc, link)) {
+ if (nsc->cache == view->cache)
+ break;
+ }
+ INSIST(nsc != NULL);
+ nsc->needflush = ISC_TRUE;
+ }
+ } else
found = ISC_TRUE;
- result = dns_view_flushcache(view);
+
+ /* Perform flush */
+ for (nsc = ISC_LIST_HEAD(server->cachelist);
+ nsc != NULL;
+ nsc = ISC_LIST_NEXT(nsc, link)) {
+ if (viewname != NULL && !nsc->needflush)
+ continue;
+ nsc->needflush = ISC_TRUE;
+ result = dns_view_flushcache2(nsc->primaryview, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
flushed = ISC_FALSE;
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"flushing cache in view '%s' failed: %s",
- view->name, isc_result_totext(result));
+ nsc->primaryview->name,
+ isc_result_totext(result));
+ }
+ }
+
+ /*
+ * Fix up views that share a flushed cache: let the views update the
+ * cache DB they're referring to. This could also be an expensive
+ * operation, but should typically be marginal: the inner loop is only
+ * necessary for views that share a cache, and if there are many such
+ * views the number of shared cache should normally be small.
+ * A worst case is that we have n views and n/2 caches, each shared by
+ * two views. Then this will be a O(n^2/4) operation.
+ */
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link))
+ {
+ if (!dns_view_iscacheshared(view))
+ continue;
+ for (nsc = ISC_LIST_HEAD(server->cachelist);
+ nsc != NULL;
+ nsc = ISC_LIST_NEXT(nsc, link)) {
+ if (!nsc->needflush || nsc->cache != view->cache)
+ continue;
+ result = dns_view_flushcache2(view, ISC_TRUE);
+ if (result != ISC_R_SUCCESS) {
+ flushed = ISC_FALSE;
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "fixing cache in view '%s' "
+ "failed: %s", view->name,
+ isc_result_totext(result));
+ }
}
}
+
+ /* Cleanup the cache list. */
+ for (nsc = ISC_LIST_HEAD(server->cachelist);
+ nsc != NULL;
+ nsc = ISC_LIST_NEXT(nsc, link)) {
+ nsc->needflush = ISC_FALSE;
+ }
+
if (flushed && found) {
if (viewname != NULL)
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
@@ -5076,7 +6572,7 @@ ns_server_flushname(ns_server_t *server, char *args) {
isc_buffer_add(&b, strlen(target));
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
@@ -5094,6 +6590,11 @@ ns_server_flushname(ns_server_t *server, char *args) {
if (viewname != NULL && strcasecmp(viewname, view->name) != 0)
continue;
found = ISC_TRUE;
+ /*
+ * It's a little inefficient to try flushing name for all views
+ * if some of the views share a single cache. But since the
+ * operation is lightweight we prefer simplicity here.
+ */
result = dns_view_flushname(view, name);
if (result != ISC_R_SUCCESS) {
flushed = ISC_FALSE;
@@ -5408,6 +6909,46 @@ ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text) {
}
/*
+ * Act on a "sign" or "loadkeys" command from the command channel.
+ */
+isc_result_t
+ns_server_rekey(ns_server_t *server, char *args) {
+ isc_result_t result;
+ dns_zone_t *zone = NULL;
+ dns_zonetype_t type;
+ isc_uint16_t keyopts;
+ isc_boolean_t fullsign = ISC_FALSE;
+
+ if (strncasecmp(args, NS_COMMAND_SIGN, strlen(NS_COMMAND_SIGN)) == 0)
+ fullsign = ISC_TRUE;
+
+ result = zone_from_args(server, args, &zone, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ if (zone == NULL)
+ return (ISC_R_UNEXPECTEDEND); /* XXX: or do all zones? */
+
+ type = dns_zone_gettype(zone);
+ if (type != dns_zone_master) {
+ dns_zone_detach(&zone);
+ return (DNS_R_NOTMASTER);
+ }
+
+ keyopts = dns_zone_getkeyopts(zone);
+
+ /* "rndc loadkeys" requires "auto-dnssec maintain". */
+ if ((keyopts & DNS_ZONEKEY_ALLOW) == 0)
+ result = ISC_R_NOPERM;
+ else if ((keyopts & DNS_ZONEKEY_MAINTAIN) == 0 && !fullsign)
+ result = ISC_R_NOPERM;
+ else
+ dns_zone_rekey(zone, fullsign);
+
+ dns_zone_detach(&zone);
+ return (result);
+}
+
+/*
* Act on a "freeze" or "thaw" command from the command channel.
*/
isc_result_t
@@ -5425,7 +6966,7 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
isc_boolean_t frozen;
const char *msg = NULL;
- result = zone_from_args(server, args, &zone);
+ result = zone_from_args(server, args, &zone, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL) {
@@ -5451,7 +6992,7 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
type = dns_zone_gettype(zone);
if (type != dns_zone_master) {
dns_zone_detach(&zone);
- return (ISC_R_NOTFOUND);
+ return (DNS_R_NOTMASTER);
}
result = isc_task_beginexclusive(server->task);
@@ -5502,8 +7043,8 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
strlen(msg) + 1);
view = dns_zone_getview(zone);
- if (strcmp(view->name, "_bind") == 0 ||
- strcmp(view->name, "_default") == 0)
+ if (strcmp(view->name, "_default") == 0 ||
+ strcmp(view->name, "_bind") == 0)
{
vname = "";
sep = "";
@@ -5543,3 +7084,376 @@ ns_smf_add_message(isc_buffer_t *text) {
return (ISC_R_SUCCESS);
}
#endif /* HAVE_LIBSCF */
+
+/*
+ * Act on an "addzone" command from the command channel.
+ */
+isc_result_t
+ns_server_add_zone(ns_server_t *server, char *args) {
+ isc_result_t result;
+ isc_buffer_t argbuf;
+ size_t arglen;
+ cfg_parser_t *parser = NULL;
+ cfg_obj_t *config = NULL;
+ const cfg_obj_t *vconfig = NULL;
+ const cfg_obj_t *views = NULL;
+ const cfg_obj_t *parms = NULL;
+ const cfg_obj_t *obj = NULL;
+ const cfg_listelt_t *element;
+ const char *zonename;
+ const char *classname = NULL;
+ const char *argp;
+ const char *viewname = NULL;
+ dns_rdataclass_t rdclass;
+ dns_view_t *view = 0;
+ isc_buffer_t buf, *nbuf = NULL;
+ dns_name_t dnsname;
+ dns_zone_t *zone = NULL;
+ FILE *fp = NULL;
+ struct cfg_context *cfg = NULL;
+
+ /* Try to parse the argument string */
+ arglen = strlen(args);
+ isc_buffer_init(&argbuf, args, arglen);
+ isc_buffer_add(&argbuf, strlen(args));
+ CHECK(cfg_parser_create(server->mctx, ns_g_lctx, &parser));
+ CHECK(cfg_parse_buffer(parser, &argbuf, &cfg_type_addzoneconf,
+ &config));
+ CHECK(cfg_map_get(config, "addzone", &parms));
+
+ zonename = cfg_obj_asstring(cfg_tuple_get(parms, "name"));
+ isc_buffer_init(&buf, zonename, strlen(zonename));
+ isc_buffer_add(&buf, strlen(zonename));
+ dns_name_init(&dnsname, NULL);
+ isc_buffer_allocate(server->mctx, &nbuf, 256);
+ dns_name_setbuffer(&dnsname, nbuf);
+ CHECK(dns_name_fromtext(&dnsname, &buf, dns_rootname, ISC_FALSE, NULL));
+
+ /* Make sense of optional class argument */
+ obj = cfg_tuple_get(parms, "class");
+ CHECK(ns_config_getclass(obj, dns_rdataclass_in, &rdclass));
+ if (rdclass != dns_rdataclass_in && obj)
+ classname = cfg_obj_asstring(obj);
+
+ /* Make sense of optional view argument */
+ obj = cfg_tuple_get(parms, "view");
+ if (obj && cfg_obj_isstring(obj))
+ viewname = cfg_obj_asstring(obj);
+ if (viewname == NULL || *viewname == '\0')
+ viewname = "_default";
+ CHECK(dns_viewlist_find(&server->viewlist, viewname, rdclass, &view));
+
+ /* Are we accepting new zones? */
+ if (view->new_zone_file == NULL) {
+ result = ISC_R_NOPERM;
+ goto cleanup;
+ }
+
+ cfg = (struct cfg_context *) view->new_zone_config;
+ if (cfg == NULL) {
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
+ /* Zone shouldn't already exist */
+ result = dns_zt_find(view->zonetable, &dnsname, 0, NULL, &zone);
+ if (result == ISC_R_SUCCESS) {
+ result = ISC_R_EXISTS;
+ goto cleanup;
+ } else if (result == DNS_R_PARTIALMATCH) {
+ /* Create our sub-zone anyway */
+ dns_zone_detach(&zone);
+ zone = NULL;
+ }
+ else if (result != ISC_R_NOTFOUND)
+ goto cleanup;
+
+ /* Find the view statement */
+ cfg_map_get(cfg->config, "view", &views);
+ for (element = cfg_list_first(views);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const char *vname;
+ vconfig = cfg_listelt_value(element);
+ vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name"));
+ if (vname && !strcasecmp(vname, viewname))
+ break;
+ vconfig = NULL;
+ }
+
+ /* Open save file for write configuration */
+ CHECK(isc_stdio_open(view->new_zone_file, "a", &fp));
+
+ /* Mark view unfrozen so that zone can be added */
+ dns_view_thaw(view);
+ result = configure_zone(cfg->config, parms, vconfig,
+ server->mctx, view, &cfg->actx, ISC_FALSE);
+ dns_view_freeze(view);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
+
+ /* Is it there yet? */
+ CHECK(dns_zt_find(view->zonetable, &dnsname, 0, NULL, &zone));
+
+ /*
+ * Load the zone from the master file. If this fails, we'll
+ * need to undo the configuration we've done already.
+ */
+ result = dns_zone_loadnew(zone);
+ if (result != ISC_R_SUCCESS) {
+ dns_db_t *dbp = NULL;
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "addzone failed; reverting.");
+
+ /* If the zone loaded partially, unload it */
+ if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) {
+ dns_db_detach(&dbp);
+ dns_zone_unload(zone);
+ }
+
+ /* Remove the zone from the zone table */
+ dns_zt_unmount(view->zonetable, zone);
+ goto cleanup;
+ }
+
+ /* Flag the zone as having been added at runtime */
+ dns_zone_setadded(zone, ISC_TRUE);
+
+ /* Emit just the zone name from args */
+ CHECK(isc_stdio_write("zone ", 5, 1, fp, NULL));
+ CHECK(isc_stdio_write(zonename, strlen(zonename), 1, fp, NULL));
+ CHECK(isc_stdio_write(" ", 1, 1, fp, NULL));
+
+ /* Classname, if not default */
+ if (classname != NULL && *classname != '\0') {
+ CHECK(isc_stdio_write(classname, strlen(classname), 1, fp,
+ NULL));
+ CHECK(isc_stdio_write(" ", 1, 1, fp, NULL));
+ }
+
+ /* Find beginning of option block from args */
+ for (argp = args; *argp; argp++, arglen--) {
+ if (*argp == '{') { /* Assume matching '}' */
+ /* Add that to our file */
+ CHECK(isc_stdio_write(argp, arglen, 1, fp, NULL));
+
+ /* Make sure we end with a LF */
+ if (argp[arglen-1] != '\n') {
+ CHECK(isc_stdio_write("\n", 1, 1, fp, NULL));
+ }
+ break;
+ }
+ }
+
+ CHECK(isc_stdio_close(fp));
+ fp = NULL;
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "zone %s added to view %s via addzone",
+ zonename, viewname);
+
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (fp != NULL)
+ isc_stdio_close(fp);
+ if (parser != NULL) {
+ if (config != NULL)
+ cfg_obj_destroy(parser, &config);
+ cfg_parser_destroy(&parser);
+ }
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ if (view != NULL)
+ dns_view_detach(&view);
+ if (nbuf != NULL)
+ isc_buffer_free(&nbuf);
+
+ return (result);
+}
+
+/*
+ * Act on a "delzone" command from the command channel.
+ */
+isc_result_t
+ns_server_del_zone(ns_server_t *server, char *args) {
+ isc_result_t result;
+ dns_zone_t *zone = NULL;
+ dns_view_t *view = NULL;
+ dns_db_t *dbp = NULL;
+ const char *filename = NULL;
+ char *tmpname = NULL;
+ char buf[1024];
+ const char *zonename = NULL;
+ size_t znamelen = 0;
+ FILE *ifp = NULL, *ofp = NULL;
+
+ /* Parse parameters */
+ CHECK(zone_from_args(server, args, &zone, &zonename));
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ if (zone == NULL) {
+ result = ISC_R_UNEXPECTEDEND;
+ goto cleanup;
+ }
+
+ /*
+ * Was this zone originally added at runtime?
+ * If not, we can't delete it now.
+ */
+ if (!dns_zone_getadded(zone)) {
+ result = ISC_R_NOPERM;
+ goto cleanup;
+ }
+
+ if (zonename != NULL)
+ znamelen = strlen(zonename);
+
+ /* Dig out configuration for this zone */
+ view = dns_zone_getview(zone);
+ filename = view->new_zone_file;
+ if (filename == NULL) {
+ /* No adding zones in this view */
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
+ /* Rewrite zone list */
+ result = isc_stdio_open(filename, "r", &ifp);
+ if (ifp != NULL && result == ISC_R_SUCCESS) {
+ char *found = NULL, *p = NULL;
+ size_t n;
+
+ /* Create a temporary file */
+ CHECK(isc_string_printf(buf, 1023, "%s.%ld", filename,
+ (long)getpid()));
+ if (!(tmpname = isc_mem_strdup(server->mctx, buf))) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ CHECK(isc_stdio_open(tmpname, "w", &ofp));
+
+ /* Look for the entry for that zone */
+ while (fgets(buf, 1024, ifp)) {
+ /* A 'zone' line */
+ if (strncasecmp(buf, "zone", 4)) {
+ fputs(buf, ofp);
+ continue;
+ }
+ p = buf+4;
+
+ /* Locate a name */
+ while (*p &&
+ ((*p == '"') || isspace((unsigned char)*p)))
+ p++;
+
+ /* Is that the zone we're looking for */
+ if (strncasecmp(p, zonename, znamelen)) {
+ fputs(buf, ofp);
+ continue;
+ }
+
+ /* And nothing else? */
+ p += znamelen;
+ if (isspace((unsigned char)*p) ||
+ *p == '"' || *p == '{') {
+ /* This must be the entry */
+ found = p;
+ break;
+ }
+
+ /* Spit it out, keep looking */
+ fputs(buf, ofp);
+ }
+
+ /* Skip over an option block (matching # of braces) */
+ if (found) {
+ int obrace = 0, cbrace = 0;
+ for (;;) {
+ while (*p) {
+ if (*p == '{') obrace++;
+ if (*p == '}') cbrace++;
+ p++;
+ }
+ if (obrace && (obrace == cbrace))
+ break;
+ if (!fgets(buf, 1024, ifp))
+ break;
+ p = buf;
+ }
+
+ /* Just spool the remainder of the file out */
+ result = isc_stdio_read(buf, 1, 1024, ifp, &n);
+ while (n > 0U) {
+ if (result == ISC_R_EOF)
+ result = ISC_R_SUCCESS;
+ CHECK(result);
+ isc_stdio_write(buf, 1, n, ofp, NULL);
+ result = isc_stdio_read(buf, 1, 1024, ifp, &n);
+ }
+
+ /* Move temporary into place */
+ CHECK(isc_file_rename(tmpname, view->new_zone_file));
+ } else {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "deleted zone %s was missing from "
+ "new zone file", zonename);
+ goto cleanup;
+ }
+ }
+
+ /* Stop answering for this zone */
+ if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) {
+ dns_db_detach(&dbp);
+ dns_zone_unload(zone);
+ }
+
+ CHECK(dns_zt_unmount(view->zonetable, zone));
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "zone %s removed via delzone", zonename);
+
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (ifp != NULL)
+ isc_stdio_close(ifp);
+ if (ofp != NULL) {
+ isc_stdio_close(ofp);
+ isc_file_remove(tmpname);
+ }
+ if (tmpname != NULL)
+ isc_mem_free(server->mctx, tmpname);
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+
+ return (result);
+}
+
+static void
+cfgctx_destroy(void **cfgp) {
+ struct cfg_context *cfg;
+ isc_mem_t *mctx;
+
+ REQUIRE(cfgp != NULL && *cfgp != NULL);
+ cfg = *cfgp;
+ mctx = cfg->mctx;
+ cfg->mctx = NULL;
+
+ if (cfg->parser != NULL) {
+ if (cfg->config != NULL)
+ cfg_obj_destroy(cfg->parser, &cfg->config);
+ cfg_parser_destroy(&cfg->parser);
+ }
+ cfg_aclconfctx_clear(&cfg->actx);
+
+ isc_mem_put(mctx, cfg, sizeof(*cfg));
+ isc_mem_detach(&mctx);
+ *cfgp = NULL;
+}
diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c
index c77d3ca1bfeb..6dce8e0a77c5 100644
--- a/bin/named/statschannel.c
+++ b/bin/named/statschannel.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: statschannel.c,v 1.14.64.11 2010-02-04 23:47:46 tbox Exp $ */
+/* $Id: statschannel.c,v 1.26 2010-02-04 23:49:13 tbox Exp $ */
/*! \file */
@@ -29,6 +29,7 @@
#include <isc/stats.h>
#include <isc/task.h>
+#include <dns/cache.h>
#include <dns/db.h>
#include <dns/opcode.h>
#include <dns/resolver.h>
@@ -823,9 +824,9 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
TRY0(xmlTextWriterStartElement(writer,
ISC_XMLCHAR "cache"));
TRY0(xmlTextWriterWriteAttribute(writer,
- ISC_XMLCHAR "name",
- ISC_XMLCHAR
- view->name));
+ ISC_XMLCHAR "name",
+ ISC_XMLCHAR
+ dns_cache_getname(view->cache)));
dumparg.result = ISC_R_SUCCESS;
dns_rdatasetstats_dump(cachestats, rdatasetstats_dump,
&dumparg, 0);
@@ -1405,7 +1406,15 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
if (strcmp(view->name, "_default") == 0)
fprintf(fp, "[View: default]\n");
else
- fprintf(fp, "[View: %s]\n", view->name);
+ fprintf(fp, "[View: %s (Cache: %s)]\n", view->name,
+ dns_cache_getname(view->cache));
+ if (dns_view_iscacheshared(view)) {
+ /*
+ * Avoid dumping redundant statistics when the cache is
+ * shared.
+ */
+ continue;
+ }
dns_rdatasetstats_dump(cachestats, rdatasetstats_dump, &dumparg,
0);
}
diff --git a/bin/named/tkeyconf.c b/bin/named/tkeyconf.c
index 734497803191..66c2d7f47cc9 100644
--- a/bin/named/tkeyconf.c
+++ b/bin/named/tkeyconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tkeyconf.c,v 1.29 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: tkeyconf.c,v 1.33 2010-12-20 23:47:20 tbox Exp $ */
/*! \file */
@@ -77,8 +77,7 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_add(&b, strlen(s));
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- RETERR(dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL));
+ RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY;
RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH,
type, NULL, mctx, &tctx->dhkey));
@@ -92,8 +91,7 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_add(&b, strlen(s));
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE,
- NULL));
+ RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t));
if (tctx->domain == NULL) {
result = ISC_R_NOMEMORY;
@@ -112,12 +110,22 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_add(&b, strlen(s));
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
- RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE,
- NULL));
- RETERR(dst_gssapi_acquirecred(name, ISC_FALSE,
- &tctx->gsscred));
+ RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
+ RETERR(dst_gssapi_acquirecred(name, ISC_FALSE, &tctx->gsscred));
}
+ obj = NULL;
+ result = cfg_map_get(options, "tkey-gssapi-keytab", &obj);
+ if (result == ISC_R_SUCCESS) {
+ s = cfg_obj_asstring(obj);
+ tctx->gssapi_keytab = isc_mem_strdup(mctx, s);
+ if (tctx->gssapi_keytab == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto failure;
+ }
+ }
+
+
*tctxp = tctx;
return (ISC_R_SUCCESS);
diff --git a/bin/named/tsigconf.c b/bin/named/tsigconf.c
index e90a86b5a783..19e8d385e05b 100644
--- a/bin/named/tsigconf.c
+++ b/bin/named/tsigconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tsigconf.c,v 1.30 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: tsigconf.c,v 1.35 2011-01-11 23:47:12 tbox Exp $ */
/*! \file */
@@ -82,7 +82,7 @@ add_initial_keys(const cfg_obj_t *list, dns_tsig_keyring_t *ring,
isc_buffer_add(&keynamesrc, strlen(keyid));
isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata));
ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname,
- ISC_TRUE, &keynamebuf);
+ DNS_NAME_DOWNCASE, &keynamebuf);
if (ret != ISC_R_SUCCESS)
goto failure;
@@ -149,6 +149,8 @@ ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
isc_result_t result;
int i;
+ REQUIRE(ringp != NULL && *ringp == NULL);
+
i = 0;
if (config != NULL)
maps[i++] = config;
@@ -176,6 +178,6 @@ ns_tsigkeyring_fromconfig(const cfg_obj_t *config, const cfg_obj_t *vconfig,
return (ISC_R_SUCCESS);
failure:
- dns_tsigkeyring_destroy(&ring);
+ dns_tsigkeyring_detach(&ring);
return (result);
}
diff --git a/bin/named/unix/Makefile.in b/bin/named/unix/Makefile.in
index 502db2508c98..ca92c49b5c78 100644
--- a/bin/named/unix/Makefile.in
+++ b/bin/named/unix/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.10 2007-06-19 23:46:59 tbox Exp $
+# $Id: Makefile.in,v 1.13 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/bin/named/unix/include/named/os.h b/bin/named/unix/include/named/os.h
index 0a846080a66f..c2768f426647 100644
--- a/bin/named/unix/include/named/os.h
+++ b/bin/named/unix/include/named/os.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.h,v 1.29 2008-10-24 01:44:48 tbox Exp $ */
+/* $Id: os.h,v 1.31 2009-08-05 23:47:43 tbox Exp $ */
#ifndef NS_OS_H
#define NS_OS_H 1
@@ -51,8 +51,12 @@ ns_os_adjustnofile(void);
void
ns_os_minprivs(void);
+FILE *
+ns_os_openfile(const char *filename, mode_t mode, isc_boolean_t switch_user);
+
void
ns_os_writepidfile(const char *filename, isc_boolean_t first_time);
+
void
ns_os_shutdown(void);
diff --git a/bin/named/unix/os.c b/bin/named/unix/os.c
index 3f07784fcb82..53e9e4501249 100644
--- a/bin/named/unix/os.c
+++ b/bin/named/unix/os.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.c,v 1.89.12.5 2009-03-02 03:03:54 marka Exp $ */
+/* $Id: os.c,v 1.104 2010-11-17 23:47:08 tbox Exp $ */
/*! \file */
@@ -291,6 +291,12 @@ linux_initialprivs(void) {
*/
SET_CAP(CAP_SYS_RESOURCE);
+ /*
+ * We need to be able to set the ownership of the containing
+ * directory of the pid file when we create it.
+ */
+ SET_CAP(CAP_CHOWN);
+
linux_setcaps(caps);
#ifdef HAVE_LIBCAP
@@ -631,7 +637,7 @@ ns_os_minprivs(void) {
}
static int
-safe_open(const char *filename, isc_boolean_t append) {
+safe_open(const char *filename, mode_t mode, isc_boolean_t append) {
int fd;
struct stat sb;
@@ -644,13 +650,11 @@ safe_open(const char *filename, isc_boolean_t append) {
}
if (append)
- fd = open(filename, O_WRONLY|O_CREAT|O_APPEND,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, mode);
else {
if (unlink(filename) < 0 && errno != ENOENT)
return (-1);
- fd = open(filename, O_WRONLY|O_CREAT|O_EXCL,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
}
return (fd);
}
@@ -686,6 +690,15 @@ mkdirpath(char *filename, void (*report)(const char *, ...)) {
}
if (mkdirpath(filename, report) == -1)
goto error;
+ /*
+ * Handle "//", "/./" and "/../" in path.
+ */
+ if (!strcmp(slash + 1, "") ||
+ !strcmp(slash + 1, ".") ||
+ !strcmp(slash + 1, "..")) {
+ *slash = '/';
+ return (0);
+ }
mode = S_IRUSR | S_IWUSR | S_IXUSR; /* u=rwx */
mode |= S_IRGRP | S_IXGRP; /* g=rx */
mode |= S_IROTH | S_IXOTH; /* o=rx */
@@ -695,6 +708,13 @@ mkdirpath(char *filename, void (*report)(const char *, ...)) {
strbuf);
goto error;
}
+ if (runas_pw != NULL &&
+ chown(filename, runas_pw->pw_uid,
+ runas_pw->pw_gid) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ (*report)("couldn't chown '%s': %s", filename,
+ strbuf);
+ }
}
*slash = '/';
}
@@ -705,11 +725,127 @@ mkdirpath(char *filename, void (*report)(const char *, ...)) {
return (-1);
}
+static void
+setperms(uid_t uid, gid_t gid) {
+ char strbuf[ISC_STRERRORSIZE];
+#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID)
+ gid_t oldgid, tmpg;
+#endif
+#if !defined(HAVE_SETEUID) && defined(HAVE_SETRESUID)
+ uid_t olduid, tmpu;
+#endif
+#if defined(HAVE_SETEGID)
+ if (getegid() != gid && setegid(gid) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("unable to set effective gid to %ld: %s",
+ (long)gid, strbuf);
+ }
+#elif defined(HAVE_SETRESGID)
+ if (getresgid(&tmpg, &oldgid, &tmpg) == -1 || oldgid != gid) {
+ if (setresgid(-1, gid, -1) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("unable to set effective "
+ "gid to %d: %s", gid, strbuf);
+ }
+ }
+#endif
+
+#if defined(HAVE_SETEUID)
+ if (geteuid() != uid && seteuid(uid) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("unable to set effective uid to %ld: %s",
+ (long)uid, strbuf);
+ }
+#elif defined(HAVE_SETRESUID)
+ if (getresuid(&tmpu, &olduid, &tmpu) == -1 || olduid != uid) {
+ if (setresuid(-1, uid, -1) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("unable to set effective "
+ "uid to %d: %s", uid, strbuf);
+ }
+ }
+#endif
+}
+
+FILE *
+ns_os_openfile(const char *filename, mode_t mode, isc_boolean_t switch_user) {
+ char strbuf[ISC_STRERRORSIZE], *f;
+ FILE *fp;
+ int fd;
+
+ /*
+ * Make the containing directory if it doesn't exist.
+ */
+ f = strdup(filename);
+ if (f == NULL) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("couldn't strdup() '%s': %s",
+ filename, strbuf);
+ return (NULL);
+ }
+ if (mkdirpath(f, ns_main_earlywarning) == -1) {
+ free(f);
+ return (NULL);
+ }
+ free(f);
+
+ if (switch_user && runas_pw != NULL) {
+ /* Set UID/GID to the one we'll be running with eventually */
+ setperms(runas_pw->pw_uid, runas_pw->pw_gid);
+
+ fd = safe_open(filename, mode, ISC_FALSE);
+
+#ifndef HAVE_LINUXTHREADS
+ /* Restore UID/GID to root */
+ setperms(0, 0);
+#endif /* HAVE_LINUXTHREADS */
+
+ if (fd == -1) {
+#ifndef HAVE_LINUXTHREADS
+ fd = safe_open(filename, mode, ISC_FALSE);
+ if (fd != -1) {
+ ns_main_earlywarning("Required root "
+ "permissions to open "
+ "'%s'.", filename);
+ } else {
+ ns_main_earlywarning("Could not open "
+ "'%s'.", filename);
+ }
+ ns_main_earlywarning("Please check file and "
+ "directory permissions "
+ "or reconfigure the filename.");
+#else /* HAVE_LINUXTHREADS */
+ ns_main_earlywarning("Could not open "
+ "'%s'.", filename);
+ ns_main_earlywarning("Please check file and "
+ "directory permissions "
+ "or reconfigure the filename.");
+#endif /* HAVE_LINUXTHREADS */
+ }
+ } else {
+ fd = safe_open(filename, mode, ISC_FALSE);
+ }
+
+ if (fd < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("could not open file '%s': %s",
+ filename, strbuf);
+ return (NULL);
+ }
+
+ fp = fdopen(fd, "w");
+ if (fp == NULL) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ns_main_earlywarning("could not fdopen() file '%s': %s",
+ filename, strbuf);
+ }
+
+ return (fp);
+}
+
void
ns_os_writepidfile(const char *filename, isc_boolean_t first_time) {
- int fd;
FILE *lockfile;
- size_t len;
pid_t pid;
char strbuf[ISC_STRERRORSIZE];
void (*report)(const char *, ...);
@@ -725,40 +861,16 @@ ns_os_writepidfile(const char *filename, isc_boolean_t first_time) {
if (filename == NULL)
return;
- len = strlen(filename);
- pidfile = malloc(len + 1);
+ pidfile = strdup(filename);
if (pidfile == NULL) {
isc__strerror(errno, strbuf, sizeof(strbuf));
- (*report)("couldn't malloc '%s': %s", filename, strbuf);
+ (*report)("couldn't strdup() '%s': %s", filename, strbuf);
return;
}
- /* This is safe. */
- strcpy(pidfile, filename);
-
- /*
- * Make the containing directory if it doesn't exist.
- */
- if (mkdirpath(pidfile, report) == -1) {
- free(pidfile);
- pidfile = NULL;
- return;
- }
-
- fd = safe_open(filename, ISC_FALSE);
- if (fd < 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- (*report)("couldn't open pid file '%s': %s", filename, strbuf);
- free(pidfile);
- pidfile = NULL;
- return;
- }
- lockfile = fdopen(fd, "w");
+ lockfile = ns_os_openfile(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
+ first_time);
if (lockfile == NULL) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- (*report)("could not fdopen() pid file '%s': %s",
- filename, strbuf);
- (void)close(fd);
cleanup_pidfile();
return;
}
diff --git a/bin/named/update.c b/bin/named/update.c
index 1504a44b5ad0..eb1ed1d64ef9 100644
--- a/bin/named/update.c
+++ b/bin/named/update.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: update.c,v 1.151.12.11 2010-02-26 23:48:43 tbox Exp $ */
+/* $Id: update.c,v 1.186.16.1.2.1 2011-06-02 23:47:28 tbox Exp $ */
#include <config.h>
@@ -38,6 +38,7 @@
#include <dns/message.h>
#include <dns/nsec.h>
#include <dns/nsec3.h>
+#include <dns/private.h>
#include <dns/rdataclass.h>
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
@@ -45,6 +46,7 @@
#include <dns/rdatatype.h>
#include <dns/soa.h>
#include <dns/ssu.h>
+#include <dns/tsig.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zt.h>
@@ -281,6 +283,47 @@ inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
}
/*%
+ * Check if we could have queried for the contents of this zone or
+ * if the zone is potentially updateable.
+ * If the zone can potentially be updated and the check failed then
+ * log a error otherwise we log a informational message.
+ */
+static isc_result_t
+checkqueryacl(ns_client_t *client, dns_acl_t *queryacl, dns_name_t *zonename,
+ dns_acl_t *updateacl, dns_ssutable_t *ssutable)
+{
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char classbuf[DNS_RDATACLASS_FORMATSIZE];
+ int level;
+ isc_result_t result;
+
+ result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE);
+ if (result != ISC_R_SUCCESS) {
+ dns_name_format(zonename, namebuf, sizeof(namebuf));
+ dns_rdataclass_format(client->view->rdclass, classbuf,
+ sizeof(classbuf));
+
+ level = (updateacl == NULL && ssutable == NULL) ?
+ ISC_LOG_INFO : ISC_LOG_ERROR;
+
+ ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY,
+ NS_LOGMODULE_UPDATE, level,
+ "update '%s/%s' denied due to allow-query",
+ namebuf, classbuf);
+ } else if (updateacl == NULL && ssutable == NULL) {
+ dns_name_format(zonename, namebuf, sizeof(namebuf));
+ dns_rdataclass_format(client->view->rdclass, classbuf,
+ sizeof(classbuf));
+
+ result = DNS_R_REFUSED;
+ ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY,
+ NS_LOGMODULE_UPDATE, ISC_LOG_INFO,
+ "update '%s/%s' denied", namebuf, classbuf);
+ }
+ return (result);
+}
+
+/*%
* Override the default acl logging when checking whether a client
* can update the zone or whether we can forward the request to the
* master based on IP address.
@@ -809,6 +852,9 @@ typedef struct {
/* The ssu table to check against. */
dns_ssutable_t *table;
+
+ /* the key used for TKEY requests */
+ dst_key_t *key;
} ssu_check_t;
static isc_result_t
@@ -825,14 +871,14 @@ ssu_checkrule(void *data, dns_rdataset_t *rrset) {
return (ISC_R_SUCCESS);
result = dns_ssutable_checkrules(ssuinfo->table, ssuinfo->signer,
ssuinfo->name, ssuinfo->tcpaddr,
- rrset->type);
+ rrset->type, ssuinfo->key);
return (result == ISC_TRUE ? ISC_R_SUCCESS : ISC_R_FAILURE);
}
static isc_boolean_t
ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_ssutable_t *ssutable, dns_name_t *signer,
- isc_netaddr_t *tcpaddr)
+ isc_netaddr_t *tcpaddr, dst_key_t *key)
{
isc_result_t result;
ssu_check_t ssuinfo;
@@ -841,6 +887,7 @@ ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
ssuinfo.table = ssutable;
ssuinfo.signer = signer;
ssuinfo.tcpaddr = tcpaddr;
+ ssuinfo.key = key;
result = foreach_rrset(db, ver, name, ssu_checkrule, &ssuinfo);
return (ISC_TF(result == ISC_R_SUCCESS));
}
@@ -889,7 +936,7 @@ temp_check_rrset(dns_difftuple_t *a, dns_difftuple_t *b) {
b->op == DNS_DIFFOP_EXISTS);
INSIST(a->rdata.type == b->rdata.type);
INSIST(dns_name_equal(&a->name, &b->name));
- if (dns_rdata_compare(&a->rdata, &b->rdata) != 0)
+ if (dns_rdata_casecompare(&a->rdata, &b->rdata) != 0)
return (DNS_R_NXRRSET);
a = ISC_LIST_NEXT(a, link);
b = ISC_LIST_NEXT(b, link);
@@ -917,7 +964,7 @@ temp_order(const void *av, const void *bv) {
r = (b->rdata.type - a->rdata.type);
if (r != 0)
return (r);
- r = dns_rdata_compare(&a->rdata, &b->rdata);
+ r = dns_rdata_casecompare(&a->rdata, &b->rdata);
return (r);
}
@@ -1146,7 +1193,7 @@ rr_equal_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
* dns_rdata_equal() (that used dns_name_equal()), since it
* would be faster. Not a priority.
*/
- return (dns_rdata_compare(update_rr, db_rr) == 0 ?
+ return (dns_rdata_casecompare(update_rr, db_rr) == 0 ?
ISC_TRUE : ISC_FALSE);
}
@@ -1208,11 +1255,10 @@ replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
return (ISC_FALSE);
INSIST(db_rr->length >= 4 && update_rr->length >= 4);
/*
- * Replace records added in this UPDATE request.
+ * Replace NSEC3PARAM records that only differ by the
+ * flags field.
*/
if (db_rr->data[0] == update_rr->data[0] &&
- db_rr->data[1] & DNS_NSEC3FLAG_UPDATE &&
- update_rr->data[1] & DNS_NSEC3FLAG_UPDATE &&
memcmp(db_rr->data+2, update_rr->data+2,
update_rr->length - 2) == 0)
return (ISC_TRUE);
@@ -1293,7 +1339,7 @@ add_rr_prepare_action(void *data, rr_t *rr) {
* If the update RR is a "duplicate" of the update RR,
* the update should be silently ignored.
*/
- equal = ISC_TF(dns_rdata_compare(&rr->rdata, ctx->update_rr) == 0);
+ equal = ISC_TF(dns_rdata_casecompare(&rr->rdata, ctx->update_rr) == 0);
if (equal && rr->ttl == ctx->update_rr_ttl) {
ctx->ignore_add = ISC_TRUE;
return (ISC_R_SUCCESS);
@@ -1717,35 +1763,6 @@ next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
return (result);
}
-static isc_boolean_t
-has_opt_bit(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t rdataset;
- isc_boolean_t has_bit = ISC_FALSE;
-
- dns_rdataset_init(&rdataset);
- CHECK(dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
- dns_rdatatype_none, 0, &rdataset, NULL));
- CHECK(dns_rdataset_first(&rdataset));
- dns_rdataset_current(&rdataset, &rdata);
- has_bit = dns_nsec_typepresent(&rdata, dns_rdatatype_opt);
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- return (has_bit);
-}
-
-static void
-set_bit(unsigned char *array, unsigned int index) {
- unsigned int shift, bit;
-
- shift = 7 - (index % 8);
- bit = 1 << shift;
-
- array[index / 8] |= bit;
-}
-
/*%
* Add a NSEC record for "name", recording the change in "diff".
* The existing NSEC is removed.
@@ -1777,24 +1794,6 @@ add_nsec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
dns_rdata_init(&rdata);
CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata));
- /*
- * Preserve the status of the OPT bit in the origin's NSEC record.
- */
- if (dns_name_equal(dns_db_origin(db), name) &&
- has_opt_bit(db, ver, node))
- {
- isc_region_t region;
- dns_name_t next;
-
- dns_name_init(&next, NULL);
- dns_rdata_toregion(&rdata, &region);
- dns_name_fromregion(&next, &region);
- isc_region_consume(&region, next.length);
- INSIST(region.length > (2 + dns_rdatatype_opt / 8) &&
- region.base[0] == 0 &&
- region.base[1] > dns_rdatatype_opt / 8);
- set_bit(region.base + 2, dns_rdatatype_opt);
- }
dns_db_detachnode(db, &node);
/*
@@ -1856,44 +1855,6 @@ find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
return (result);
}
-static isc_boolean_t
-ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) {
- isc_boolean_t ret = ISC_FALSE;
- isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE;
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_dnskey_t dnskey;
-
- dns_rdataset_init(&rdataset);
- CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
- CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0,
- &rdataset, NULL));
- CHECK(dns_rdataset_first(&rdataset));
- while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) {
- dns_rdataset_current(&rdataset, &rdata);
- CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
- if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
- == DNS_KEYOWNER_ZONE) {
- if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0)
- have_ksk = ISC_TRUE;
- else
- have_nonksk = ISC_TRUE;
- }
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&rdataset);
- }
- if (have_ksk && have_nonksk)
- ret = ISC_TRUE;
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (ret);
-}
-
/*%
* Add RRSIG records for an RRset, recording the change in "diff".
*/
@@ -1902,7 +1863,7 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type,
dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys,
isc_stdtime_t inception, isc_stdtime_t expire,
- isc_boolean_t check_ksk)
+ isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly)
{
isc_result_t result;
dns_dbnode_t *node = NULL;
@@ -1910,7 +1871,7 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_rdata_t sig_rdata = DNS_RDATA_INIT;
isc_buffer_t buffer;
unsigned char data[1024]; /* XXX */
- unsigned int i;
+ unsigned int i, j;
isc_boolean_t added_sig = ISC_FALSE;
isc_mem_t *mctx = client->mctx;
@@ -1926,13 +1887,52 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
(isc_stdtime_t) 0, &rdataset, NULL));
dns_db_detachnode(db, &node);
+#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
+#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
+#define ALG(x) dst_key_alg(x)
+
+ /*
+ * If we are honoring KSK flags then we need to check that we
+ * have both KSK and non-KSK keys that are not revoked per
+ * algorithm.
+ */
for (i = 0; i < nkeys; i++) {
+ isc_boolean_t both = ISC_FALSE;
- if (check_ksk && type != dns_rdatatype_dnskey &&
- (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0)
+ if (!dst_key_isprivate(keys[i]))
continue;
- if (!dst_key_isprivate(keys[i]))
+ if (check_ksk && !REVOKE(keys[i])) {
+ isc_boolean_t have_ksk, have_nonksk;
+ if (KSK(keys[i])) {
+ have_ksk = ISC_TRUE;
+ have_nonksk = ISC_FALSE;
+ } else {
+ have_ksk = ISC_FALSE;
+ have_nonksk = ISC_TRUE;
+ }
+ for (j = 0; j < nkeys; j++) {
+ if (j == i || ALG(keys[i]) != ALG(keys[j]))
+ continue;
+ if (REVOKE(keys[j]))
+ continue;
+ if (KSK(keys[j]))
+ have_ksk = ISC_TRUE;
+ else
+ have_nonksk = ISC_TRUE;
+ both = have_ksk && have_nonksk;
+ if (both)
+ break;
+ }
+ }
+
+ if (both) {
+ if (type == dns_rdatatype_dnskey) {
+ if (!KSK(keys[i]) && keyset_kskonly)
+ continue;
+ } else if (KSK(keys[i]))
+ continue;
+ } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
continue;
/* Calculate the signature, creating a RRSIG RDATA. */
@@ -1950,7 +1950,7 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
}
if (!added_sig) {
update_log(client, zone, ISC_LOG_ERROR,
- "found no private keys, "
+ "found no active private keys, "
"unable to generate any signatures");
result = ISC_R_NOTFOUND;
}
@@ -2044,7 +2044,7 @@ add_exposed_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *ver, dns_name_t *name, isc_boolean_t cut,
dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys,
isc_stdtime_t inception, isc_stdtime_t expire,
- isc_boolean_t check_ksk)
+ isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly)
{
isc_result_t result;
dns_dbnode_t *node;
@@ -2090,7 +2090,8 @@ add_exposed_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
if (flag)
continue;;
result = add_sigs(client, zone, db, ver, name, type, diff,
- keys, nkeys, inception, expire, check_ksk);
+ keys, nkeys, inception, expire,
+ check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS)
goto cleanup_iterator;
}
@@ -2120,8 +2121,7 @@ add_exposed_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
static isc_result_t
update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *oldver, dns_dbversion_t *newver,
- dns_diff_t *diff, isc_uint32_t sigvalidityinterval,
- isc_boolean_t *deleted_zsk)
+ dns_diff_t *diff, isc_uint32_t sigvalidityinterval)
{
isc_result_t result;
dns_difftuple_t *t;
@@ -2130,7 +2130,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_diff_t sig_diff;
dns_diff_t nsec_diff;
dns_diff_t nsec_mindiff;
- isc_boolean_t flag;
+ isc_boolean_t flag, build_nsec, build_nsec3;
dst_key_t *zone_keys[MAXZONEKEYS];
unsigned int nkeys = 0;
unsigned int i;
@@ -2140,9 +2140,10 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_t rdataset;
dns_dbnode_t *node = NULL;
- isc_boolean_t check_ksk;
+ isc_boolean_t check_ksk, keyset_kskonly;
isc_boolean_t unsecure;
isc_boolean_t cut;
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
dns_diff_init(client->mctx, &diffnames);
dns_diff_init(client->mctx, &affected);
@@ -2172,27 +2173,8 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
*/
check_ksk = ISC_TF((dns_zone_getoptions(zone) &
DNS_ZONEOPT_UPDATECHECKKSK) != 0);
- /*
- * If we are not checking the ZSK flag then all DNSKEY's are
- * already signing all RRsets so we don't need to trigger special
- * changes.
- */
- if (*deleted_zsk && (!check_ksk || !ksk_sanity(db, oldver)))
- *deleted_zsk = ISC_FALSE;
-
- if (check_ksk) {
- check_ksk = ksk_sanity(db, newver);
- if (!check_ksk && ksk_sanity(db, oldver))
- update_log(client, zone, ISC_LOG_WARNING,
- "disabling update-check-ksk");
- }
-
- /*
- * If we have deleted a ZSK and we we still have some ZSK's
- * we don't need to convert the KSK's to a ZSK's.
- */
- if (*deleted_zsk && check_ksk)
- *deleted_zsk = ISC_FALSE;
+ keyset_kskonly = ISC_TF((dns_zone_getoptions(zone) &
+ DNS_ZONEOPT_DNSKEYKSKONLY) != 0);
/*
* Get the NSEC/NSEC3 TTL from the SOA MINIMUM field.
@@ -2259,7 +2241,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
CHECK(add_sigs(client, zone, db, newver, name,
type, &sig_diff, zone_keys,
nkeys, inception, expire,
- check_ksk));
+ check_ksk, keyset_kskonly));
}
skip:
/* Skip any other updates to the same RRset. */
@@ -2289,12 +2271,11 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
"removed any orphaned NSEC records");
/*
- * If we don't have a NSEC record at the origin then we need to
- * update the NSEC3 records.
+ * See if we need to build NSEC or NSEC3 chains.
*/
- CHECK(rrset_exists(db, newver, dns_db_origin(db), dns_rdatatype_nsec,
- 0, &flag));
- if (!flag)
+ CHECK(dns_private_chains(db, newver, privatetype, &build_nsec,
+ &build_nsec3));
+ if (!build_nsec)
goto update_nsec3;
update_log(client, zone, ISC_LOG_DEBUG(3), "rebuilding NSEC chain");
@@ -2398,16 +2379,25 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_rdatatype_any, 0, NULL, diff));
} else {
/*
- * This name is not obscured. It should have a NSEC.
+ * This name is not obscured. It needs to have a
+ * NSEC unless it is the at the origin, in which
+ * case it should already exist if there is a complete
+ * NSEC chain and if there isn't a complete NSEC chain
+ * we don't want to add one as that would signal that
+ * there is a complete NSEC chain.
*/
- CHECK(rrset_exists(db, newver, name,
- dns_rdatatype_nsec, 0, &flag));
- if (! flag)
- CHECK(add_placeholder_nsec(db, newver, name,
- diff));
+ if (!dns_name_equal(name, dns_db_origin(db))) {
+ CHECK(rrset_exists(db, newver, name,
+ dns_rdatatype_nsec, 0,
+ &flag));
+ if (!flag)
+ CHECK(add_placeholder_nsec(db, newver,
+ name, diff));
+ }
CHECK(add_exposed_sigs(client, zone, db, newver, name,
cut, diff, zone_keys, nkeys,
- inception, expire, check_ksk));
+ inception, expire, check_ksk,
+ keyset_kskonly));
}
}
@@ -2469,7 +2459,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
CHECK(add_sigs(client, zone, db, newver, &t->name,
dns_rdatatype_nsec, &sig_diff,
zone_keys, nkeys, inception, expire,
- check_ksk));
+ check_ksk, keyset_kskonly));
} else {
INSIST(0);
}
@@ -2491,13 +2481,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
INSIST(ISC_LIST_EMPTY(nsec_diff.tuples));
INSIST(ISC_LIST_EMPTY(nsec_mindiff.tuples));
- /*
- * Check if we have any active NSEC3 chains by looking for a
- * NSEC3PARAM RRset.
- */
- CHECK(rrset_exists(db, newver, dns_db_origin(db),
- dns_rdatatype_nsec3param, 0, &flag));
- if (!flag) {
+ if (!build_nsec3) {
update_log(client, zone, ISC_LOG_DEBUG(3),
"no NSEC3 chains to rebuild");
goto failure;
@@ -2521,6 +2505,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
isc_boolean_t ns_existed, dname_existed;
isc_boolean_t ns_exists, dname_exists;
+ isc_boolean_t exists, existed;
if (t->rdata.type == dns_rdatatype_nsec ||
t->rdata.type == dns_rdatatype_rrsig) {
@@ -2539,7 +2524,9 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
CHECK(rrset_exists(db, newver, name, dns_rdatatype_dname, 0,
&dname_exists));
- if ((ns_exists || dname_exists) == (ns_existed || dname_existed))
+ exists = ns_exists || dname_exists;
+ existed = ns_existed || dname_existed;
+ if (exists == existed)
goto nextname;
/*
* There was a delegation change. Mark all subdomains
@@ -2563,14 +2550,16 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
if (!flag) {
CHECK(delete_if(rrsig_p, db, newver, name,
dns_rdatatype_any, 0, NULL, diff));
- CHECK(dns_nsec3_delnsec3s(db, newver, name,
- &nsec_diff));
+ CHECK(dns_nsec3_delnsec3sx(db, newver, name,
+ privatetype, &nsec_diff));
} else {
CHECK(add_exposed_sigs(client, zone, db, newver, name,
cut, diff, zone_keys, nkeys,
- inception, expire, check_ksk));
- CHECK(dns_nsec3_addnsec3s(db, newver, name, nsecttl,
- unsecure, &nsec_diff));
+ inception, expire, check_ksk,
+ keyset_kskonly));
+ CHECK(dns_nsec3_addnsec3sx(db, newver, name, nsecttl,
+ unsecure, privatetype,
+ &nsec_diff));
}
}
@@ -2601,7 +2590,8 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
CHECK(add_sigs(client, zone, db, newver, &t->name,
dns_rdatatype_nsec3,
&sig_diff, zone_keys, nkeys,
- inception, expire, check_ksk));
+ inception, expire, check_ksk,
+ keyset_kskonly));
} else {
INSIST(0);
}
@@ -2734,6 +2724,7 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
switch(dns_zone_gettype(zone)) {
case dns_zone_master:
+ case dns_zone_dlz:
/*
* We can now fail due to a bad signature as we now know
* that we are the master.
@@ -2943,7 +2934,7 @@ rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
result = dns_rdataset_next(&rdataset)) {
dns_rdata_t myrdata = DNS_RDATA_INIT;
dns_rdataset_current(&rdataset, &myrdata);
- if (!dns_rdata_compare(&myrdata, rdata))
+ if (!dns_rdata_casecompare(&myrdata, rdata))
break;
}
dns_rdataset_disassociate(&rdataset);
@@ -2961,7 +2952,9 @@ rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
}
static isc_result_t
-get_iterations(dns_db_t *db, dns_dbversion_t *ver, unsigned int *iterationsp) {
+get_iterations(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype,
+ unsigned int *iterationsp)
+{
dns_dbnode_t *node = NULL;
dns_rdata_nsec3param_t nsec3param;
dns_rdataset_t rdataset;
@@ -2975,7 +2968,33 @@ get_iterations(dns_db_t *db, dns_dbversion_t *ver, unsigned int *iterationsp) {
return (result);
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
0, (isc_stdtime_t) 0, &rdataset, NULL);
- dns_db_detachnode(db, &node);
+ if (result == ISC_R_NOTFOUND)
+ goto try_private;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_current(&rdataset, &rdata);
+ CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
+ if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
+ continue;
+ if (nsec3param.iterations > iterations)
+ iterations = nsec3param.iterations;
+ }
+ if (result != ISC_R_NOMORE)
+ goto failure;
+
+ dns_rdataset_disassociate(&rdataset);
+
+ try_private:
+ if (privatetype == 0)
+ goto success;
+
+ result = dns_db_findrdataset(db, node, ver, privatetype,
+ 0, (isc_stdtime_t) 0, &rdataset, NULL);
if (result == ISC_R_NOTFOUND)
goto success;
if (result != ISC_R_SUCCESS)
@@ -2984,8 +3003,14 @@ get_iterations(dns_db_t *db, dns_dbversion_t *ver, unsigned int *iterationsp) {
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ dns_rdata_t private = DNS_RDATA_INIT;
dns_rdata_t rdata = DNS_RDATA_INIT;
+
dns_rdataset_current(&rdataset, &rdata);
+ if (!dns_nsec3param_fromprivate(&private, &rdata,
+ buf, sizeof(buf)))
+ continue;
CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
continue;
@@ -3000,6 +3025,8 @@ get_iterations(dns_db_t *db, dns_dbversion_t *ver, unsigned int *iterationsp) {
result = ISC_R_SUCCESS;
failure:
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset);
return (result);
@@ -3013,77 +3040,83 @@ static isc_result_t
check_dnssec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *ver, dns_diff_t *diff)
{
- dns_diff_t temp_diff;
- dns_diffop_t op;
- dns_difftuple_t *tuple, *newtuple = NULL, *next;
- isc_boolean_t flag;
+ dns_difftuple_t *tuple;
+ isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
isc_result_t result;
unsigned int iterations = 0, max;
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
- dns_diff_init(diff->mctx, &temp_diff);
-
- CHECK(dns_nsec_nseconly(db, ver, &flag));
+ /* Scan the tuples for an NSEC-only DNSKEY or an NSEC3PARAM */
+ for (tuple = ISC_LIST_HEAD(diff->tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_NEXT(tuple, link)) {
+ if (tuple->op != DNS_DIFFOP_ADD)
+ continue;
- if (flag)
- CHECK(dns_nsec3_active(db, ver, ISC_FALSE, &flag));
- if (flag) {
- update_log(client, zone, ISC_LOG_WARNING,
- "NSEC only DNSKEYs and NSEC3 chains not allowed");
- } else {
- CHECK(get_iterations(db, ver, &iterations));
- CHECK(dns_nsec3_maxiterations(db, ver, client->mctx, &max));
- if (max != 0 && iterations > max) {
- flag = ISC_TRUE;
- update_log(client, zone, ISC_LOG_WARNING,
- "too many NSEC3 iterations (%u) for "
- "weakest DNSKEY (%u)", iterations, max);
+ if (tuple->rdata.type == dns_rdatatype_dnskey) {
+ isc_uint8_t alg;
+ alg = tuple->rdata.data[3];
+ if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
+ alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
+ nseconly = ISC_TRUE;
+ break;
+ }
+ } else if (tuple->rdata.type == dns_rdatatype_nsec3param) {
+ nsec3 = ISC_TRUE;
+ break;
}
}
- if (flag) {
- for (tuple = ISC_LIST_HEAD(diff->tuples);
- tuple != NULL;
- tuple = next) {
- next = ISC_LIST_NEXT(tuple, link);
- if (tuple->rdata.type != dns_rdatatype_dnskey &&
- tuple->rdata.type != dns_rdatatype_nsec3param)
- continue;
- op = (tuple->op == DNS_DIFFOP_DEL) ?
- DNS_DIFFOP_ADD : DNS_DIFFOP_DEL;
- CHECK(dns_difftuple_create(temp_diff.mctx, op,
- &tuple->name, tuple->ttl,
- &tuple->rdata, &newtuple));
- CHECK(do_one_tuple(&newtuple, db, ver, &temp_diff));
- INSIST(newtuple == NULL);
- }
- for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
- tuple != NULL;
- tuple = ISC_LIST_HEAD(temp_diff.tuples)) {
- ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
- dns_diff_appendminimal(diff, &tuple);
- }
+
+ /* Check existing DB for NSEC-only DNSKEY */
+ if (!nseconly)
+ CHECK(dns_nsec_nseconly(db, ver, &nseconly));
+
+ /* Check existing DB for NSEC3 */
+ if (!nsec3)
+ CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
+ privatetype, &nsec3));
+
+ /* Refuse to allow NSEC3 with NSEC-only keys */
+ if (nseconly && nsec3) {
+ update_log(client, zone, ISC_LOG_ERROR,
+ "NSEC only DNSKEYs and NSEC3 chains not allowed");
+ result = DNS_R_REFUSED;
+ goto failure;
}
+ /* Verify NSEC3 params */
+ CHECK(get_iterations(db, ver, privatetype, &iterations));
+ CHECK(dns_nsec3_maxiterations(db, ver, client->mctx, &max));
+ if (max != 0 && iterations > max) {
+ update_log(client, zone, ISC_LOG_ERROR,
+ "too many NSEC3 iterations (%u) for "
+ "weakest DNSKEY (%u)", iterations, max);
+ result = DNS_R_REFUSED;
+ goto failure;
+ }
failure:
- dns_diff_clear(&temp_diff);
return (result);
}
-#ifdef ALLOW_NSEC3PARAM_UPDATE
/*
* Delay NSEC3PARAM changes as they need to be applied to the whole zone.
*/
static isc_result_t
add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
- dns_name_t *name, dns_dbversion_t *ver, dns_diff_t *diff)
+ dns_dbversion_t *ver, dns_diff_t *diff)
{
isc_result_t result = ISC_R_SUCCESS;
dns_difftuple_t *tuple, *newtuple = NULL, *next;
dns_rdata_t rdata = DNS_RDATA_INIT;
- unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
dns_diff_t temp_diff;
dns_diffop_t op;
isc_boolean_t flag;
+ dns_name_t *name = dns_zone_getorigin(zone);
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
+ isc_uint32_t ttl = 0;
+ isc_boolean_t ttl_good = ISC_FALSE;
update_log(client, zone, ISC_LOG_DEBUG(3),
"checking for NSEC3PARAM changes");
@@ -3106,55 +3139,143 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
ISC_LIST_APPEND(temp_diff.tuples, tuple, link);
}
+ /*
+ * Extract TTL changes pairs, we don't need to convert these to
+ * delayed changes.
+ */
for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
tuple != NULL; tuple = next) {
-
if (tuple->op == DNS_DIFFOP_ADD) {
+ if (!ttl_good) {
+ /*
+ * Any adds here will contain the final
+ * NSEC3PARAM RRset TTL.
+ */
+ ttl = tuple->ttl;
+ ttl_good = ISC_TRUE;
+ }
+ /*
+ * Walk the temp_diff list looking for the
+ * corresponding delete.
+ */
+ next = ISC_LIST_HEAD(temp_diff.tuples);
+ while (next != NULL) {
+ unsigned char *next_data = next->rdata.data;
+ unsigned char *tuple_data = tuple->rdata.data;
+ if (next->op == DNS_DIFFOP_DEL &&
+ next->rdata.length == tuple->rdata.length &&
+ !memcmp(next_data, tuple_data,
+ next->rdata.length)) {
+ ISC_LIST_UNLINK(temp_diff.tuples, next,
+ link);
+ ISC_LIST_APPEND(diff->tuples, next,
+ link);
+ break;
+ }
+ next = ISC_LIST_NEXT(next, link);
+ }
+ /*
+ * If we have not found a pair move onto the next
+ * tuple.
+ */
+ if (next == NULL) {
+ next = ISC_LIST_NEXT(tuple, link);
+ continue;
+ }
+ /*
+ * Find the next tuple to be processed before
+ * unlinking then complete moving the pair to 'diff'.
+ */
+ next = ISC_LIST_NEXT(tuple, link);
+ ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
+ ISC_LIST_APPEND(diff->tuples, tuple, link);
+ } else
next = ISC_LIST_NEXT(tuple, link);
+ }
+
+ /*
+ * Preserve any ongoing changes from a BIND 9.6.x upgrade.
+ *
+ * Any NSEC3PARAM records with flags other than OPTOUT named
+ * in managing and should not be touched so revert such changes
+ * taking into account any TTL change of the NSEC3PARAM RRset.
+ */
+ for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
+ tuple != NULL; tuple = next) {
+ next = ISC_LIST_NEXT(tuple, link);
+ if ((tuple->rdata.data[1] & ~DNS_NSEC3FLAG_OPTOUT) != 0) {
+ /*
+ * If we havn't had any adds then the tuple->ttl must
+ * be the original ttl and should be used for any
+ * future changes.
+ */
+ if (!ttl_good) {
+ ttl = tuple->ttl;
+ ttl_good = ISC_TRUE;
+ }
+ op = (tuple->op == DNS_DIFFOP_DEL) ?
+ DNS_DIFFOP_ADD : DNS_DIFFOP_DEL;
+ CHECK(dns_difftuple_create(diff->mctx, op, name,
+ ttl, &tuple->rdata,
+ &newtuple));
+ CHECK(do_one_tuple(&newtuple, db, ver, diff));
+ ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
+ dns_diff_appendminimal(diff, &tuple);
+ }
+ }
+
+ /*
+ * We now have just the actual changes to the NSEC3PARAM RRset.
+ * Convert the adds to delayed adds and the deletions into delayed
+ * deletions.
+ */
+ for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
+ tuple != NULL; tuple = next) {
+ /*
+ * If we havn't had any adds then the tuple->ttl must be the
+ * original ttl and should be used for any future changes.
+ */
+ if (!ttl_good) {
+ ttl = tuple->ttl;
+ ttl_good = ISC_TRUE;
+ }
+ if (tuple->op == DNS_DIFFOP_ADD) {
+ /*
+ * Look for any deletes which match this ADD ignoring
+ * OPTOUT. We don't need to explictly remove them as
+ * they will be removed a side effect of processing
+ * the add.
+ */
+ next = ISC_LIST_HEAD(temp_diff.tuples);
while (next != NULL) {
unsigned char *next_data = next->rdata.data;
unsigned char *tuple_data = tuple->rdata.data;
- if (next_data[0] != tuple_data[0] ||
- /* Ignore flags. */
+ if (next->op != DNS_DIFFOP_DEL ||
+ next->rdata.length != tuple->rdata.length ||
+ next_data[0] != tuple_data[0] ||
next_data[2] != tuple_data[2] ||
next_data[3] != tuple_data[3] ||
- next_data[4] != tuple_data[4] ||
- !memcmp(&next_data[5], &tuple_data[5],
- tuple_data[4])) {
+ memcmp(next_data + 4, tuple_data + 4,
+ tuple->rdata.length - 4)) {
next = ISC_LIST_NEXT(next, link);
continue;
}
- op = (next->op == DNS_DIFFOP_DEL) ?
- DNS_DIFFOP_ADD : DNS_DIFFOP_DEL;
- CHECK(dns_difftuple_create(diff->mctx, op,
- name, next->ttl,
- &next->rdata,
- &newtuple));
- CHECK(do_one_tuple(&newtuple, db, ver, diff));
ISC_LIST_UNLINK(temp_diff.tuples, next, link);
- dns_diff_appendminimal(diff, &next);
- next = ISC_LIST_NEXT(tuple, link);
+ ISC_LIST_APPEND(diff->tuples, next, link);
+ next = ISC_LIST_HEAD(temp_diff.tuples);
}
-
- INSIST(tuple->rdata.data[1] & DNS_NSEC3FLAG_UPDATE);
-
/*
* See if we already have a CREATE request in progress.
*/
- dns_rdata_clone(&tuple->rdata, &rdata);
- INSIST(rdata.length <= sizeof(buf));
- memcpy(buf, rdata.data, rdata.length);
- buf[1] |= DNS_NSEC3FLAG_CREATE;
- buf[1] &= ~DNS_NSEC3FLAG_UPDATE;
- rdata.data = buf;
-
+ dns_nsec3param_toprivate(&tuple->rdata, &rdata,
+ privatetype, buf, sizeof(buf));
+ buf[2] |= DNS_NSEC3FLAG_CREATE;
CHECK(rr_exists(db, ver, name, &rdata, &flag));
if (!flag) {
CHECK(dns_difftuple_create(diff->mctx,
DNS_DIFFOP_ADD,
- name, tuple->ttl,
- &rdata,
+ name, 0, &rdata,
&newtuple));
CHECK(do_one_tuple(&newtuple, db, ver, diff));
}
@@ -3164,26 +3285,26 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
* otherwise indentical chain with a reversed
* OPTOUT state.
*/
- buf[1] ^= DNS_NSEC3FLAG_OPTOUT;
+ buf[2] ^= DNS_NSEC3FLAG_OPTOUT;
CHECK(rr_exists(db, ver, name, &rdata, &flag));
if (flag) {
CHECK(dns_difftuple_create(diff->mctx,
DNS_DIFFOP_DEL,
- name, tuple->ttl,
- &rdata,
+ name, 0, &rdata,
&newtuple));
CHECK(do_one_tuple(&newtuple, db, ver, diff));
}
/*
- * Remove the temporary add record.
+ * Find the next tuple to be processed and remove the
+ * temporary add record.
*/
+ next = ISC_LIST_NEXT(tuple, link);
CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
- name, tuple->ttl,
- &tuple->rdata, &newtuple));
+ name, ttl, &tuple->rdata,
+ &newtuple));
CHECK(do_one_tuple(&newtuple, db, ver, diff));
- next = ISC_LIST_NEXT(tuple, link);
ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
dns_diff_appendminimal(diff, &tuple);
dns_rdata_reset(&rdata);
@@ -3191,50 +3312,33 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
next = ISC_LIST_NEXT(tuple, link);
}
- /*
- * Reverse any pending changes.
- */
for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
tuple != NULL; tuple = next) {
- next = ISC_LIST_NEXT(tuple, link);
- if ((tuple->rdata.data[1] & ~DNS_NSEC3FLAG_OPTOUT) != 0) {
- op = (tuple->op == DNS_DIFFOP_DEL) ?
- DNS_DIFFOP_ADD : DNS_DIFFOP_DEL;
- CHECK(dns_difftuple_create(diff->mctx, op, name,
- tuple->ttl, &tuple->rdata,
- &newtuple));
- CHECK(do_one_tuple(&newtuple, db, ver, diff));
- ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
- dns_diff_appendminimal(diff, &tuple);
- }
- }
- /*
- * Convert deletions into delayed deletions.
- */
- for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
- tuple != NULL; tuple = next) {
+ INSIST(ttl_good);
+
next = ISC_LIST_NEXT(tuple, link);
/*
* See if we already have a REMOVE request in progress.
*/
- dns_rdata_clone(&tuple->rdata, &rdata);
- INSIST(rdata.length <= sizeof(buf));
- memcpy(buf, rdata.data, rdata.length);
- buf[1] |= DNS_NSEC3FLAG_REMOVE;
- rdata.data = buf;
+ dns_nsec3param_toprivate(&tuple->rdata, &rdata, privatetype,
+ buf, sizeof(buf));
+
+ buf[2] |= DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
CHECK(rr_exists(db, ver, name, &rdata, &flag));
+ if (!flag) {
+ buf[2] &= ~DNS_NSEC3FLAG_NONSEC;
+ CHECK(rr_exists(db, ver, name, &rdata, &flag));
+ }
if (!flag) {
CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
- name, tuple->ttl, &rdata,
- &newtuple));
+ name, 0, &rdata, &newtuple));
CHECK(do_one_tuple(&newtuple, db, ver, diff));
}
CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name,
- tuple->ttl, &tuple->rdata,
- &newtuple));
+ ttl, &tuple->rdata, &newtuple));
CHECK(do_one_tuple(&newtuple, db, ver, diff));
ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
dns_diff_appendminimal(diff, &tuple);
@@ -3246,17 +3350,75 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_diff_clear(&temp_diff);
return (result);
}
-#endif
+
+static isc_result_t
+rollback_private(dns_db_t *db, dns_rdatatype_t privatetype,
+ dns_dbversion_t *ver, dns_diff_t *diff)
+{
+ dns_diff_t temp_diff;
+ dns_diffop_t op;
+ dns_difftuple_t *tuple, *newtuple = NULL, *next;
+ dns_name_t *name = dns_db_origin(db);
+ isc_mem_t *mctx = diff->mctx;
+ isc_result_t result;
+
+ if (privatetype == 0)
+ return (ISC_R_SUCCESS);
+
+ dns_diff_init(mctx, &temp_diff);
+
+ /*
+ * Extract the changes to be rolled back.
+ */
+ for (tuple = ISC_LIST_HEAD(diff->tuples);
+ tuple != NULL; tuple = next) {
+
+ next = ISC_LIST_NEXT(tuple, link);
+
+ if (tuple->rdata.type != privatetype ||
+ !dns_name_equal(name, &tuple->name))
+ continue;
+
+ /*
+ * Allow records which indicate that a zone has been
+ * signed with a DNSKEY to be be removed.
+ */
+ if (tuple->op == DNS_DIFFOP_DEL &&
+ tuple->rdata.length == 5 &&
+ tuple->rdata.data[0] != 0 &&
+ tuple->rdata.data[4] != 0)
+ continue;
+
+ ISC_LIST_UNLINK(diff->tuples, tuple, link);
+ ISC_LIST_PREPEND(temp_diff.tuples, tuple, link);
+ }
+
+ /*
+ * Rollback the changes.
+ */
+ while ((tuple = ISC_LIST_HEAD(temp_diff.tuples)) != NULL) {
+ op = (tuple->op == DNS_DIFFOP_DEL) ?
+ DNS_DIFFOP_ADD : DNS_DIFFOP_DEL;
+ CHECK(dns_difftuple_create(mctx, op, name, tuple->ttl,
+ &tuple->rdata, &newtuple));
+ CHECK(do_one_tuple(&newtuple, db, ver, &temp_diff));
+ }
+ result = ISC_R_SUCCESS;
+
+ failure:
+ dns_diff_clear(&temp_diff);
+ return (result);
+}
/*
* Add records to cause the delayed signing of the zone by added DNSKEY
* to remove the RRSIG records generated by a deleted DNSKEY.
*/
static isc_result_t
-add_signing_records(dns_db_t *db, dns_name_t *name, dns_dbversion_t *ver,
- dns_rdatatype_t privatetype, dns_diff_t *diff)
+add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
+ dns_dbversion_t *ver, dns_diff_t *diff)
{
- dns_difftuple_t *tuple, *newtuple = NULL;
+ dns_difftuple_t *tuple, *newtuple = NULL, *next;
dns_rdata_dnskey_t dnskey;
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_boolean_t flag;
@@ -3264,13 +3426,82 @@ add_signing_records(dns_db_t *db, dns_name_t *name, dns_dbversion_t *ver,
isc_result_t result = ISC_R_SUCCESS;
isc_uint16_t keyid;
unsigned char buf[5];
+ dns_name_t *name = dns_db_origin(db);
+ dns_diff_t temp_diff;
+
+ dns_diff_init(diff->mctx, &temp_diff);
+ /*
+ * Extract the DNSKEY tuples from the list.
+ */
for (tuple = ISC_LIST_HEAD(diff->tuples);
- tuple != NULL;
- tuple = ISC_LIST_NEXT(tuple, link)) {
+ tuple != NULL; tuple = next) {
+
+ next = ISC_LIST_NEXT(tuple, link);
+
if (tuple->rdata.type != dns_rdatatype_dnskey)
continue;
+ ISC_LIST_UNLINK(diff->tuples, tuple, link);
+ ISC_LIST_APPEND(temp_diff.tuples, tuple, link);
+ }
+
+ /*
+ * Extract TTL changes pairs, we don't need signing records for these.
+ */
+ for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
+ tuple != NULL; tuple = next) {
+ if (tuple->op == DNS_DIFFOP_ADD) {
+ /*
+ * Walk the temp_diff list looking for the
+ * corresponding delete.
+ */
+ next = ISC_LIST_HEAD(temp_diff.tuples);
+ while (next != NULL) {
+ unsigned char *next_data = next->rdata.data;
+ unsigned char *tuple_data = tuple->rdata.data;
+ if (next->op == DNS_DIFFOP_DEL &&
+ dns_name_equal(&tuple->name, &next->name) &&
+ next->rdata.length == tuple->rdata.length &&
+ !memcmp(next_data, tuple_data,
+ next->rdata.length)) {
+ ISC_LIST_UNLINK(temp_diff.tuples, next,
+ link);
+ ISC_LIST_APPEND(diff->tuples, next,
+ link);
+ break;
+ }
+ next = ISC_LIST_NEXT(next, link);
+ }
+ /*
+ * If we have not found a pair move onto the next
+ * tuple.
+ */
+ if (next == NULL) {
+ next = ISC_LIST_NEXT(tuple, link);
+ continue;
+ }
+ /*
+ * Find the next tuple to be processed before
+ * unlinking then complete moving the pair to 'diff'.
+ */
+ next = ISC_LIST_NEXT(tuple, link);
+ ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
+ ISC_LIST_APPEND(diff->tuples, tuple, link);
+ } else
+ next = ISC_LIST_NEXT(tuple, link);
+ }
+
+ /*
+ * Process the remaining DNSKEY entries.
+ */
+ for (tuple = ISC_LIST_HEAD(temp_diff.tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_HEAD(temp_diff.tuples)) {
+
+ ISC_LIST_UNLINK(temp_diff.tuples, tuple, link);
+ ISC_LIST_APPEND(diff->tuples, tuple, link);
+
dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
if ((dnskey.flags &
(DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
@@ -3278,6 +3509,7 @@ add_signing_records(dns_db_t *db, dns_name_t *name, dns_dbversion_t *ver,
continue;
dns_rdata_toregion(&tuple->rdata, &r);
+
keyid = dst_region_computeid(&r, dnskey.algorithm);
buf[0] = dnskey.algorithm;
@@ -3310,87 +3542,25 @@ add_signing_records(dns_db_t *db, dns_name_t *name, dns_dbversion_t *ver,
INSIST(newtuple == NULL);
}
}
+
failure:
+ dns_diff_clear(&temp_diff);
return (result);
}
-#ifdef ALLOW_NSEC3PARAM_UPDATE
-/*
- * Mark all NSEC3 chains for deletion without creating a NSEC chain as
- * a side effect of deleting the last chain.
- */
-static isc_result_t
-delete_chains(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
- dns_diff_t *diff)
-{
- dns_dbnode_t *node = NULL;
- dns_difftuple_t *tuple = NULL;
- dns_name_t next;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t rdataset;
- isc_boolean_t flag;
- isc_result_t result = ISC_R_SUCCESS;
- unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
-
- dns_name_init(&next, NULL);
- dns_rdataset_init(&rdataset);
-
- result = dns_db_getoriginnode(db, &node);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * Cause all NSEC3 chains to be deleted.
- */
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
- 0, (isc_stdtime_t) 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND)
- goto success;
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- for (result = dns_rdataset_first(&rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&rdataset)) {
- dns_rdataset_current(&rdataset, &rdata);
- INSIST(rdata.length <= sizeof(buf));
- memcpy(buf, rdata.data, rdata.length);
-
- if (buf[1] == (DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC)) {
- dns_rdata_reset(&rdata);
- continue;
- }
-
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
- origin, 0, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, ver, diff));
- INSIST(tuple == NULL);
-
- buf[1] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
- rdata.data = buf;
-
- CHECK(rr_exists(db, ver, origin, &rdata, &flag));
+static isc_boolean_t
+isdnssec(dns_db_t *db, dns_dbversion_t *ver, dns_rdatatype_t privatetype) {
+ isc_result_t result;
+ isc_boolean_t build_nsec, build_nsec3;
- if (!flag) {
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
- origin, 0, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, ver, diff));
- INSIST(tuple == NULL);
- }
- dns_rdata_reset(&rdata);
- }
- if (result != ISC_R_NOMORE)
- goto failure;
- success:
- result = ISC_R_SUCCESS;
+ if (dns_db_issecure(db))
+ return (ISC_TRUE);
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- dns_db_detachnode(db, &node);
- return (result);
+ result = dns_private_chains(db, ver, privatetype,
+ &build_nsec, &build_nsec3);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ return (build_nsec || build_nsec3);
}
-#endif
static void
update_action(isc_task_t *task, isc_event_t *event) {
@@ -3414,15 +3584,10 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_fixedname_t tmpnamefixed;
dns_name_t *tmpname = NULL;
unsigned int options;
- isc_boolean_t deleted_zsk;
dns_difftuple_t *tuple;
dns_rdata_dnskey_t dnskey;
-#ifdef ALLOW_NSEC3PARAM_UPDATE
- unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
-#endif
-#if !defined(ALLOW_SECURE_TO_INSECURE) || !defined(ALLOW_INSECURE_TO_SECURE)
isc_boolean_t had_dnskey;
-#endif
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
INSIST(event->ev_type == DNS_EVENT_UPDATE);
@@ -3433,6 +3598,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
zonename = dns_db_origin(db);
zoneclass = dns_db_class(db);
dns_zone_getssutable(zone, &ssutable);
+
+ /*
+ * Update message processing can leak record existance information
+ * so check that we are allowed to query this zone. Additionally
+ * if we would refuse all updates for this zone we bail out here.
+ */
+ CHECK(checkqueryacl(client, dns_zone_getqueryacl(zone), zonename,
+ dns_zone_getupdateacl(zone), ssutable));
+
+ /*
+ * Get old and new versions now that queryacl has been checked.
+ */
dns_db_currentversion(db, &oldver);
CHECK(dns_db_newversion(db, &ver));
@@ -3525,7 +3702,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
if (result != ISC_R_NOMORE)
FAIL(result);
-
/*
* Perform the final check of the "rrset exists (value dependent)"
* prerequisites.
@@ -3619,31 +3795,31 @@ update_action(isc_task_t *task, isc_event_t *event) {
update_class);
FAIL(DNS_R_FORMERR);
}
+
/*
* draft-ietf-dnsind-simple-secure-update-01 says
* "Unlike traditional dynamic update, the client
* is forbidden from updating NSEC records."
*/
- if (dns_db_issecure(db)) {
- if (rdata.type == dns_rdatatype_nsec3) {
- FAILC(DNS_R_REFUSED,
- "explicit NSEC3 updates are not allowed "
- "in secure zones");
- } else if (rdata.type == dns_rdatatype_nsec) {
- FAILC(DNS_R_REFUSED,
- "explicit NSEC updates are not allowed "
- "in secure zones");
- } else if (rdata.type == dns_rdatatype_rrsig &&
- !dns_name_equal(name, zonename)) {
- FAILC(DNS_R_REFUSED,
- "explicit RRSIG updates are currently "
- "not supported in secure zones except "
- "at the apex");
- }
+ if (rdata.type == dns_rdatatype_nsec3) {
+ FAILC(DNS_R_REFUSED,
+ "explicit NSEC3 updates are not allowed "
+ "in secure zones");
+ } else if (rdata.type == dns_rdatatype_nsec) {
+ FAILC(DNS_R_REFUSED,
+ "explicit NSEC updates are not allowed "
+ "in secure zones");
+ } else if (rdata.type == dns_rdatatype_rrsig &&
+ !dns_name_equal(name, zonename)) {
+ FAILC(DNS_R_REFUSED,
+ "explicit RRSIG updates are currently "
+ "not supported in secure zones except "
+ "at the apex");
}
if (ssutable != NULL) {
isc_netaddr_t *tcpaddr, netaddr;
+ dst_key_t *tsigkey = NULL;
/*
* If this is a TCP connection then pass the
* address of the client through for tcp-self
@@ -3656,16 +3832,22 @@ update_action(isc_task_t *task, isc_event_t *event) {
tcpaddr = &netaddr;
} else
tcpaddr = NULL;
+
+ if (client->message->tsigkey != NULL)
+ tsigkey = client->message->tsigkey->key;
+
if (rdata.type != dns_rdatatype_any) {
if (!dns_ssutable_checkrules(ssutable,
client->signer,
name, tcpaddr,
- rdata.type))
+ rdata.type,
+ tsigkey))
FAILC(DNS_R_REFUSED,
"rejected by secure update");
} else {
if (!ssu_checkall(db, ver, name, ssutable,
- client->signer, tcpaddr))
+ client->signer, tcpaddr,
+ tsigkey))
FAILC(DNS_R_REFUSED,
"rejected by secure update");
}
@@ -3774,7 +3956,14 @@ update_action(isc_task_t *task, isc_event_t *event) {
soa_serial_changed = ISC_TRUE;
}
-#ifdef ALLOW_NSEC3PARAM_UPDATE
+ if (rdata.type == privatetype) {
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "attempt to add a private type "
+ "(%u) record rejected internal "
+ "use only", privatetype);
+ continue;
+ }
+
if (rdata.type == dns_rdatatype_nsec3param) {
/*
* Ignore attempts to add NSEC3PARAM records
@@ -3788,27 +3977,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
"flag");
continue;
}
-
- /*
- * Set the NSEC3CHAIN creation flag.
- */
- INSIST(rdata.length <= sizeof(buf));
- memcpy(buf, rdata.data, rdata.length);
- buf[1] |= DNS_NSEC3FLAG_UPDATE;
- rdata.data = buf;
- /*
- * Force the TTL to zero for NSEC3PARAM records.
- */
- ttl = 0;
}
-#else
- if (rdata.type == dns_rdatatype_nsec3param) {
- update_log(client, zone, LOGLEVEL_PROTOCOL,
- "attempt to add NSEC3PARAM "
- "record ignored");
- continue;
- };
-#endif
if ((options & DNS_ZONEOPT_CHECKWILDCARD) != 0 &&
dns_name_internalwildcard(name)) {
@@ -3885,13 +4054,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_rdatatype_any, 0,
&rdata, &diff));
}
-#ifndef ALLOW_NSEC3PARAM_UPDATE
- } else if (rdata.type == dns_rdatatype_nsec3param) {
- update_log(client, zone, LOGLEVEL_PROTOCOL,
- "attempt to delete a NSEC3PARAM "
- "records ignored");
- continue;
-#endif
} else if (dns_name_equal(name, zonename) &&
(rdata.type == dns_rdatatype_soa ||
rdata.type == dns_rdatatype_ns)) {
@@ -3920,6 +4082,9 @@ update_action(isc_task_t *task, isc_event_t *event) {
&diff));
}
} else if (update_class == dns_rdataclass_none) {
+ char namestr[DNS_NAME_FORMATSIZE];
+ char typestr[DNS_RDATATYPE_FORMATSIZE];
+
/*
* The (name == zonename) condition appears in
* RFC2136 3.4.2.4 but is missing from the pseudocode.
@@ -3947,11 +4112,13 @@ update_action(isc_task_t *task, isc_event_t *event) {
}
}
}
- update_log(client, zone,
- LOGLEVEL_PROTOCOL,
- "deleting an RR");
- CHECK(delete_if(rr_equal_p, db, ver, name,
- rdata.type, covers, &rdata, &diff));
+ dns_name_format(name, namestr, sizeof(namestr));
+ dns_rdatatype_format(rdata.type, typestr,
+ sizeof(typestr));
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "deleting an RR at %s %s", namestr, typestr);
+ CHECK(delete_if(rr_equal_p, db, ver, name, rdata.type,
+ covers, &rdata, &diff));
}
}
if (result != ISC_R_NOMORE)
@@ -3965,6 +4132,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
if (! ISC_LIST_EMPTY(diff.tuples))
CHECK(check_dnssec(client, zone, db, ver, &diff));
+ if (! ISC_LIST_EMPTY(diff.tuples)) {
+ unsigned int errors = 0;
+ CHECK(dns_zone_nscheck(zone, db, ver, &errors));
+ if (errors != 0) {
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "update rejected: post update name server "
+ "sanity check failed");
+ result = DNS_R_REFUSED;
+ goto failure;
+ }
+ }
+
/*
* If any changes were made, increment the SOA serial number,
* update RRSIGs and NSECs (if zone is secure), and write the update
@@ -3990,37 +4169,29 @@ update_action(isc_task_t *task, isc_event_t *event) {
CHECK(rrset_exists(db, ver, zonename, dns_rdatatype_dnskey,
0, &has_dnskey));
-#if !defined(ALLOW_SECURE_TO_INSECURE) || !defined(ALLOW_INSECURE_TO_SECURE)
- CHECK(rrset_exists(db, oldver, zonename, dns_rdatatype_dnskey,
- 0, &had_dnskey));
+#define ALLOW_SECURE_TO_INSECURE(zone) \
+ ((dns_zone_getoptions(zone) & DNS_ZONEOPT_SECURETOINSECURE) != 0)
-#ifndef ALLOW_SECURE_TO_INSECURE
- if (had_dnskey && !has_dnskey) {
- update_log(client, zone, LOGLEVEL_PROTOCOL,
- "update rejected: all DNSKEY records "
- "removed");
- result = DNS_R_REFUSED;
- goto failure;
- }
-#endif
-#ifndef ALLOW_INSECURE_TO_SECURE
- if (!had_dnskey && has_dnskey) {
- update_log(client, zone, LOGLEVEL_PROTOCOL,
- "update rejected: DNSKEY record added");
- result = DNS_R_REFUSED;
- goto failure;
+ if (!ALLOW_SECURE_TO_INSECURE(zone)) {
+ CHECK(rrset_exists(db, oldver, zonename,
+ dns_rdatatype_dnskey, 0,
+ &had_dnskey));
+ if (had_dnskey && !has_dnskey) {
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "update rejected: all DNSKEY "
+ "records removed and "
+ "'dnssec-secure-to-insecure' "
+ "not set");
+ result = DNS_R_REFUSED;
+ goto failure;
+ }
}
-#endif
-#endif
- CHECK(add_signing_records(db, zonename, ver,
- dns_zone_getprivatetype(zone),
- &diff));
+ CHECK(rollback_private(db, privatetype, ver, &diff));
+
+ CHECK(add_signing_records(db, privatetype, ver, &diff));
-#ifdef ALLOW_NSEC3PARAM_UPDATE
- CHECK(add_nsec3param_records(client, zone, db, zonename,
- ver, &diff));
-#endif
+ CHECK(add_nsec3param_records(client, zone, db, ver, &diff));
if (!has_dnskey) {
/*
@@ -4029,15 +4200,13 @@ update_action(isc_task_t *task, isc_event_t *event) {
* the last signature for the DNSKEY records are
* remove any NSEC chain present will also be removed.
*/
-#ifdef ALLOW_NSEC3PARAM_UPDATE
- CHECK(delete_chains(db, ver, zonename, &diff));
-#endif
- } else if (has_dnskey && dns_db_isdnssec(db)) {
+ CHECK(dns_nsec3param_deletechains(db, ver, zone,
+ &diff));
+ } else if (has_dnskey && isdnssec(db, ver, privatetype)) {
isc_uint32_t interval;
interval = dns_zone_getsigvalidityinterval(zone);
result = update_signatures(client, zone, db, oldver,
- ver, &diff, interval,
- &deleted_zsk);
+ ver, &diff, interval);
if (result != ISC_R_SUCCESS) {
update_log(client, zone,
ISC_LOG_ERROR,
@@ -4123,7 +4292,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
}
}
-#ifdef ALLOW_NSEC3PARAM_UPDATE
/*
* Cause the zone to add/delete NSEC3 chains for the
* deferred NSEC3PARAM changes.
@@ -4133,13 +4301,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
for (tuple = ISC_LIST_HEAD(diff.tuples);
tuple != NULL;
tuple = ISC_LIST_NEXT(tuple, link)) {
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_nsec3param_t nsec3param;
- if (tuple->rdata.type != dns_rdatatype_nsec3param ||
+ if (tuple->rdata.type != privatetype ||
tuple->op != DNS_DIFFOP_ADD)
continue;
- dns_rdata_tostruct(&tuple->rdata, &nsec3param, NULL);
+ if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
+ buf, sizeof(buf)))
+ continue;
+ dns_rdata_tostruct(&rdata, &nsec3param, NULL);
if (nsec3param.flags == 0)
continue;
@@ -4150,7 +4323,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_result_totext(result));
}
}
-#endif
} else {
update_log(client, zone, LOGLEVEL_DEBUG, "redundant request");
dns_db_closeversion(db, &ver, ISC_TRUE);
diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c
index e61dc72efda2..b036ed14d57f 100644
--- a/bin/named/xfrout.c
+++ b/bin/named/xfrout.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: xfrout.c,v 1.131.26.6 2010-05-27 23:48:18 tbox Exp $ */
+/* $Id: xfrout.c,v 1.139 2010-12-18 01:56:19 each Exp $ */
#include <config.h>
@@ -40,6 +40,7 @@
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
#include <dns/result.h>
+#include <dns/rriterator.h>
#include <dns/soa.h>
#include <dns/stats.h>
#include <dns/timer.h>
@@ -112,43 +113,6 @@
} while (0)
/**************************************************************************/
-/*%
- * A db_rr_iterator_t is an iterator that iterates over an entire database,
- * returning one RR at a time, in some arbitrary order.
- */
-
-typedef struct db_rr_iterator db_rr_iterator_t;
-
-/*% db_rr_iterator structure */
-struct db_rr_iterator {
- isc_result_t result;
- dns_db_t *db;
- dns_dbiterator_t *dbit;
- dns_dbversion_t *ver;
- isc_stdtime_t now;
- dns_dbnode_t *node;
- dns_fixedname_t fixedname;
- dns_rdatasetiter_t *rdatasetit;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata;
-};
-
-static isc_result_t
-db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
- isc_stdtime_t now);
-
-static isc_result_t
-db_rr_iterator_first(db_rr_iterator_t *it);
-
-static isc_result_t
-db_rr_iterator_next(db_rr_iterator_t *it);
-
-static void
-db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,
- isc_uint32_t *ttl, dns_rdata_t **rdata);
-
-static void
-db_rr_iterator_destroy(db_rr_iterator_t *it);
static inline void
inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
@@ -160,145 +124,6 @@ inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
}
}
-static isc_result_t
-db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
- isc_stdtime_t now)
-{
- isc_result_t result;
- it->db = db;
- it->dbit = NULL;
- it->ver = ver;
- it->now = now;
- it->node = NULL;
- result = dns_db_createiterator(it->db, 0, &it->dbit);
- if (result != ISC_R_SUCCESS)
- return (result);
- it->rdatasetit = NULL;
- dns_rdata_init(&it->rdata);
- dns_rdataset_init(&it->rdataset);
- dns_fixedname_init(&it->fixedname);
- INSIST(! dns_rdataset_isassociated(&it->rdataset));
- it->result = ISC_R_SUCCESS;
- return (it->result);
-}
-
-static isc_result_t
-db_rr_iterator_first(db_rr_iterator_t *it) {
- it->result = dns_dbiterator_first(it->dbit);
- /*
- * The top node may be empty when out of zone glue exists.
- * Walk the tree to find the first node with data.
- */
- while (it->result == ISC_R_SUCCESS) {
- it->result = dns_dbiterator_current(it->dbit, &it->node,
- dns_fixedname_name(&it->fixedname));
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
-
- it->result = dns_db_allrdatasets(it->db, it->node,
- it->ver, it->now,
- &it->rdatasetit);
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
-
- it->result = dns_rdatasetiter_first(it->rdatasetit);
- if (it->result != ISC_R_SUCCESS) {
- /*
- * This node is empty. Try next node.
- */
- dns_rdatasetiter_destroy(&it->rdatasetit);
- dns_db_detachnode(it->db, &it->node);
- it->result = dns_dbiterator_next(it->dbit);
- continue;
- }
- dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
- it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
- it->result = dns_rdataset_first(&it->rdataset);
- return (it->result);
- }
- return (it->result);
-}
-
-
-static isc_result_t
-db_rr_iterator_next(db_rr_iterator_t *it) {
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
-
- INSIST(it->dbit != NULL);
- INSIST(it->node != NULL);
- INSIST(it->rdatasetit != NULL);
-
- it->result = dns_rdataset_next(&it->rdataset);
- if (it->result == ISC_R_NOMORE) {
- dns_rdataset_disassociate(&it->rdataset);
- it->result = dns_rdatasetiter_next(it->rdatasetit);
- /*
- * The while loop body is executed more than once
- * only when an empty dbnode needs to be skipped.
- */
- while (it->result == ISC_R_NOMORE) {
- dns_rdatasetiter_destroy(&it->rdatasetit);
- dns_db_detachnode(it->db, &it->node);
- it->result = dns_dbiterator_next(it->dbit);
- if (it->result == ISC_R_NOMORE) {
- /* We are at the end of the entire database. */
- return (it->result);
- }
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
- it->result = dns_dbiterator_current(it->dbit,
- &it->node,
- dns_fixedname_name(&it->fixedname));
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
- it->result = dns_db_allrdatasets(it->db, it->node,
- it->ver, it->now,
- &it->rdatasetit);
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
- it->result = dns_rdatasetiter_first(it->rdatasetit);
- }
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
- dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
- it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
- it->result = dns_rdataset_first(&it->rdataset);
- if (it->result != ISC_R_SUCCESS)
- return (it->result);
- }
- return (it->result);
-}
-
-static void
-db_rr_iterator_pause(db_rr_iterator_t *it) {
- RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS);
-}
-
-static void
-db_rr_iterator_destroy(db_rr_iterator_t *it) {
- if (dns_rdataset_isassociated(&it->rdataset))
- dns_rdataset_disassociate(&it->rdataset);
- if (it->rdatasetit != NULL)
- dns_rdatasetiter_destroy(&it->rdatasetit);
- if (it->node != NULL)
- dns_db_detachnode(it->db, &it->node);
- dns_dbiterator_destroy(&it->dbit);
-}
-
-static void
-db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,
- isc_uint32_t *ttl, dns_rdata_t **rdata)
-{
- REQUIRE(name != NULL && *name == NULL);
- REQUIRE(it->result == ISC_R_SUCCESS);
- *name = dns_fixedname_name(&it->fixedname);
- *ttl = it->rdataset.ttl;
- dns_rdata_reset(&it->rdata);
- dns_rdataset_current(&it->rdataset, &it->rdata);
- *rdata = &it->rdata;
-}
-
/**************************************************************************/
/*% Log an RR (for debugging) */
@@ -488,7 +313,7 @@ static rrstream_methods_t ixfr_rrstream_methods = {
typedef struct axfr_rrstream {
rrstream_t common;
- db_rr_iterator_t it;
+ dns_rriterator_t it;
isc_boolean_t it_valid;
} axfr_rrstream_t;
@@ -516,7 +341,7 @@ axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
s->common.methods = &axfr_rrstream_methods;
s->it_valid = ISC_FALSE;
- CHECK(db_rr_iterator_init(&s->it, db, ver, 0));
+ CHECK(dns_rriterator_init(&s->it, db, ver, 0));
s->it_valid = ISC_TRUE;
*sp = (rrstream_t *) s;
@@ -531,7 +356,7 @@ static isc_result_t
axfr_rrstream_first(rrstream_t *rs) {
axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
isc_result_t result;
- result = db_rr_iterator_first(&s->it);
+ result = dns_rriterator_first(&s->it);
if (result != ISC_R_SUCCESS)
return (result);
/* Skip SOA records. */
@@ -539,11 +364,11 @@ axfr_rrstream_first(rrstream_t *rs) {
dns_name_t *name_dummy = NULL;
isc_uint32_t ttl_dummy;
dns_rdata_t *rdata = NULL;
- db_rr_iterator_current(&s->it, &name_dummy,
- &ttl_dummy, &rdata);
+ dns_rriterator_current(&s->it, &name_dummy,
+ &ttl_dummy, NULL, &rdata);
if (rdata->type != dns_rdatatype_soa)
break;
- result = db_rr_iterator_next(&s->it);
+ result = dns_rriterator_next(&s->it);
if (result != ISC_R_SUCCESS)
break;
}
@@ -560,11 +385,11 @@ axfr_rrstream_next(rrstream_t *rs) {
dns_name_t *name_dummy = NULL;
isc_uint32_t ttl_dummy;
dns_rdata_t *rdata = NULL;
- result = db_rr_iterator_next(&s->it);
+ result = dns_rriterator_next(&s->it);
if (result != ISC_R_SUCCESS)
break;
- db_rr_iterator_current(&s->it, &name_dummy,
- &ttl_dummy, &rdata);
+ dns_rriterator_current(&s->it, &name_dummy,
+ &ttl_dummy, NULL, &rdata);
if (rdata->type != dns_rdatatype_soa)
break;
}
@@ -576,20 +401,20 @@ axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl,
dns_rdata_t **rdata)
{
axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
- db_rr_iterator_current(&s->it, name, ttl, rdata);
+ dns_rriterator_current(&s->it, name, ttl, NULL, rdata);
}
static void
axfr_rrstream_pause(rrstream_t *rs) {
axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
- db_rr_iterator_pause(&s->it);
+ dns_rriterator_pause(&s->it);
}
static void
axfr_rrstream_destroy(rrstream_t **rsp) {
axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp;
if (s->it_valid)
- db_rr_iterator_destroy(&s->it);
+ dns_rriterator_destroy(&s->it);
isc_mem_put(s->common.mctx, s, sizeof(*s));
}
@@ -1038,6 +863,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
switch(dns_zone_gettype(zone)) {
case dns_zone_master:
case dns_zone_slave:
+ case dns_zone_dlz:
break; /* Master and slave zones are OK for transfer. */
default:
FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class);
diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c
index 367ddd320d2c..eb93f1bbe45b 100644
--- a/bin/named/zoneconf.c
+++ b/bin/named/zoneconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zoneconf.c,v 1.147.50.2 2009-01-29 23:47:44 tbox Exp $ */
+/* $Id: zoneconf.c,v 1.170 2011-01-06 23:47:00 tbox Exp $ */
/*% */
@@ -30,10 +30,16 @@
#include <isc/util.h>
#include <dns/acl.h>
+#include <dns/db.h>
#include <dns/fixedname.h>
#include <dns/log.h>
#include <dns/name.h>
+#include <dns/rdata.h>
#include <dns/rdatatype.h>
+#include <dns/rdataset.h>
+#include <dns/rdatalist.h>
+#include <dns/result.h>
+#include <dns/sdlz.h>
#include <dns/ssu.h>
#include <dns/stats.h>
#include <dns/view.h>
@@ -55,16 +61,18 @@ typedef enum {
allow_update_forwarding
} acl_type_t;
-/*%
- * These are BIND9 server defaults, not necessarily identical to the
- * library defaults defined in zone.c.
- */
#define RETERR(x) do { \
isc_result_t _r = (x); \
if (_r != ISC_R_SUCCESS) \
return (_r); \
} while (0)
+#define CHECK(x) do { \
+ result = (x); \
+ if (result != ISC_R_SUCCESS) \
+ goto cleanup; \
+ } while (0)
+
/*%
* Convenience function for configuring a single zone ACL.
*/
@@ -133,8 +141,11 @@ configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
}
/* Check for default ACLs that haven't been parsed yet */
- if (vconfig != NULL)
- maps[i++] = cfg_tuple_get(vconfig, "options");
+ if (vconfig != NULL) {
+ const cfg_obj_t *options = cfg_tuple_get(vconfig, "options");
+ if (options != NULL)
+ maps[i++] = options;
+ }
if (config != NULL) {
const cfg_obj_t *options = NULL;
(void)cfg_map_get(config, "options", &options);
@@ -169,19 +180,29 @@ parse_acl:
* Parse the zone update-policy statement.
*/
static isc_result_t
-configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
+configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
+ const char *zname)
+{
const cfg_obj_t *updatepolicy = NULL;
const cfg_listelt_t *element, *element2;
dns_ssutable_t *table = NULL;
isc_mem_t *mctx = dns_zone_getmctx(zone);
+ isc_boolean_t autoddns = ISC_FALSE;
isc_result_t result;
(void)cfg_map_get(zconfig, "update-policy", &updatepolicy);
+
if (updatepolicy == NULL) {
dns_zone_setssutable(zone, NULL);
return (ISC_R_SUCCESS);
}
+ if (cfg_obj_isstring(updatepolicy) &&
+ strcmp("local", cfg_obj_asstring(updatepolicy)) == 0) {
+ autoddns = ISC_TRUE;
+ updatepolicy = NULL;
+ }
+
result = dns_ssutable_create(mctx, &table);
if (result != ISC_R_SUCCESS)
return (result);
@@ -198,6 +219,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types");
const char *str;
isc_boolean_t grant = ISC_FALSE;
+ isc_boolean_t usezone = ISC_FALSE;
unsigned int mtype = DNS_SSUMATCHTYPE_NAME;
dns_fixedname_t fname, fident;
isc_buffer_t b;
@@ -237,6 +259,11 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
mtype = DNS_SSUMATCHTYPE_TCPSELF;
else if (strcasecmp(str, "6to4-self") == 0)
mtype = DNS_SSUMATCHTYPE_6TO4SELF;
+ else if (strcasecmp(str, "zonesub") == 0) {
+ mtype = DNS_SSUMATCHTYPE_SUBDOMAIN;
+ usezone = ISC_TRUE;
+ } else if (strcasecmp(str, "external") == 0)
+ mtype = DNS_SSUMATCHTYPE_EXTERNAL;
else
INSIST(0);
@@ -245,7 +272,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(dns_fixedname_name(&fident), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
@@ -253,15 +280,27 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
}
dns_fixedname_init(&fname);
- str = cfg_obj_asstring(dname);
- isc_buffer_init(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
- dns_rootname, ISC_FALSE, NULL);
- if (result != ISC_R_SUCCESS) {
- cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
- "'%s' is not a valid name", str);
- goto cleanup;
+ if (usezone) {
+ result = dns_name_copy(dns_zone_getorigin(zone),
+ dns_fixedname_name(&fname),
+ NULL);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
+ "error copying origin: %s",
+ isc_result_totext(result));
+ goto cleanup;
+ }
+ } else {
+ str = cfg_obj_asstring(dname);
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ result = dns_name_fromtext(dns_fixedname_name(&fname),
+ &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
+ "'%s' is not a valid name", str);
+ goto cleanup;
+ }
}
n = ns_config_listcount(typelist);
@@ -311,7 +350,34 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
+ }
+
+ /*
+ * If "update-policy local;" and a session key exists,
+ * then use the default policy, which is equivalent to:
+ * update-policy { grant <session-keyname> zonesub any; };
+ */
+ if (autoddns) {
+ dns_rdatatype_t any = dns_rdatatype_any;
+
+ if (ns_g_server->session_keyname == NULL) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "failed to enable auto DDNS policy "
+ "for zone %s: session key not found",
+ zname);
+ result = ISC_R_NOTFOUND;
+ goto cleanup;
+ }
+ result = dns_ssutable_addrule(table, ISC_TRUE,
+ ns_g_server->session_keyname,
+ DNS_SSUMATCHTYPE_SUBDOMAIN,
+ dns_zone_getorigin(zone),
+ 1, &any);
+
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
}
result = ISC_R_SUCCESS;
@@ -322,6 +388,323 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone) {
return (result);
}
+/*
+ * This is the TTL used for internally generated RRsets for static-stub zones.
+ * The value doesn't matter because the mapping is static, but needs to be
+ * defined for the sake of implementation.
+ */
+#define STATICSTUB_SERVER_TTL 86400
+
+/*%
+ * Configure an apex NS with glues for a static-stub zone.
+ * For example, for the zone named "example.com", the following RRs will be
+ * added to the zone DB:
+ * example.com. NS example.com.
+ * example.com. A 192.0.2.1
+ * example.com. AAAA 2001:db8::1
+ */
+static isc_result_t
+configure_staticstub_serveraddrs(const cfg_obj_t *zconfig, dns_zone_t *zone,
+ dns_rdatalist_t *rdatalist_ns,
+ dns_rdatalist_t *rdatalist_a,
+ dns_rdatalist_t *rdatalist_aaaa)
+{
+ const cfg_listelt_t *element;
+ isc_mem_t *mctx = dns_zone_getmctx(zone);
+ isc_region_t region, sregion;
+ dns_rdata_t *rdata;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ for (element = cfg_list_first(zconfig);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const isc_sockaddr_t* sa;
+ isc_netaddr_t na;
+ const cfg_obj_t *address = cfg_listelt_value(element);
+ dns_rdatalist_t *rdatalist;
+
+ sa = cfg_obj_assockaddr(address);
+ if (isc_sockaddr_getport(sa) != 0) {
+ cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
+ "port is not configurable for "
+ "static stub server-addresses");
+ return (ISC_R_FAILURE);
+ }
+ isc_netaddr_fromsockaddr(&na, sa);
+ if (isc_netaddr_getzone(&na) != 0) {
+ cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
+ "scoped address is not allowed "
+ "for static stub "
+ "server-addresses");
+ return (ISC_R_FAILURE);
+ }
+
+ switch (na.family) {
+ case AF_INET:
+ region.length = sizeof(na.type.in);
+ rdatalist = rdatalist_a;
+ break;
+ default:
+ INSIST(na.family == AF_INET6);
+ region.length = sizeof(na.type.in6);
+ rdatalist = rdatalist_aaaa;
+ break;
+ }
+
+ rdata = isc_mem_get(mctx, sizeof(*rdata) + region.length);
+ if (rdata == NULL)
+ return (ISC_R_NOMEMORY);
+ region.base = (unsigned char *)(rdata + 1);
+ memcpy(region.base, &na.type, region.length);
+ dns_rdata_init(rdata);
+ dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
+ rdatalist->type, &region);
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ }
+
+ /*
+ * If no address is specified (unlikely in this context, but possible),
+ * there's nothing to do anymore.
+ */
+ if (ISC_LIST_EMPTY(rdatalist_a->rdata) &&
+ ISC_LIST_EMPTY(rdatalist_aaaa->rdata)) {
+ return (ISC_R_SUCCESS);
+ }
+
+ /* Add to the list an apex NS with the ns name being the origin name */
+ dns_name_toregion(dns_zone_getorigin(zone), &sregion);
+ rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
+ if (rdata == NULL) {
+ /*
+ * Already allocated data will be freed in the caller, so
+ * we can simply return here.
+ */
+ return (ISC_R_NOMEMORY);
+ }
+ region.length = sregion.length;
+ region.base = (unsigned char *)(rdata + 1);
+ memcpy(region.base, sregion.base, region.length);
+ dns_rdata_init(rdata);
+ dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
+ dns_rdatatype_ns, &region);
+ ISC_LIST_APPEND(rdatalist_ns->rdata, rdata, link);
+
+ return (result);
+}
+
+/*%
+ * Configure an apex NS with an out-of-zone NS names for a static-stub zone.
+ * For example, for the zone named "example.com", something like the following
+ * RRs will be added to the zone DB:
+ * example.com. NS ns.example.net.
+ */
+static isc_result_t
+configure_staticstub_servernames(const cfg_obj_t *zconfig, dns_zone_t *zone,
+ dns_rdatalist_t *rdatalist, const char *zname)
+{
+ const cfg_listelt_t *element;
+ isc_mem_t *mctx = dns_zone_getmctx(zone);
+ dns_rdata_t *rdata;
+ isc_region_t sregion, region;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ for (element = cfg_list_first(zconfig);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const cfg_obj_t *obj;
+ const char *str;
+ dns_fixedname_t fixed_name;
+ dns_name_t *nsname;
+ isc_buffer_t b;
+
+ obj = cfg_listelt_value(element);
+ str = cfg_obj_asstring(obj);
+
+ dns_fixedname_init(&fixed_name);
+ nsname = dns_fixedname_name(&fixed_name);
+
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ result = dns_name_fromtext(nsname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
+ "server-name '%s' is not a valid "
+ "name", str);
+ return (result);
+ }
+ if (dns_name_issubdomain(nsname, dns_zone_getorigin(zone))) {
+ cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
+ "server-name '%s' must not be a "
+ "subdomain of zone name '%s'",
+ str, zname);
+ return (ISC_R_FAILURE);
+ }
+
+ dns_name_toregion(nsname, &sregion);
+ rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
+ if (rdata == NULL)
+ return (ISC_R_NOMEMORY);
+ region.length = sregion.length;
+ region.base = (unsigned char *)(rdata + 1);
+ memcpy(region.base, sregion.base, region.length);
+ dns_rdata_init(rdata);
+ dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
+ dns_rdatatype_ns, &region);
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ }
+
+ return (result);
+}
+
+/*%
+ * Configure static-stub zone.
+ */
+static isc_result_t
+configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone,
+ const char *zname, const char *dbtype)
+{
+ int i = 0;
+ const cfg_obj_t *obj;
+ isc_mem_t *mctx = dns_zone_getmctx(zone);
+ dns_db_t *db = NULL;
+ dns_dbversion_t *dbversion = NULL;
+ dns_dbnode_t *apexnode = NULL;
+ dns_name_t apexname;
+ isc_result_t result;
+ dns_rdataset_t rdataset;
+ dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa;
+ dns_rdatalist_t* rdatalists[] = {
+ &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa, NULL
+ };
+ dns_rdata_t *rdata;
+ isc_region_t region;
+
+ /* Create the DB beforehand */
+ RETERR(dns_db_create(mctx, dbtype, dns_zone_getorigin(zone),
+ dns_dbtype_stub, dns_zone_getclass(zone),
+ 0, NULL, &db));
+ dns_zone_setdb(zone, db);
+
+ dns_rdatalist_init(&rdatalist_ns);
+ rdatalist_ns.rdclass = dns_zone_getclass(zone);
+ rdatalist_ns.type = dns_rdatatype_ns;
+ rdatalist_ns.ttl = STATICSTUB_SERVER_TTL;
+
+ dns_rdatalist_init(&rdatalist_a);
+ rdatalist_a.rdclass = dns_zone_getclass(zone);
+ rdatalist_a.type = dns_rdatatype_a;
+ rdatalist_a.ttl = STATICSTUB_SERVER_TTL;
+
+ dns_rdatalist_init(&rdatalist_aaaa);
+ rdatalist_aaaa.rdclass = dns_zone_getclass(zone);
+ rdatalist_aaaa.type = dns_rdatatype_aaaa;
+ rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL;
+
+ /* Prepare zone RRs from the configuration */
+ obj = NULL;
+ result = cfg_map_get(zconfig, "server-addresses", &obj);
+ if (obj != NULL) {
+ result = configure_staticstub_serveraddrs(obj, zone,
+ &rdatalist_ns,
+ &rdatalist_a,
+ &rdatalist_aaaa);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ obj = NULL;
+ result = cfg_map_get(zconfig, "server-names", &obj);
+ if (obj != NULL) {
+ result = configure_staticstub_servernames(obj, zone,
+ &rdatalist_ns,
+ zname);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ /*
+ * Sanity check: there should be at least one NS RR at the zone apex
+ * to trigger delegation.
+ */
+ if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "No NS record is configured for a "
+ "static-stub zone '%s'", zname);
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
+ /*
+ * Now add NS and glue A/AAAA RRsets to the zone DB.
+ * First open a new version for the add operation and get a pointer
+ * to the apex node (all RRs are of the apex name).
+ */
+ result = dns_db_newversion(db, &dbversion);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_name_init(&apexname, NULL);
+ dns_name_clone(dns_zone_getorigin(zone), &apexname);
+ result = dns_db_findnode(db, &apexname, ISC_FALSE, &apexnode);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Add NS RRset */
+ dns_rdataset_init(&rdataset);
+ RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns, &rdataset)
+ == ISC_R_SUCCESS);
+ result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset,
+ 0, NULL);
+ dns_rdataset_disassociate(&rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Add glue A RRset, if any */
+ if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) {
+ RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a, &rdataset)
+ == ISC_R_SUCCESS);
+ result = dns_db_addrdataset(db, apexnode, dbversion, 0,
+ &rdataset, 0, NULL);
+ dns_rdataset_disassociate(&rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ /* Add glue AAAA RRset, if any */
+ if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) {
+ RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa,
+ &rdataset)
+ == ISC_R_SUCCESS);
+ result = dns_db_addrdataset(db, apexnode, dbversion, 0,
+ &rdataset, 0, NULL);
+ dns_rdataset_disassociate(&rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (apexnode != NULL)
+ dns_db_detachnode(db, &apexnode);
+ if (dbversion != NULL)
+ dns_db_closeversion(db, &dbversion, ISC_TRUE);
+ if (db != NULL)
+ dns_db_detach(&db);
+ for (i = 0; rdatalists[i] != NULL; i++) {
+ while ((rdata = ISC_LIST_HEAD(rdatalists[i]->rdata)) != NULL) {
+ ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link);
+ dns_rdata_toregion(rdata, &region);
+ isc_mem_put(mctx, rdata,
+ sizeof(*rdata) + region.length);
+ }
+ }
+
+ return (result);
+}
+
/*%
* Convert a config file zone type into a server zone type.
*/
@@ -503,6 +886,19 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
if (result == ISC_R_SUCCESS)
filename = cfg_obj_asstring(obj);
+ /*
+ * Unless we're using some alternative database, a master zone
+ * will be needing a master file.
+ */
+ if (ztype == dns_zone_master && cpval == default_dbtype &&
+ filename == NULL) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "zone '%s': 'file' not specified",
+ zname);
+ return (ISC_R_FAILURE);
+ }
+
masterformat = dns_masterformat_text;
obj = NULL;
result= ns_config_get(maps, "masterfile-format", &obj);
@@ -577,7 +973,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
* to primary masters (type "master") and slaves
* acting as masters (type "slave"), but not to stubs.
*/
- if (ztype != dns_zone_stub) {
+ if (ztype != dns_zone_stub && ztype != dns_zone_staticstub) {
obj = NULL;
result = ns_config_get(maps, "notify", &obj);
INSIST(result == ISC_R_SUCCESS);
@@ -731,6 +1127,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
*/
if (ztype == dns_zone_master) {
dns_acl_t *updateacl;
+
RETERR(configure_zone_acl(zconfig, vconfig, config,
allow_update, ac, zone,
dns_zone_setupdateacl,
@@ -744,7 +1141,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
"address, which is insecure",
zname);
- RETERR(configure_zone_ssutable(zoptions, zone));
+ RETERR(configure_zone_ssutable(zoptions, zone, zname));
obj = NULL;
result = ns_config_get(maps, "sig-validity-interval", &obj);
@@ -774,12 +1171,6 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
result = ns_config_get(maps, "key-directory", &obj);
if (result == ISC_R_SUCCESS) {
filename = cfg_obj_asstring(obj);
- if (!isc_file_isabsolute(filename)) {
- cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
- "key-directory '%s' "
- "is not absolute", filename);
- return (ISC_R_FAILURE);
- }
RETERR(dns_zone_setkeydirectory(zone, filename));
}
@@ -804,6 +1195,11 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK,
cfg_obj_asboolean(obj));
+ obj = NULL;
+ result = ns_config_get(maps, "dnssec-dnskey-kskonly", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY,
+ cfg_obj_asboolean(obj));
} else if (ztype == dns_zone_slave) {
RETERR(configure_zone_acl(zconfig, vconfig, config,
allow_update_forwarding, ac, zone,
@@ -811,11 +1207,13 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_clearforwardacl));
}
-
/*%
* Primary master functionality.
*/
if (ztype == dns_zone_master) {
+ isc_boolean_t allow = ISC_FALSE, maint = ISC_FALSE;
+ isc_boolean_t create = ISC_FALSE;
+
obj = NULL;
result = ns_config_get(maps, "check-wildcard", &obj);
if (result == ISC_R_SUCCESS)
@@ -825,6 +1223,21 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKWILDCARD, check);
obj = NULL;
+ result = ns_config_get(maps, "check-dup-records", &obj);
+ INSIST(obj != NULL);
+ if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
+ fail = ISC_FALSE;
+ check = ISC_TRUE;
+ } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
+ fail = check = ISC_TRUE;
+ } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
+ fail = check = ISC_FALSE;
+ } else
+ INSIST(0);
+ dns_zone_setoption(zone, DNS_ZONEOPT_CHECKDUPRR, check);
+ dns_zone_setoption(zone, DNS_ZONEOPT_CHECKDUPRRFAIL, fail);
+
+ obj = NULL;
result = ns_config_get(maps, "check-mx", &obj);
INSIST(obj != NULL);
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
@@ -874,6 +1287,31 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
INSIST(0);
dns_zone_setoption(zone, DNS_ZONEOPT_WARNSRVCNAME, warn);
dns_zone_setoption(zone, DNS_ZONEOPT_IGNORESRVCNAME, ignore);
+
+ obj = NULL;
+ result = ns_config_get(maps, "dnssec-secure-to-insecure", &obj);
+ INSIST(obj != NULL);
+ dns_zone_setoption(zone, DNS_ZONEOPT_SECURETOINSECURE,
+ cfg_obj_asboolean(obj));
+
+ obj = NULL;
+ result = cfg_map_get(zoptions, "auto-dnssec", &obj);
+ if (result == ISC_R_SUCCESS) {
+ const char *arg = cfg_obj_asstring(obj);
+ if (strcasecmp(arg, "allow") == 0)
+ allow = ISC_TRUE;
+ else if (strcasecmp(arg, "maintain") == 0)
+ allow = maint = ISC_TRUE;
+ else if (strcasecmp(arg, "create") == 0)
+ allow = maint = create = ISC_TRUE;
+ else if (strcasecmp(arg, "off") == 0)
+ ;
+ else
+ INSIST(0);
+ dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow);
+ dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint);
+ dns_zone_setkeyopt(zone, DNS_ZONEKEY_CREATE, create);
+ }
}
/*
@@ -982,6 +1420,11 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
cfg_obj_asboolean(obj));
break;
+ case dns_zone_staticstub:
+ RETERR(configure_staticstub(zoptions, zone, zname,
+ default_dbtype));
+ break;
+
default:
break;
}
@@ -989,6 +1432,31 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
return (ISC_R_SUCCESS);
}
+
+#ifdef DLZ
+/*
+ * Set up a DLZ zone as writeable
+ */
+isc_result_t
+ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
+ dns_rdataclass_t rdclass, dns_name_t *name)
+{
+ dns_db_t *db = NULL;
+ isc_time_t now;
+ isc_result_t result;
+
+ TIME_NOW(&now);
+
+ dns_zone_settype(zone, dns_zone_dlz);
+ result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db);
+ if (result != ISC_R_SUCCESS)
+ return result;
+ result = dns_zone_dlzpostload(zone, db);
+ dns_db_detach(&db);
+ return result;
+}
+#endif
+
isc_boolean_t
ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
const cfg_obj_t *zoptions = NULL;
@@ -1001,6 +1469,13 @@ ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
if (zonetype_fromconfig(zoptions) != dns_zone_gettype(zone))
return (ISC_FALSE);
+ /*
+ * We always reconfigure a static-stub zone for simplicity, assuming
+ * the amount of data to be loaded is small.
+ */
+ if (zonetype_fromconfig(zoptions) == dns_zone_staticstub)
+ return (ISC_FALSE);
+
obj = NULL;
(void)cfg_map_get(zoptions, "file", &obj);
if (obj != NULL)
diff --git a/bin/nsupdate/Makefile.in b/bin/nsupdate/Makefile.in
index f7f6346c9d6b..a65aad9162ed 100644
--- a/bin/nsupdate/Makefile.in
+++ b/bin/nsupdate/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2006-2008 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2006-2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.29 2008-08-29 23:47:22 tbox Exp $
+# $Id: Makefile.in,v 1.36 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -24,7 +24,7 @@ top_srcdir = @top_srcdir@
@BIND9_MAKE_INCLUDES@
CINCLUDES = ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \
- ${ISC_INCLUDES} @DST_GSSAPI_INC@
+ ${ISC_INCLUDES} ${ISCCFG_INCLUDES} @DST_GSSAPI_INC@
CDEFINES = @USE_GSSAPI@
CWARNINGS =
@@ -33,6 +33,7 @@ LWRESLIBS = ../../lib/lwres/liblwres.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
@@ -43,7 +44,9 @@ ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS}
-LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCLIBS} ${ISCCFGLIBS} @LIBS@
+LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@
+
+NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} ${ISCNOSYMLIBS} @LIBS@
SUBDIRS =
@@ -63,8 +66,14 @@ MANOBJS = ${MANPAGES} ${HTMLPAGES}
@BIND9_MAKE_RULES@
+nsupdate.@O@: nsupdate.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DSESSION_KEYFILE=\"${localstatedir}/run/named/session.key\" \
+ -c ${srcdir}/nsupdate.c
+
nsupdate@EXEEXT@: nsupdate.@O@ ${UOBJS} ${DEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ nsupdate.@O@ ${UOBJS} ${LIBS}
+ export BASEOBJS="nsupdate.@O@ ${UOBJS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
diff --git a/bin/nsupdate/nsupdate.1 b/bin/nsupdate/nsupdate.1
index 6c03486559ef..9d82891dda9f 100644
--- a/bin/nsupdate/nsupdate.1
+++ b/bin/nsupdate/nsupdate.1
@@ -13,18 +13,18 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: nsupdate.1,v 1.3.48.4 2010-07-10 02:06:17 tbox Exp $
+.\" $Id: nsupdate.1,v 1.13 2010-07-10 01:14:19 tbox Exp $
.\"
.hy 0
.ad l
.\" Title: nsupdate
.\" Author:
.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
-.\" Date: Jun 30, 2000
+.\" Date: Aug 25, 2009
.\" Manual: BIND9
.\" Source: BIND9
.\"
-.TH "NSUPDATE" "1" "Jun 30, 2000" "BIND9" "BIND9"
+.TH "NSUPDATE" "1" "Aug 25, 2009" "BIND9" "BIND9"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -33,11 +33,11 @@
nsupdate \- Dynamic DNS update utility
.SH "SYNOPSIS"
.HP 9
-\fBnsupdate\fR [\fB\-d\fR] [\fB\-D\fR] [[\fB\-g\fR] | [\fB\-o\fR] | [\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-R\ \fR\fB\fIrandomdev\fR\fR] [\fB\-v\fR] [filename]
+\fBnsupdate\fR [\fB\-d\fR] [\fB\-D\fR] [[\fB\-g\fR] | [\fB\-o\fR] | [\fB\-l\fR] | [\fB\-y\ \fR\fB\fI[hmac:]\fR\fIkeyname:secret\fR\fR] | [\fB\-k\ \fR\fB\fIkeyfile\fR\fR]] [\fB\-t\ \fR\fB\fItimeout\fR\fR] [\fB\-u\ \fR\fB\fIudptimeout\fR\fR] [\fB\-r\ \fR\fB\fIudpretries\fR\fR] [\fB\-R\ \fR\fB\fIrandomdev\fR\fR] [\fB\-v\fR] [filename]
.SH "DESCRIPTION"
.PP
\fBnsupdate\fR
-is used to submit Dynamic DNS Update requests as defined in RFC2136 to a name server. This allows resource records to be added or removed from a zone without manually editing the zone file. A single update request can contain requests to add or remove more than one resource record.
+is used to submit Dynamic DNS Update requests as defined in RFC 2136 to a name server. This allows resource records to be added or removed from a zone without manually editing the zone file. A single update request can contain requests to add or remove more than one resource record.
.PP
Zones that are under dynamic control via
\fBnsupdate\fR
@@ -60,7 +60,11 @@ option makes
report additional debugging information to
\fB\-d\fR.
.PP
-Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC2845 or the SIG(0) record described in RFC3535 and RFC2931 or GSS\-TSIG as described in RFC3645. TSIG relies on a shared secret that should only be known to
+The
+\fB\-L\fR
+option with an integer argument of zero or higher sets the logging debug level. If zero, logging is disabled.
+.PP
+Transaction signatures can be used to authenticate the Dynamic DNS updates. These use the TSIG resource record type described in RFC 2845 or the SIG(0) record described in RFC 2535 and RFC 2931 or GSS\-TSIG as described in RFC 3645. TSIG relies on a shared secret that should only be known to
\fBnsupdate\fR
and the name server. Currently, the only supported encryption algorithm for TSIG is HMAC\-MD5, which is defined in RFC 2104. Once other algorithms are defined for TSIG, applications will need to ensure they select the appropriate algorithm as well as the key when authenticating each other. For instance, suitable
\fBkey\fR
@@ -71,22 +75,22 @@ statements would be added to
so that the name server can associate the appropriate secret key and algorithm with the IP address of the client application that will be using TSIG authentication. SIG(0) uses public key cryptography. To use a SIG(0) key, the public key must be stored in a KEY record in a zone served by the name server.
\fBnsupdate\fR
does not read
-\fI/etc/named.conf\fR. GSS\-TSIG uses Kerberos credentials.
+\fI/etc/named.conf\fR.
+.PP
+GSS\-TSIG uses Kerberos credentials. Standard GSS\-TSIG mode is switched on with the
+\fB\-g\fR
+flag. A non\-standards\-compliant variant of GSS\-TSIG used by Windows 2000 can be switched on with the
+\fB\-o\fR
+flag.
.PP
\fBnsupdate\fR
uses the
\fB\-y\fR
or
\fB\-k\fR
-option to provide the shared secret needed to generate a TSIG record for authenticating Dynamic DNS update requests, default type HMAC\-MD5. These options are mutually exclusive. With the
-\fB\-k\fR
-option,
-\fBnsupdate\fR
-reads the shared secret from the file
-\fIkeyfile\fR, whose name is of the form
-\fIK{name}.+157.+{random}.private\fR. For historical reasons, the file
-\fIK{name}.+157.+{random}.key\fR
-must also be present. When the
+option to provide the shared secret needed to generate a TSIG record for authenticating Dynamic DNS update requests, default type HMAC\-MD5. These options are mutually exclusive.
+.PP
+When the
\fB\-y\fR
option is used, a signature is generated from
[\fIhmac:\fR]\fIkeyname:secret.\fR
@@ -99,17 +103,37 @@ option is discouraged because the shared secret is supplied as a command line ar
\fBps\fR(1)
or in a history file maintained by the user's shell.
.PP
-The
+With the
+\fB\-k\fR
+option,
+\fBnsupdate\fR
+reads the shared secret from the file
+\fIkeyfile\fR. Keyfiles may be in two formats: a single file containing a
+\fInamed.conf\fR\-format
+\fBkey\fR
+statement, which may be generated automatically by
+\fBddns\-confgen\fR, or a pair of files whose names are of the format
+\fIK{name}.+157.+{random}.key\fR
+and
+\fIK{name}.+157.+{random}.private\fR, which can be generated by
+\fBdnssec\-keygen\fR. The
\fB\-k\fR
may also be used to specify a SIG(0) key used to authenticate Dynamic DNS update requests. In this case, the key specified is not an HMAC\-MD5 key.
.PP
-The
-\fB\-g\fR
-and
-\fB\-o\fR
-specify that GSS\-TSIG is to be used. The
-\fB\-o\fR
-should only be used with old Microsoft Windows 2000 servers.
+\fBnsupdate\fR
+can be run in a local\-host only mode using the
+\fB\-l\fR
+flag. This sets the server address to localhost (disabling the
+\fBserver\fR
+so that the server address cannot be overridden). Connections to the local server will use a TSIG key found in
+\fI/var/run/named/session.key\fR, which is automatically generated by
+\fBnamed\fR
+if any local master zone has set
+\fBupdate\-policy\fR
+to
+\fBlocal\fR. The location of this key file can be overridden with the
+\fB\-k\fR
+option.
.PP
By default,
\fBnsupdate\fR
@@ -120,6 +144,10 @@ option makes
use a TCP connection. This may be preferable when a batch of update requests is made.
.PP
The
+\fB\-p\fR
+sets the default port number to use for connections to a name server. The default is 53.
+.PP
+The
\fB\-t\fR
option sets the maximum time an update request can take before it is aborted. The default is 300 seconds. Zero can be used to disable the timeout.
.PP
@@ -367,7 +395,7 @@ with IP address 172.16.1.1 is added. The newly\-added record has a 1 day TTL (86
.sp
.PP
The prerequisite condition gets the name server to check that there are no resource records of any type for
-\fBnickname.example.com\fR. If there are, the update request fails. If this name does not exist, a CNAME for it is added. This ensures that when the CNAME is added, it cannot conflict with the long\-standing rule in RFC1034 that a name must not exist as any other record type if it exists as a CNAME. (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have RRSIG, DNSKEY and NSEC records.)
+\fBnickname.example.com\fR. If there are, the update request fails. If this name does not exist, a CNAME for it is added. This ensures that when the CNAME is added, it cannot conflict with the long\-standing rule in RFC 1034 that a name must not exist as any other record type if it exists as a CNAME. (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have RRSIG, DNSKEY and NSEC records.)
.SH "FILES"
.PP
\fB/etc/resolv.conf\fR
@@ -375,6 +403,11 @@ The prerequisite condition gets the name server to check that there are no resou
used to identify default name server
.RE
.PP
+\fB/var/run/named/session.key\fR
+.RS 4
+sets the default TSIG key for use in local\-only mode
+.RE
+.PP
\fBK{name}.+157.+{random}.key\fR
.RS 4
base\-64 encoding of HMAC\-MD5 key created by
@@ -388,14 +421,15 @@ base\-64 encoding of HMAC\-MD5 key created by
.RE
.SH "SEE ALSO"
.PP
-\fBRFC2136\fR(),
-\fBRFC3007\fR(),
-\fBRFC2104\fR(),
-\fBRFC2845\fR(),
-\fBRFC1034\fR(),
-\fBRFC2535\fR(),
-\fBRFC2931\fR(),
+RFC 2136,
+RFC 3007,
+RFC 2104,
+RFC 2845,
+RFC 1034,
+RFC 2535,
+RFC 2931,
\fBnamed\fR(8),
+\fBddns\-confgen\fR(8),
\fBdnssec\-keygen\fR(8).
.SH "BUGS"
.PP
diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c
index d9ee4884a604..9bbea4bc937c 100644
--- a/bin/nsupdate/nsupdate.c
+++ b/bin/nsupdate/nsupdate.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsupdate.c,v 1.163.48.15 2010-12-09 04:30:57 tbox Exp $ */
+/* $Id: nsupdate.c,v 1.193 2011-01-10 05:32:03 marka Exp $ */
/*! \file */
@@ -33,6 +33,7 @@
#include <isc/commandline.h>
#include <isc/entropy.h>
#include <isc/event.h>
+#include <isc/file.h>
#include <isc/hash.h>
#include <isc/lex.h>
#include <isc/log.h>
@@ -50,6 +51,8 @@
#include <isc/types.h>
#include <isc/util.h>
+#include <isccfg/namedconf.h>
+
#include <dns/callbacks.h>
#include <dns/dispatch.h>
#include <dns/dnssec.h>
@@ -78,6 +81,7 @@
#ifdef GSSAPI
#include <dst/gssapi.h>
+#include ISC_PLATFORM_KRB5HEADER
#endif
#include <bind9/getaddresses.h>
@@ -106,6 +110,8 @@ extern int h_errno;
#define DNSDEFAULTPORT 53
+static isc_uint16_t dnsport = DNSDEFAULTPORT;
+
#ifndef RESOLV_CONF
#define RESOLV_CONF "/etc/resolv.conf"
#endif
@@ -119,6 +125,7 @@ static isc_boolean_t usevc = ISC_FALSE;
static isc_boolean_t usegsstsig = ISC_FALSE;
static isc_boolean_t use_win2k_gsstsig = ISC_FALSE;
static isc_boolean_t tried_other_gsstsig = ISC_FALSE;
+static isc_boolean_t local_only = ISC_FALSE;
static isc_taskmgr_t *taskmgr = NULL;
static isc_task_t *global_task = NULL;
static isc_event_t *global_event = NULL;
@@ -148,7 +155,8 @@ static isc_sockaddr_t *userserver = NULL;
static isc_sockaddr_t *localaddr = NULL;
static isc_sockaddr_t *serveraddr = NULL;
static isc_sockaddr_t tempaddr;
-static char *keystr = NULL, *keyfile = NULL;
+static const char *keyfile = NULL;
+static char *keystr = NULL;
static isc_entropy_t *entropy = NULL;
static isc_boolean_t shuttingdown = ISC_FALSE;
static FILE *input;
@@ -174,8 +182,10 @@ typedef struct nsu_requestinfo {
static void
sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
dns_message_t *msg, dns_request_t **request);
-static void
-fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
+
+ISC_PLATFORM_NORETURN_PRE static void
+fatal(const char *format, ...)
+ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
static void
debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
@@ -406,7 +416,7 @@ reset_system(void) {
if (tsigkey != NULL)
dns_tsigkey_detach(&tsigkey);
if (gssring != NULL)
- dns_tsigkeyring_destroy(&gssring);
+ dns_tsigkeyring_detach(&gssring);
tried_other_gsstsig = ISC_FALSE;
}
}
@@ -479,6 +489,19 @@ parse_hmac(dns_name_t **hmac, const char *hmacstr, size_t len) {
return (digestbits);
}
+static int
+basenamelen(const char *file) {
+ int len = strlen(file);
+
+ if (len > 1 && file[len - 1] == '.')
+ len -= 1;
+ else if (len > 8 && strcmp(file + len - 8, ".private") == 0)
+ len -= 8;
+ else if (len > 4 && strcmp(file + len - 4, ".key") == 0)
+ len -= 4;
+ return (len);
+}
+
static void
setup_keystr(void) {
unsigned char *secret = NULL;
@@ -520,8 +543,7 @@ setup_keystr(void) {
isc_buffer_add(&keynamesrc, n - name);
debug("namefromtext");
- result = dns_name_fromtext(keyname, &keynamesrc, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &keynamesrc, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
secretlen = strlen(secretstr) * 3 / 4;
@@ -553,21 +575,67 @@ setup_keystr(void) {
isc_mem_free(mctx, secret);
}
-static int
-basenamelen(const char *file) {
- int len = strlen(file);
+/*
+ * Get a key from a named.conf format keyfile
+ */
+static isc_result_t
+read_sessionkey(isc_mem_t *mctx, isc_log_t *lctx) {
+ cfg_parser_t *pctx = NULL;
+ cfg_obj_t *sessionkey = NULL;
+ const cfg_obj_t *key = NULL;
+ const cfg_obj_t *secretobj = NULL;
+ const cfg_obj_t *algorithmobj = NULL;
+ const char *keyname;
+ const char *secretstr;
+ const char *algorithm;
+ isc_result_t result;
+ int len;
- if (len > 1 && file[len - 1] == '.')
- len -= 1;
- else if (len > 8 && strcmp(file + len - 8, ".private") == 0)
- len -= 8;
- else if (len > 4 && strcmp(file + len - 4, ".key") == 0)
- len -= 4;
- return (len);
+ if (! isc_file_exists(keyfile))
+ return (ISC_R_FILENOTFOUND);
+
+ result = cfg_parser_create(mctx, lctx, &pctx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey,
+ &sessionkey);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = cfg_map_get(sessionkey, "key", &key);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ (void) cfg_map_get(key, "secret", &secretobj);
+ (void) cfg_map_get(key, "algorithm", &algorithmobj);
+ if (secretobj == NULL || algorithmobj == NULL)
+ fatal("key must have algorithm and secret");
+
+ keyname = cfg_obj_asstring(cfg_map_getname(key));
+ secretstr = cfg_obj_asstring(secretobj);
+ algorithm = cfg_obj_asstring(algorithmobj);
+
+ len = strlen(algorithm) + strlen(keyname) + strlen(secretstr) + 3;
+ keystr = isc_mem_allocate(mctx, len);
+ snprintf(keystr, len, "%s:%s:%s", algorithm, keyname, secretstr);
+ setup_keystr();
+
+ cleanup:
+ if (pctx != NULL) {
+ if (sessionkey != NULL)
+ cfg_obj_destroy(pctx, &sessionkey);
+ cfg_parser_destroy(&pctx);
+ }
+
+ if (keystr != NULL)
+ isc_mem_free(mctx, keystr);
+
+ return (result);
}
static void
-setup_keyfile(void) {
+setup_keyfile(isc_mem_t *mctx, isc_log_t *lctx) {
dst_key_t *dstkey = NULL;
isc_result_t result;
dns_name_t *hmacname = NULL;
@@ -577,15 +645,25 @@ setup_keyfile(void) {
if (sig0key != NULL)
dst_key_free(&sig0key);
- result = dst_key_fromnamedfile(keyfile,
+ /* Try reading the key from a K* pair */
+ result = dst_key_fromnamedfile(keyfile, NULL,
DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx,
&dstkey);
+
+ /* If that didn't work, try reading it as a session.key keyfile */
+ if (result != ISC_R_SUCCESS) {
+ result = read_sessionkey(mctx, lctx);
+ if (result == ISC_R_SUCCESS)
+ return;
+ }
+
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "could not read key from %.*s.{private,key}: "
"%s\n", basenamelen(keyfile), keyfile,
isc_result_totext(result));
return;
}
+
switch (dst_key_alg(dstkey)) {
case DST_ALG_HMACMD5:
hmacname = DNS_TSIG_HMACMD5_NAME;
@@ -746,7 +824,7 @@ setup_system(void) {
if (servers == NULL)
fatal("out of memory");
localhost.s_addr = htonl(INADDR_LOOPBACK);
- isc_sockaddr_fromin(&servers[0], &localhost, DNSDEFAULTPORT);
+ isc_sockaddr_fromin(&servers[0], &localhost, dnsport);
} else {
servers = isc_mem_get(mctx, ns_total * sizeof(isc_sockaddr_t));
if (servers == NULL)
@@ -755,12 +833,12 @@ setup_system(void) {
if (lwconf->nameservers[i].family == LWRES_ADDRTYPE_V4) {
struct in_addr in4;
memcpy(&in4, lwconf->nameservers[i].address, 4);
- isc_sockaddr_fromin(&servers[i], &in4, DNSDEFAULTPORT);
+ isc_sockaddr_fromin(&servers[i], &in4, dnsport);
} else {
struct in6_addr in6;
memcpy(&in6, lwconf->nameservers[i].address, 16);
isc_sockaddr_fromin6(&servers[i], &in6,
- DNSDEFAULTPORT);
+ dnsport);
}
}
}
@@ -827,8 +905,13 @@ setup_system(void) {
if (keystr != NULL)
setup_keystr();
- else if (keyfile != NULL)
- setup_keyfile();
+ else if (local_only) {
+ result = read_sessionkey(mctx, lctx);
+ if (result != ISC_R_SUCCESS)
+ fatal("can't read key from %s: %s\n",
+ keyfile, isc_result_totext(result));
+ } else if (keyfile != NULL)
+ setup_keyfile(mctx, lctx);
}
static void
@@ -845,7 +928,7 @@ get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr) {
INSIST(count == 1);
}
-#define PARSE_ARGS_FMT "dDMl:y:govk:rR::t:u:"
+#define PARSE_ARGS_FMT "dDML:y:ghlovk:p:rR::t:u:"
static void
pre_parse_args(int argc, char **argv) {
@@ -862,10 +945,11 @@ pre_parse_args(int argc, char **argv) {
break;
case '?':
+ case 'h':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
argv[0], isc_commandline_option);
- fprintf(stderr, "usage: nsupdate [-d] "
+ fprintf(stderr, "usage: nsupdate [-dD] [-L level] [-l]"
"[-g | -o | -y keyname:secret | -k keyfile] "
"[-v] [filename]\n");
exit(1);
@@ -897,6 +981,9 @@ parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) {
case 'M':
break;
case 'l':
+ local_only = ISC_TRUE;
+ break;
+ case 'L':
result = isc_parse_uint32(&i, isc_commandline_argument,
10);
if (result != ISC_R_SUCCESS) {
@@ -923,6 +1010,15 @@ parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) {
usegsstsig = ISC_TRUE;
use_win2k_gsstsig = ISC_TRUE;
break;
+ case 'p':
+ result = isc_parse_uint16(&dnsport,
+ isc_commandline_argument, 10);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "bad port number "
+ "'%s'\n", isc_commandline_argument);
+ exit(1);
+ }
+ break;
case 't':
result = isc_parse_uint32(&timeout,
isc_commandline_argument, 10);
@@ -968,6 +1064,22 @@ parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) {
exit(1);
}
+ if (local_only) {
+ struct in_addr localhost;
+
+ if (keyfile == NULL)
+ keyfile = SESSION_KEYFILE;
+
+ if (userserver == NULL) {
+ userserver = isc_mem_get(mctx, sizeof(isc_sockaddr_t));
+ if (userserver == NULL)
+ fatal("out of memory");
+ }
+
+ localhost.s_addr = htonl(INADDR_LOOPBACK);
+ isc_sockaddr_fromin(userserver, &localhost, dnsport);
+ }
+
#ifdef GSSAPI
if (usegsstsig && (keyfile != NULL || keystr != NULL)) {
fprintf(stderr, "%s: cannot specify -g with -k or -y\n",
@@ -976,7 +1088,7 @@ parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) {
}
#else
if (usegsstsig) {
- fprintf(stderr, "%s: cannot specify -g or -o, " \
+ fprintf(stderr, "%s: cannot specify -g or -o, " \
"program not linked with GSS API Library\n",
argv[0]);
exit(1);
@@ -1022,8 +1134,7 @@ parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) {
dns_message_takebuffer(msg, &namebuf);
isc_buffer_init(&source, word, strlen(word));
isc_buffer_add(&source, strlen(word));
- result = dns_name_fromtext(*namep, &source, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(*namep, &source, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
isc_buffer_invalidate(&source);
return (STATUS_MORE);
@@ -1225,6 +1336,11 @@ evaluate_server(char *cmdline) {
char *word, *server;
long port;
+ if (local_only) {
+ fprintf(stderr, "cannot reset server in localhost-only mode\n");
+ return (STATUS_SYNTAX);
+ }
+
word = nsu_strsep(&cmdline, " \t\r\n");
if (*word == 0) {
fprintf(stderr, "could not read server name\n");
@@ -1234,7 +1350,7 @@ evaluate_server(char *cmdline) {
word = nsu_strsep(&cmdline, " \t\r\n");
if (*word == 0)
- port = DNSDEFAULTPORT;
+ port = dnsport;
else {
char *endp;
port = strtol(word, &endp, 10);
@@ -1340,7 +1456,7 @@ evaluate_key(char *cmdline) {
isc_buffer_init(&b, namestr, strlen(namestr));
isc_buffer_add(&b, strlen(namestr));
- result = dns_name_fromtext(keyname, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "could not parse key name\n");
return (STATUS_SYNTAX);
@@ -1397,8 +1513,7 @@ evaluate_zone(char *cmdline) {
userzone = dns_fixedname_name(&fuserzone);
isc_buffer_init(&b, word, strlen(word));
isc_buffer_add(&b, strlen(word));
- result = dns_name_fromtext(userzone, &b, dns_rootname, ISC_FALSE,
- NULL);
+ result = dns_name_fromtext(userzone, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
userzone = NULL; /* Lest it point to an invalid name */
fprintf(stderr, "could not parse zone name\n");
@@ -1850,9 +1965,9 @@ get_next_command(void) {
"server address [port] (set master server for zone)\n"
"send (send the update request)\n"
"show (show the update request)\n"
-"answer (show the answer to the last request)\n"
+"answer (show the answer to the last request)\n"
"quit (quit, any pending update is not sent\n"
-"help (display this message_\n"
+"help (display this message_\n"
"key [hmac:]keyname secret (use TSIG to sign the request)\n"
"gsstsig (use GSS_TSIG to sign the request)\n"
"oldgsstsig (use Microsoft's GSS_TSIG to sign the request)\n"
@@ -2013,7 +2128,7 @@ send_update(dns_name_t *zonename, isc_sockaddr_t *master,
{
isc_result_t result;
dns_request_t *request = NULL;
- unsigned int options = 0;
+ unsigned int options = DNS_REQUESTOPT_CASE;
ddebug("send_update()");
@@ -2246,7 +2361,7 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
result = dns_name_totext(&master, ISC_TRUE, &buf);
check_result(result, "dns_name_totext");
serverstr[isc_buffer_usedlength(&buf)] = 0;
- get_address(serverstr, DNSDEFAULTPORT, &tempaddr);
+ get_address(serverstr, dnsport, &tempaddr);
serveraddr = &tempaddr;
}
dns_rdata_freestruct(&soa);
@@ -2317,9 +2432,60 @@ sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
}
#ifdef GSSAPI
+
+/*
+ * Get the realm from the users kerberos ticket if possible
+ */
static void
-start_gssrequest(dns_name_t *master)
+get_ticket_realm(isc_mem_t *mctx)
{
+ krb5_context ctx;
+ krb5_error_code rc;
+ krb5_ccache ccache;
+ krb5_principal princ;
+ char *name, *ticket_realm;
+
+ rc = krb5_init_context(&ctx);
+ if (rc != 0)
+ return;
+
+ rc = krb5_cc_default(ctx, &ccache);
+ if (rc != 0) {
+ krb5_free_context(ctx);
+ return;
+ }
+
+ rc = krb5_cc_get_principal(ctx, ccache, &princ);
+ if (rc != 0) {
+ krb5_cc_close(ctx, ccache);
+ krb5_free_context(ctx);
+ return;
+ }
+
+ rc = krb5_unparse_name(ctx, princ, &name);
+ if (rc != 0) {
+ krb5_free_principal(ctx, princ);
+ krb5_cc_close(ctx, ccache);
+ krb5_free_context(ctx);
+ return;
+ }
+
+ ticket_realm = strrchr(name, '@');
+ if (ticket_realm != NULL) {
+ realm = isc_mem_strdup(mctx, ticket_realm);
+ }
+
+ free(name);
+ krb5_free_principal(ctx, princ);
+ krb5_cc_close(ctx, ccache);
+ krb5_free_context(ctx);
+ if (realm != NULL && debugging)
+ fprintf(stderr, "Found realm from ticket: %s\n", realm+1);
+}
+
+
+static void
+start_gssrequest(dns_name_t *master) {
gss_ctx_id_t context;
isc_buffer_t buf;
isc_result_t result;
@@ -2330,12 +2496,13 @@ start_gssrequest(dns_name_t *master)
dns_fixedname_t fname;
char namestr[DNS_NAME_FORMATSIZE];
char keystr[DNS_NAME_FORMATSIZE];
+ char *err_message = NULL;
debug("start_gssrequest");
usevc = ISC_TRUE;
if (gssring != NULL)
- dns_tsigkeyring_destroy(&gssring);
+ dns_tsigkeyring_detach(&gssring);
gssring = NULL;
result = dns_tsigkeyring_create(mctx, &gssring);
@@ -2350,13 +2517,16 @@ start_gssrequest(dns_name_t *master)
fatal("out of memory");
}
if (userserver == NULL)
- get_address(namestr, DNSDEFAULTPORT, kserver);
+ get_address(namestr, dnsport, kserver);
else
(void)memcpy(kserver, userserver, sizeof(isc_sockaddr_t));
dns_fixedname_init(&fname);
servname = dns_fixedname_name(&fname);
+ if (realm == NULL)
+ get_ticket_realm(mctx);
+
result = isc_string_printf(servicename, sizeof(servicename),
"DNS/%s%s", namestr, realm ? realm : "");
if (result != ISC_R_SUCCESS)
@@ -2364,8 +2534,7 @@ start_gssrequest(dns_name_t *master)
isc_result_totext(result));
isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename));
- result = dns_name_fromtext(servname, &buf, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
fatal("dns_name_fromtext(servname) failed: %s",
isc_result_totext(result));
@@ -2382,8 +2551,7 @@ start_gssrequest(dns_name_t *master)
isc_buffer_init(&buf, keystr, strlen(keystr));
isc_buffer_add(&buf, strlen(keystr));
- result = dns_name_fromtext(keyname, &buf, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &buf, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
fatal("dns_name_fromtext(keyname) failed: %s",
isc_result_totext(result));
@@ -2400,9 +2568,11 @@ start_gssrequest(dns_name_t *master)
/* Build first request. */
context = GSS_C_NO_CONTEXT;
result = dns_tkey_buildgssquery(rmsg, keyname, servname, NULL, 0,
- &context, use_win2k_gsstsig);
+ &context, use_win2k_gsstsig,
+ mctx, &err_message);
if (result == ISC_R_FAILURE)
- fatal("Check your Kerberos ticket, it may have expired.");
+ fatal("tkey query failed: %s",
+ err_message != NULL ? err_message : "unknown error");
if (result != ISC_R_SUCCESS)
fatal("dns_tkey_buildgssquery failed: %s",
isc_result_totext(result));
@@ -2451,6 +2621,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
isc_buffer_t buf;
dns_name_t *servname;
dns_fixedname_t fname;
+ char *err_message = NULL;
UNUSED(task);
@@ -2533,14 +2704,14 @@ recvgss(isc_task_t *task, isc_event_t *event) {
servname = dns_fixedname_name(&fname);
isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename));
- result = dns_name_fromtext(servname, &buf, dns_rootname,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL);
check_result(result, "dns_name_fromtext");
tsigkey = NULL;
result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname,
&context, &tsigkey, gssring,
- use_win2k_gsstsig);
+ use_win2k_gsstsig,
+ &err_message);
switch (result) {
case DNS_R_CONTINUE:
@@ -2583,7 +2754,9 @@ recvgss(isc_task_t *task, isc_event_t *event) {
break;
default:
- fatal("dns_tkey_negotiategss: %s", isc_result_totext(result));
+ fatal("dns_tkey_negotiategss: %s %s",
+ isc_result_totext(result),
+ err_message != NULL ? err_message : "");
}
done:
@@ -2693,8 +2866,8 @@ cleanup(void) {
dns_tsigkey_detach(&tsigkey);
}
if (gssring != NULL) {
- ddebug("Destroying GSS-TSIG keyring");
- dns_tsigkeyring_destroy(&gssring);
+ ddebug("Detaching GSS-TSIG keyring");
+ dns_tsigkeyring_detach(&gssring);
}
if (kserver != NULL) {
isc_mem_put(mctx, kserver, sizeof(isc_sockaddr_t));
diff --git a/bin/nsupdate/nsupdate.docbook b/bin/nsupdate/nsupdate.docbook
index 4069a2bb2832..2a92af438dac 100644
--- a/bin/nsupdate/nsupdate.docbook
+++ b/bin/nsupdate/nsupdate.docbook
@@ -18,10 +18,10 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: nsupdate.docbook,v 1.34.48.5 2010-07-09 23:45:50 tbox Exp $ -->
+<!-- $Id: nsupdate.docbook,v 1.44 2010-07-09 23:46:51 tbox Exp $ -->
<refentry id="man.nsupdate">
<refentryinfo>
- <date>Jun 30, 2000</date>
+ <date>Aug 25, 2009</date>
</refentryinfo>
<refmeta>
<refentrytitle><application>nsupdate</application></refentrytitle>
@@ -61,6 +61,7 @@
<group>
<arg><option>-g</option></arg>
<arg><option>-o</option></arg>
+ <arg><option>-l</option></arg>
<arg><option>-y <replaceable class="parameter"><optional>hmac:</optional>keyname:secret</replaceable></option></arg>
<arg><option>-k <replaceable class="parameter">keyfile</replaceable></option></arg>
</group>
@@ -76,7 +77,7 @@
<refsect1>
<title>DESCRIPTION</title>
<para><command>nsupdate</command>
- is used to submit Dynamic DNS Update requests as defined in RFC2136
+ is used to submit Dynamic DNS Update requests as defined in RFC 2136
to a name server.
This allows resource records to be added or removed from a zone
without manually editing the zone file.
@@ -112,10 +113,14 @@
report additional debugging information to <option>-d</option>.
</para>
<para>
+ The <option>-L</option> option with an integer argument of zero or
+ higher sets the logging debug level. If zero, logging is disabled.
+ </para>
+ <para>
Transaction signatures can be used to authenticate the Dynamic
DNS updates. These use the TSIG resource record type described
- in RFC2845 or the SIG(0) record described in RFC3535 and
- RFC2931 or GSS-TSIG as described in RFC3645. TSIG relies on
+ in RFC 2845 or the SIG(0) record described in RFC 2535 and
+ RFC 2931 or GSS-TSIG as described in RFC 3645. TSIG relies on
a shared secret that should only be known to
<command>nsupdate</command> and the name server. Currently,
the only supported encryption algorithm for TSIG is HMAC-MD5,
@@ -132,46 +137,61 @@
record in a zone served by the name server.
<command>nsupdate</command> does not read
<filename>/etc/named.conf</filename>.
- GSS-TSIG uses Kerberos credentials.
+ </para>
+ <para>
+ GSS-TSIG uses Kerberos credentials. Standard GSS-TSIG mode
+ is switched on with the <option>-g</option> flag. A
+ non-standards-compliant variant of GSS-TSIG used by Windows
+ 2000 can be switched on with the <option>-o</option> flag.
</para>
<para><command>nsupdate</command>
uses the <option>-y</option> or <option>-k</option> option
to provide the shared secret needed to generate a TSIG record
for authenticating Dynamic DNS update requests, default type
- HMAC-MD5. These options are mutually exclusive. With the
- <option>-k</option> option, <command>nsupdate</command> reads
- the shared secret from the file <parameter>keyfile</parameter>,
- whose name is of the form
- <filename>K{name}.+157.+{random}.private</filename>. For
- historical reasons, the file
- <filename>K{name}.+157.+{random}.key</filename> must also be
- present. When the <option>-y</option> option is used, a
- signature is generated from
+ HMAC-MD5. These options are mutually exclusive.
+ </para>
+ <para>
+ When the <option>-y</option> option is used, a signature is
+ generated from
<optional><parameter>hmac:</parameter></optional><parameter>keyname:secret.</parameter>
<parameter>keyname</parameter> is the name of the key, and
- <parameter>secret</parameter> is the base64 encoded shared
- secret. Use of the <option>-y</option> option is discouraged
- because the shared secret is supplied as a command line
- argument in clear text. This may be visible in the output
- from
+ <parameter>secret</parameter> is the base64 encoded shared secret.
+ Use of the <option>-y</option> option is discouraged because the
+ shared secret is supplied as a command line argument in clear text.
+ This may be visible in the output from
<citerefentry>
- <refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum>
- </citerefentry> or in a history file maintained by the user's
- shell.
+ <refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry>
+ or in a history file maintained by the user's shell.
</para>
<para>
+ With the
+ <option>-k</option> option, <command>nsupdate</command> reads
+ the shared secret from the file <parameter>keyfile</parameter>.
+ Keyfiles may be in two formats: a single file containing
+ a <filename>named.conf</filename>-format <command>key</command>
+ statement, which may be generated automatically by
+ <command>ddns-confgen</command>, or a pair of files whose names are
+ of the format <filename>K{name}.+157.+{random}.key</filename> and
+ <filename>K{name}.+157.+{random}.private</filename>, which can be
+ generated by <command>dnssec-keygen</command>.
The <option>-k</option> may also be used to specify a SIG(0) key used
to authenticate Dynamic DNS update requests. In this case, the key
specified is not an HMAC-MD5 key.
</para>
<para>
- The <option>-g</option> and <option>-o</option> specify that
- GSS-TSIG is to be used. The <option>-o</option> should only
- be used with old Microsoft Windows 2000 servers.
+ <command>nsupdate</command> can be run in a local-host only mode
+ using the <option>-l</option> flag. This sets the server address to
+ localhost (disabling the <command>server</command> so that the server
+ address cannot be overridden). Connections to the local server will
+ use a TSIG key found in <filename>/var/run/named/session.key</filename>,
+ which is automatically generated by <command>named</command> if any
+ local master zone has set <command>update-policy</command> to
+ <command>local</command>. The location of this key file can be
+ overridden with the <option>-k</option> option.
</para>
<para>
- By default,
- <command>nsupdate</command>
+ By default, <command>nsupdate</command>
uses UDP to send update requests to the name server unless they are too
large to fit in a UDP request in which case TCP will be used.
The
@@ -182,6 +202,10 @@
This may be preferable when a batch of update requests is made.
</para>
<para>
+ The <option>-p</option> sets the default port number to use for
+ connections to a name server. The default is 53.
+ </para>
+ <para>
The <option>-t</option> option sets the maximum time an update request
can
take before it is aborted. The default is 300 seconds. Zero can be
@@ -650,9 +674,9 @@
If there are, the update request fails.
If this name does not exist, a CNAME for it is added.
This ensures that when the CNAME is added, it cannot conflict with the
- long-standing rule in RFC1034 that a name must not exist as any other
+ long-standing rule in RFC 1034 that a name must not exist as any other
record type if it exists as a CNAME.
- (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have
+ (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have
RRSIG, DNSKEY and NSEC records.)
</para>
</refsect1>
@@ -671,6 +695,15 @@
</varlistentry>
<varlistentry>
+ <term><constant>/var/run/named/session.key</constant></term>
+ <listitem>
+ <para>
+ sets the default TSIG key for use in local-only mode
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><constant>K{name}.+157.+{random}.key</constant></term>
<listitem>
<para>
@@ -699,36 +732,26 @@
<refsect1>
<title>SEE ALSO</title>
- <para><citerefentry>
- <refentrytitle>RFC2136</refentrytitle>
- </citerefentry>,
- <citerefentry>
- <refentrytitle>RFC3007</refentrytitle>
- </citerefentry>,
- <citerefentry>
- <refentrytitle>RFC2104</refentrytitle>
- </citerefentry>,
- <citerefentry>
- <refentrytitle>RFC2845</refentrytitle>
- </citerefentry>,
- <citerefentry>
- <refentrytitle>RFC1034</refentrytitle>
- </citerefentry>,
- <citerefentry>
- <refentrytitle>RFC2535</refentrytitle>
- </citerefentry>,
+ <para>
+ <citetitle>RFC 2136</citetitle>,
+ <citetitle>RFC 3007</citetitle>,
+ <citetitle>RFC 2104</citetitle>,
+ <citetitle>RFC 2845</citetitle>,
+ <citetitle>RFC 1034</citetitle>,
+ <citetitle>RFC 2535</citetitle>,
+ <citetitle>RFC 2931</citetitle>,
<citerefentry>
- <refentrytitle>RFC2931</refentrytitle>
+ <refentrytitle>named</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
- <refentrytitle>named</refentrytitle><manvolnum>8</manvolnum>
+ <refentrytitle>ddns-confgen</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>.
</para>
-
</refsect1>
+
<refsect1>
<title>BUGS</title>
<para>
diff --git a/bin/nsupdate/nsupdate.html b/bin/nsupdate/nsupdate.html
index a3836175f562..f48831573e15 100644
--- a/bin/nsupdate/nsupdate.html
+++ b/bin/nsupdate/nsupdate.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: nsupdate.html,v 1.40.48.4 2010-07-10 02:06:17 tbox Exp $ -->
+<!-- $Id: nsupdate.html,v 1.50 2010-07-10 01:14:19 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -29,12 +29,12 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [<code class="option">-D</code>] [[<code class="option">-g</code>] | [<code class="option">-o</code>] | [<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-R <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-v</code>] [filename]</p></div>
+<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [<code class="option">-D</code>] [[<code class="option">-g</code>] | [<code class="option">-o</code>] | [<code class="option">-l</code>] | [<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-R <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-v</code>] [filename]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543452"></a><h2>DESCRIPTION</h2>
+<a name="id2543457"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">nsupdate</strong></span>
- is used to submit Dynamic DNS Update requests as defined in RFC2136
+ is used to submit Dynamic DNS Update requests as defined in RFC 2136
to a name server.
This allows resource records to be added or removed from a zone
without manually editing the zone file.
@@ -70,10 +70,14 @@
report additional debugging information to <code class="option">-d</code>.
</p>
<p>
+ The <code class="option">-L</code> option with an integer argument of zero or
+ higher sets the logging debug level. If zero, logging is disabled.
+ </p>
+<p>
Transaction signatures can be used to authenticate the Dynamic
DNS updates. These use the TSIG resource record type described
- in RFC2845 or the SIG(0) record described in RFC3535 and
- RFC2931 or GSS-TSIG as described in RFC3645. TSIG relies on
+ in RFC 2845 or the SIG(0) record described in RFC 2535 and
+ RFC 2931 or GSS-TSIG as described in RFC 3645. TSIG relies on
a shared secret that should only be known to
<span><strong class="command">nsupdate</strong></span> and the name server. Currently,
the only supported encryption algorithm for TSIG is HMAC-MD5,
@@ -90,44 +94,59 @@
record in a zone served by the name server.
<span><strong class="command">nsupdate</strong></span> does not read
<code class="filename">/etc/named.conf</code>.
- GSS-TSIG uses Kerberos credentials.
+ </p>
+<p>
+ GSS-TSIG uses Kerberos credentials. Standard GSS-TSIG mode
+ is switched on with the <code class="option">-g</code> flag. A
+ non-standards-compliant variant of GSS-TSIG used by Windows
+ 2000 can be switched on with the <code class="option">-o</code> flag.
</p>
<p><span><strong class="command">nsupdate</strong></span>
uses the <code class="option">-y</code> or <code class="option">-k</code> option
to provide the shared secret needed to generate a TSIG record
for authenticating Dynamic DNS update requests, default type
- HMAC-MD5. These options are mutually exclusive. With the
- <code class="option">-k</code> option, <span><strong class="command">nsupdate</strong></span> reads
- the shared secret from the file <em class="parameter"><code>keyfile</code></em>,
- whose name is of the form
- <code class="filename">K{name}.+157.+{random}.private</code>. For
- historical reasons, the file
- <code class="filename">K{name}.+157.+{random}.key</code> must also be
- present. When the <code class="option">-y</code> option is used, a
- signature is generated from
+ HMAC-MD5. These options are mutually exclusive.
+ </p>
+<p>
+ When the <code class="option">-y</code> option is used, a signature is
+ generated from
[<span class="optional"><em class="parameter"><code>hmac:</code></em></span>]<em class="parameter"><code>keyname:secret.</code></em>
<em class="parameter"><code>keyname</code></em> is the name of the key, and
- <em class="parameter"><code>secret</code></em> is the base64 encoded shared
- secret. Use of the <code class="option">-y</code> option is discouraged
- because the shared secret is supplied as a command line
- argument in clear text. This may be visible in the output
- from
- <span class="citerefentry"><span class="refentrytitle">ps</span>(1)</span> or in a history file maintained by the user's
- shell.
+ <em class="parameter"><code>secret</code></em> is the base64 encoded shared secret.
+ Use of the <code class="option">-y</code> option is discouraged because the
+ shared secret is supplied as a command line argument in clear text.
+ This may be visible in the output from
+ <span class="citerefentry"><span class="refentrytitle">ps</span>(1)</span>
+ or in a history file maintained by the user's shell.
</p>
<p>
+ With the
+ <code class="option">-k</code> option, <span><strong class="command">nsupdate</strong></span> reads
+ the shared secret from the file <em class="parameter"><code>keyfile</code></em>.
+ Keyfiles may be in two formats: a single file containing
+ a <code class="filename">named.conf</code>-format <span><strong class="command">key</strong></span>
+ statement, which may be generated automatically by
+ <span><strong class="command">ddns-confgen</strong></span>, or a pair of files whose names are
+ of the format <code class="filename">K{name}.+157.+{random}.key</code> and
+ <code class="filename">K{name}.+157.+{random}.private</code>, which can be
+ generated by <span><strong class="command">dnssec-keygen</strong></span>.
The <code class="option">-k</code> may also be used to specify a SIG(0) key used
to authenticate Dynamic DNS update requests. In this case, the key
specified is not an HMAC-MD5 key.
</p>
<p>
- The <code class="option">-g</code> and <code class="option">-o</code> specify that
- GSS-TSIG is to be used. The <code class="option">-o</code> should only
- be used with old Microsoft Windows 2000 servers.
+ <span><strong class="command">nsupdate</strong></span> can be run in a local-host only mode
+ using the <code class="option">-l</code> flag. This sets the server address to
+ localhost (disabling the <span><strong class="command">server</strong></span> so that the server
+ address cannot be overridden). Connections to the local server will
+ use a TSIG key found in <code class="filename">/var/run/named/session.key</code>,
+ which is automatically generated by <span><strong class="command">named</strong></span> if any
+ local master zone has set <span><strong class="command">update-policy</strong></span> to
+ <span><strong class="command">local</strong></span>. The location of this key file can be
+ overridden with the <code class="option">-k</code> option.
</p>
<p>
- By default,
- <span><strong class="command">nsupdate</strong></span>
+ By default, <span><strong class="command">nsupdate</strong></span>
uses UDP to send update requests to the name server unless they are too
large to fit in a UDP request in which case TCP will be used.
The
@@ -138,6 +157,10 @@
This may be preferable when a batch of update requests is made.
</p>
<p>
+ The <code class="option">-p</code> sets the default port number to use for
+ connections to a name server. The default is 53.
+ </p>
+<p>
The <code class="option">-t</code> option sets the maximum time an update request
can
take before it is aborted. The default is 300 seconds. Zero can be
@@ -169,7 +192,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543730"></a><h2>INPUT FORMAT</h2>
+<a name="id2543788"></a><h2>INPUT FORMAT</h2>
<p><span><strong class="command">nsupdate</strong></span>
reads input from
<em class="parameter"><code>filename</code></em>
@@ -457,7 +480,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544642"></a><h2>EXAMPLES</h2>
+<a name="id2544700"></a><h2>EXAMPLES</h2>
<p>
The examples below show how
<span><strong class="command">nsupdate</strong></span>
@@ -504,19 +527,23 @@
If there are, the update request fails.
If this name does not exist, a CNAME for it is added.
This ensures that when the CNAME is added, it cannot conflict with the
- long-standing rule in RFC1034 that a name must not exist as any other
+ long-standing rule in RFC 1034 that a name must not exist as any other
record type if it exists as a CNAME.
- (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have
+ (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have
RRSIG, DNSKEY and NSEC records.)
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544685"></a><h2>FILES</h2>
+<a name="id2544744"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="constant">/etc/resolv.conf</code></span></dt>
<dd><p>
used to identify default name server
</p></dd>
+<dt><span class="term"><code class="constant">/var/run/named/session.key</code></span></dt>
+<dd><p>
+ sets the default TSIG key for use in local-only mode
+ </p></dd>
<dt><span class="term"><code class="constant">K{name}.+157.+{random}.key</code></span></dt>
<dd><p>
base-64 encoding of HMAC-MD5 key created by
@@ -530,20 +557,22 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544755"></a><h2>SEE ALSO</h2>
-<p><span class="citerefentry"><span class="refentrytitle">RFC2136</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC3007</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC2104</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC2845</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC1034</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC2535</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC2931</span></span>,
+<a name="id2544827"></a><h2>SEE ALSO</h2>
+<p>
+ <em class="citetitle">RFC 2136</em>,
+ <em class="citetitle">RFC 3007</em>,
+ <em class="citetitle">RFC 2104</em>,
+ <em class="citetitle">RFC 2845</em>,
+ <em class="citetitle">RFC 1034</em>,
+ <em class="citetitle">RFC 2535</em>,
+ <em class="citetitle">RFC 2931</em>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
+ <span class="citerefentry"><span class="refentrytitle">ddns-confgen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2542163"></a><h2>BUGS</h2>
+<a name="id2542154"></a><h2>BUGS</h2>
<p>
The TSIG key is redundantly stored in two separate files.
This is a consequence of nsupdate using the DST library
diff --git a/bin/rndc/Makefile.in b/bin/rndc/Makefile.in
index 27d46111a4e5..6c7c56f4abf7 100644
--- a/bin/rndc/Makefile.in
+++ b/bin/rndc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000-2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.44 2007-06-18 23:47:22 tbox Exp $
+# $Id: Makefile.in,v 1.49 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -32,6 +32,7 @@ CWARNINGS =
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCLIBS = ../../lib/isccc/libisccc.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
@@ -41,26 +42,23 @@ ISCDEPLIBS = ../../lib/isc/libisc.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@
-RNDCLIBS = ${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS} ${ISCLIBS} @LIBS@
+LIBS = ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@
+
RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS}
-CONFLIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
-SRCS= rndc.c rndc-confgen.c
-
-SUBDIRS = unix
+SRCS= rndc.c
-TARGETS = rndc@EXEEXT@ rndc-confgen@EXEEXT@
+TARGETS = rndc@EXEEXT@
-MANPAGES = rndc.8 rndc-confgen.8 rndc.conf.5
+MANPAGES = rndc.8 rndc.conf.5
-HTMLPAGES = rndc.html rndc-confgen.html rndc.conf.html
+HTMLPAGES = rndc.html rndc.conf.html
MANOBJS = ${MANPAGES} ${HTMLPAGES}
-UOBJS = unix/os.@O@
-
@BIND9_MAKE_RULES@
rndc.@O@: rndc.c
@@ -70,18 +68,10 @@ rndc.@O@: rndc.c
-DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \
-c ${srcdir}/rndc.c
-rndc-confgen.@O@: rndc-confgen.c
- ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
- -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" \
- -c ${srcdir}/rndc-confgen.c
-
rndc@EXEEXT@: rndc.@O@ util.@O@ ${RNDCDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc.@O@ util.@O@ \
- ${RNDCLIBS}
-
-rndc-confgen@EXEEXT@: rndc-confgen.@O@ util.@O@ ${UOBJS} ${CONFDEPLIBS}
- ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rndc-confgen.@O@ util.@O@ \
- ${UOBJS} ${CONFLIBS}
+ export BASEOBJS="rndc.@O@ util.@O@"; \
+ export LIBS0="${ISCCFGLIBS} ${ISCCCLIBS} ${BIND9LIBS} ${DNSLIBS}"; \
+ ${FINALBUILDCMD}
doc man:: ${MANOBJS}
@@ -93,11 +83,9 @@ installdirs:
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5
-install:: rndc@EXEEXT@ rndc-confgen@EXEEXT@ installdirs
+install:: rndc@EXEEXT@ installdirs
${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc@EXEEXT@ ${DESTDIR}${sbindir}
- ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} rndc-confgen@EXEEXT@ ${DESTDIR}${sbindir}
${INSTALL_DATA} ${srcdir}/rndc.8 ${DESTDIR}${mandir}/man8
- ${INSTALL_DATA} ${srcdir}/rndc-confgen.8 ${DESTDIR}${mandir}/man8
${INSTALL_DATA} ${srcdir}/rndc.conf.5 ${DESTDIR}${mandir}/man5
clean distclean maintainer-clean::
diff --git a/bin/rndc/include/rndc/os.h b/bin/rndc/include/rndc/os.h
index 9f96165d75ac..91986cb0c1dc 100644
--- a/bin/rndc/include/rndc/os.h
+++ b/bin/rndc/include/rndc/os.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.h,v 1.9.332.2 2009-01-18 23:47:35 tbox Exp $ */
+/* $Id: os.h,v 1.12 2009-06-10 00:27:21 each Exp $ */
/*! \file */
@@ -27,12 +27,6 @@
ISC_LANG_BEGINDECLS
-FILE *safe_create(const char *filename);
-/*%<
- * Open 'filename' for writing, truncate if necessary. If the file was
- * created ensure that only the owner can read/write it.
- */
-
int set_user(FILE *fd, const char *user);
/*%<
* Set the owner of the file referenced by 'fd' to 'user'.
diff --git a/bin/rndc/rndc.8 b/bin/rndc/rndc.8
index 285ca9b2eb6e..e4d723bb5197 100644
--- a/bin/rndc/rndc.8
+++ b/bin/rndc/rndc.8
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: rndc.8,v 1.42.214.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: rndc.8,v 1.43 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c
index 133103e3dc73..1976d9ce3322 100644
--- a/bin/rndc/rndc.c
+++ b/bin/rndc/rndc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rndc.c,v 1.122.44.2 2009-01-18 23:47:35 tbox Exp $ */
+/* $Id: rndc.c,v 1.131.20.1.2.1 2011-06-02 23:47:28 tbox Exp $ */
/*! \file */
@@ -79,6 +79,7 @@ static unsigned char databuf[2048];
static isccc_ccmsg_t ccmsg;
static isccc_region_t secret;
static isc_boolean_t failed = ISC_FALSE;
+static isc_boolean_t c_flag = ISC_FALSE;
static isc_mem_t *mctx;
static int sends, recvs, connects;
static char *command;
@@ -89,10 +90,13 @@ static isc_uint32_t serial;
static void rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task);
+ISC_PLATFORM_NORETURN_PRE static void
+usage(int status) ISC_PLATFORM_NORETURN_POST;
+
static void
usage(int status) {
fprintf(stderr, "\
-Usage: %s [-c config] [-s server] [-p port]\n\
+Usage: %s [-b address] [-c config] [-s server] [-p port]\n\
[-k key-file ] [-y key] [-V] command\n\
\n\
command is one of the following:\n\
@@ -113,10 +117,16 @@ command is one of the following:\n\
notify zone [class [view]]\n\
Resend NOTIFY messages for the zone.\n\
reconfig Reload configuration file and new zones only.\n\
+ sign zone [class [view]]\n\
+ Update zone keys, and sign as needed.\n\
+ loadkeys zone [class [view]]\n\
+ Update keys without signing immediately.\n\
stats Write server statistics to the statistics file.\n\
querylog Toggle query logging.\n\
dumpdb [-all|-cache|-zones] [view ...]\n\
Dump cache(s) to the dump file (named_dump.db).\n\
+ secroots [view ...]\n\
+ Write security roots to the secroots file.\n\
stop Save pending updates to master files and stop the server.\n\
stop -p Save pending updates to master files and stop the server\n\
reporting process id.\n\
@@ -135,6 +145,10 @@ command is one of the following:\n\
validation newstate [view]\n\
Enable / disable DNSSEC validation.\n\
*restart Restart the server.\n\
+ addzone [\"file\"] zone [class [view]] { zone-options }\n\
+ Add zone to given view. Requires new-zone-file option.\n\
+ delzone [\"file\"] zone [class [view]]\n\
+ Removes zone from given view. Requires new-zone-file option.\n\
\n\
* == not yet implemented\n\
Version: %s\n",
@@ -455,6 +469,10 @@ parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname,
fatal("neither %s nor %s was found",
admin_conffile, admin_keyfile);
key_only = ISC_TRUE;
+ } else if (! c_flag && isc_file_exists(admin_keyfile)) {
+ fprintf(stderr, "WARNING: key file (%s) exists, but using "
+ "default configuration file (%s)\n",
+ admin_keyfile, admin_conffile);
}
DO("create parser", cfg_parser_create(mctx, log, pctxp));
@@ -709,6 +727,7 @@ main(int argc, char **argv) {
case 'c':
admin_conffile = isc_commandline_argument;
+ c_flag = ISC_TRUE;
break;
case 'k':
diff --git a/bin/rndc/rndc.conf.5 b/bin/rndc/rndc.conf.5
index d7ad81ea99d2..54c4af9c21f8 100644
--- a/bin/rndc/rndc.conf.5
+++ b/bin/rndc/rndc.conf.5
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: rndc.conf.5,v 1.38.366.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: rndc.conf.5,v 1.41 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/bin/rndc/rndc.conf.html b/bin/rndc/rndc.conf.html
index 114cc15983b1..463b99fd2c24 100644
--- a/bin/rndc/rndc.conf.html
+++ b/bin/rndc/rndc.conf.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: rndc.conf.html,v 1.29.366.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: rndc.conf.html,v 1.32 2009-07-11 01:12:46 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/bin/rndc/rndc.html b/bin/rndc/rndc.html
index 0d91784b0ec4..ecc0f318614a 100644
--- a/bin/rndc/rndc.html
+++ b/bin/rndc/rndc.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: rndc.html,v 1.31.214.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: rndc.html,v 1.32 2009-07-11 01:12:46 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/bin/rndc/util.h b/bin/rndc/util.h
index c5da488d96de..8eba61a57ee2 100644
--- a/bin/rndc/util.h
+++ b/bin/rndc/util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: util.h,v 1.10 2007-06-19 23:46:59 tbox Exp $ */
+/* $Id: util.h,v 1.12 2009-09-29 23:48:03 tbox Exp $ */
#ifndef RNDC_UTIL_H
#define RNDC_UTIL_H 1
@@ -23,6 +23,7 @@
/*! \file */
#include <isc/lang.h>
+#include <isc/platform.h>
#include <isc/formatcheck.h>
@@ -43,8 +44,9 @@ ISC_LANG_BEGINDECLS
void
notify(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2);
-void
-fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
+ISC_PLATFORM_NORETURN_PRE void
+fatal(const char *format, ...)
+ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST;
ISC_LANG_ENDDECLS
diff --git a/bin/tools/Makefile.in b/bin/tools/Makefile.in
new file mode 100644
index 000000000000..35b8285715d2
--- /dev/null
+++ b/bin/tools/Makefile.in
@@ -0,0 +1,103 @@
+# Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.13 2010-01-07 23:48:53 tbox Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} \
+ ${LWRES_INCLUDES} ${OMAPI_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
+ISCLIBS = ../../lib/isc/libisc.@A@ @DNS_CRYPTO_LIBS@
+ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@
+ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
+LWRESLIBS = ../../lib/lwres/liblwres.@A@
+
+DNSDEPLIBS = ../../lib/dns/libdns.@A@
+ISCDEPLIBS = ../../lib/isc/libisc.@A@
+ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
+LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
+
+LIBS = ${ISCLIBS} @LIBS@
+NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@
+
+SUBDIRS =
+
+TARGETS = arpaname@EXEEXT@ named-journalprint@EXEEXT@ nsec3hash@EXEEXT@ \
+ genrandom@EXEEXT@ isc-hmac-fixup@EXEEXT@
+SRCS = arpaname.c named-journalprint.c nsec3hash.c genrandom.c \
+ isc-hmac-fixup.c
+
+MANPAGES = arpaname.1 named-journalprint.8 nsec3hash.8 genrandom.8 \
+ isc-hmac-fixup.8
+HTMLPAGES = arpaname.html named-journalprint.html nsec3hash.html \
+ genrandom.html isc-hmac-fixup.html
+MANOBJS = ${MANPAGES} ${HTMLPAGES}
+
+@BIND9_MAKE_RULES@
+
+arpaname@EXEEXT@: arpaname.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ arpaname.@O@ \
+ ${ISCLIBS} ${LIBS}
+
+named-journalprint@EXEEXT@: named-journalprint.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
+ export BASEOBJS="named-journalprint.@O@"; \
+ export LIBS0="${DNSLIBS}"; \
+ ${FINALBUILDCMD}
+
+nsec3hash@EXEEXT@: nsec3hash.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
+ export BASEOBJS="nsec3hash.@O@"; \
+ export LIBS0="${DNSLIBS}"; \
+ ${FINALBUILDCMD}
+
+isc-hmac-fixup@EXEEXT@: isc-hmac-fixup.@O@ ${ISCDEPLIBS}
+ export BASEOBJS="isc-hmac-fixup.@O@"; \
+ export LIBS0="${ISCLIBS}"; \
+ ${FINALBUILDCMD}
+
+genrandom@EXEEXT@: genrandom.@O@
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ genrandom.@O@ @GENRANDOMLIB@ ${LIBS}
+
+doc man:: ${MANOBJS}
+
+docclean manclean maintainer-clean::
+ rm -f ${MANOBJS}
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir}
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man1
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8
+
+install:: ${TARGETS} installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} arpaname@EXEEXT@ ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-journalprint@EXEEXT@ ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} nsec3hash@EXEEXT@ ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} genrandom@EXEEXT@ ${DESTDIR}${sbindir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} isc-hmac-fixup@EXEEXT@ ${DESTDIR}${sbindir}
+ ${INSTALL_DATA} ${srcdir}/arpaname.1 ${DESTDIR}${mandir}/man1
+ ${INSTALL_DATA} ${srcdir}/isc-hmac-fixup.8 ${DESTDIR}${mandir}/man8
+ ${INSTALL_DATA} ${srcdir}/named-journalprint.8 ${DESTDIR}${mandir}/man8
+ ${INSTALL_DATA} ${srcdir}/nsec3hash.8 ${DESTDIR}${mandir}/man8
+ ${INSTALL_DATA} ${srcdir}/genrandom.8 ${DESTDIR}${mandir}/man8
+
+clean distclean::
+ rm -f ${TARGETS}
diff --git a/bin/tools/arpaname.1 b/bin/tools/arpaname.1
new file mode 100644
index 000000000000..66623801814f
--- /dev/null
+++ b/bin/tools/arpaname.1
@@ -0,0 +1,48 @@
+.\" Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: arpaname.1,v 1.4 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: arpaname
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: March 4, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "ARPANAME" "1" "March 4, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+arpaname \- translate IP addresses to the corresponding ARPA names
+.SH "SYNOPSIS"
+.HP 9
+\fBarpaname\fR {\fIipaddress\ \fR...}
+.SH "DESCRIPTION"
+.PP
+\fBarpaname\fR
+translates IP addresses (IPv4 and IPv6) to the corresponding IN\-ADDR.ARPA or IP6.ARPA names.
+.SH "SEE ALSO"
+.PP
+BIND 9 Administrator Reference Manual.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/tools/arpaname.c b/bin/tools/arpaname.c
new file mode 100644
index 000000000000..e7f14345dfd6
--- /dev/null
+++ b/bin/tools/arpaname.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: arpaname.c,v 1.4 2009-10-27 03:05:33 marka Exp $ */
+
+#include "config.h"
+
+#include <isc/net.h>
+
+#include <stdio.h>
+
+#define UNUSED(x) (void)(x)
+
+int
+main(int argc, char *argv[]) {
+ unsigned char buf[16];
+ int i;
+
+ UNUSED(argc);
+
+ while (argv[1]) {
+ if (inet_pton(AF_INET6, argv[1], buf) == 1) {
+ for (i = 15; i >= 0; i--)
+ fprintf(stdout, "%X.%X.", buf[i] & 0xf,
+ (buf[i] >> 4) & 0xf);
+ fprintf(stdout, "IP6.ARPA\n");
+ argv++;
+ continue;
+ }
+ if (inet_pton(AF_INET, argv[1], buf) == 1) {
+ fprintf(stdout, "%u.%u.%u.%u.IN-ADDR.ARPA\n",
+ buf[3], buf[2], buf[1], buf[0]);
+ argv++;
+ continue;
+ }
+ return (1);
+ }
+ fflush(stdout);
+ return(ferror(stdout));
+}
diff --git a/bin/tools/arpaname.docbook b/bin/tools/arpaname.docbook
new file mode 100644
index 000000000000..a7eb79e9c3b6
--- /dev/null
+++ b/bin/tools/arpaname.docbook
@@ -0,0 +1,76 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: arpaname.docbook,v 1.1 2009-03-04 01:30:27 marka Exp $ -->
+<refentry id="man.arpaname">
+ <refentryinfo>
+ <date>March 4, 2009</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>arpaname</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>arpaname</application></refname>
+ <refpurpose>translate IP addresses to the corresponding ARPA names</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2009</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>arpaname</command>
+ <arg choice="req" rep="repeat"><replaceable class="parameter">ipaddress </replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para>
+ <command>arpaname</command> translates IP addresses (IPv4 and
+ IPv6) to the corresponding IN-ADDR.ARPA or IP6.ARPA names.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para>
+ <citetitle>BIND 9 Administrator Reference Manual</citetitle>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>AUTHOR</title>
+ <para><corpauthor>Internet Systems Consortium</corpauthor>
+ </para>
+ </refsect1>
+
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->
diff --git a/bin/tools/arpaname.html b/bin/tools/arpaname.html
new file mode 100644
index 000000000000..e44cfbd782e0
--- /dev/null
+++ b/bin/tools/arpaname.html
@@ -0,0 +1,52 @@
+<!--
+ - Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: arpaname.html,v 1.4 2010-05-19 01:14:14 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>arpaname</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
+<a name="man.arpaname"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">arpaname</span> &#8212; translate IP addresses to the corresponding ARPA names</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">arpaname</code> {<em class="replaceable"><code>ipaddress </code></em>...}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543345"></a><h2>DESCRIPTION</h2>
+<p>
+ <span><strong class="command">arpaname</strong></span> translates IP addresses (IPv4 and
+ IPv6) to the corresponding IN-ADDR.ARPA or IP6.ARPA names.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543357"></a><h2>SEE ALSO</h2>
+<p>
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543371"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div></body>
+</html>
diff --git a/bin/tools/genrandom.8 b/bin/tools/genrandom.8
new file mode 100644
index 000000000000..32a4ff02efb6
--- /dev/null
+++ b/bin/tools/genrandom.8
@@ -0,0 +1,69 @@
+.\" Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: genrandom.8,v 1.8 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: genrandom
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: Feb 19, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "GENRANDOM" "8" "Feb 19, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+genrandom \- generate a file containing random data
+.SH "SYNOPSIS"
+.HP 10
+\fBgenrandom\fR [\fB\-n\ \fR\fB\fInumber\fR\fR] {\fIsize\fR} {\fIfilename\fR}
+.SH "DESCRIPTION"
+.PP
+\fBgenrandom\fR
+generates a file or a set of files containing a specified quantity of pseudo\-random data, which can be used as a source of entropy for other commands on systems with no random device.
+.SH "ARGUMENTS"
+.PP
+\-n \fInumber\fR
+.RS 4
+In place of generating one file, generates
+\fBnumber\fR
+(from 2 to 9) files, appending
+\fBnumber\fR
+to the name.
+.RE
+.PP
+size
+.RS 4
+The size of the file, in kilobytes, to generate.
+.RE
+.PP
+domain
+.RS 4
+The file name into which random data should be written.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBrand\fR(3),
+\fBarc4random\fR(3)
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/tools/genrandom.c b/bin/tools/genrandom.c
new file mode 100644
index 000000000000..8473be259404
--- /dev/null
+++ b/bin/tools/genrandom.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: genrandom.c,v 1.7 2010-05-17 23:51:04 tbox Exp $ */
+
+/*! \file */
+#include <config.h>
+
+#include <isc/commandline.h>
+#include <isc/print.h>
+#include <isc/stdlib.h>
+#include <isc/util.h>
+
+#include <stdio.h>
+#include <string.h>
+
+const char *program = "genrandom";
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "usage: %s [-n 2..9] k file\n", program);
+ exit(1);
+}
+
+static void
+generate(char *filename, unsigned int bytes) {
+ FILE *fp;
+
+ fp = fopen(filename, "w");
+ if (fp == NULL) {
+ printf("failed to open %s\n", filename);
+ exit(1);
+ }
+
+ while (bytes > 0) {
+#ifndef HAVE_ARC4RANDOM
+ unsigned short int x = (rand() & 0xFFFF);
+#else
+ unsigned short int x = (arc4random() & 0xFFFF);
+#endif
+ unsigned char c = x & 0xFF;
+ if (putc(c, fp) == EOF) {
+ printf("error writing to %s\n", filename);
+ exit(1);
+ }
+ c = x >> 8;
+ if (putc(c, fp) == EOF) {
+ printf("error writing to %s\n", filename);
+ exit(1);
+ }
+ bytes -= 2;
+ }
+ fclose(fp);
+}
+
+int
+main(int argc, char **argv) {
+ unsigned int bytes;
+ unsigned int k;
+ char *endp;
+ int c, i, n = 1;
+ size_t len;
+ char *name;
+
+ isc_commandline_errprint = ISC_FALSE;
+
+ while ((c = isc_commandline_parse(argc, argv, "hn:")) != EOF) {
+ switch (c) {
+ case 'n':
+ n = strtol(isc_commandline_argument, &endp, 10);
+ if ((*endp != 0) || (n <= 1) || (n > 9))
+ usage();
+ break;
+
+ case '?':
+ if (isc_commandline_option != '?')
+ fprintf(stderr, "%s: invalid argument -%c\n",
+ program, isc_commandline_option);
+ case 'h':
+ usage();
+
+ default:
+ fprintf(stderr, "%s: unhandled option -%c\n",
+ program, isc_commandline_option);
+ exit(1);
+ }
+ }
+
+ if (isc_commandline_index + 2 != argc)
+ usage();
+
+ k = strtoul(argv[isc_commandline_index++], &endp, 10);
+ if (*endp != 0)
+ usage();
+ bytes = k << 10;
+
+#ifndef HAVE_ARC4RANDOM
+ srand(0x12345678);
+#endif
+ if (n == 1) {
+ generate(argv[isc_commandline_index], bytes);
+ return (0);
+ }
+
+ len = strlen(argv[isc_commandline_index]) + 2;
+ name = (char *) malloc(len);
+ if (name == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+
+ for (i = 1; i <= n; i++) {
+ snprintf(name, len, "%s%d", argv[isc_commandline_index], i);
+ generate(name, bytes);
+ }
+ free(name);
+
+ return (0);
+}
diff --git a/bin/tools/genrandom.docbook b/bin/tools/genrandom.docbook
new file mode 100644
index 000000000000..84e45534a822
--- /dev/null
+++ b/bin/tools/genrandom.docbook
@@ -0,0 +1,119 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: genrandom.docbook,v 1.6 2010-05-17 23:51:05 tbox Exp $ -->
+<refentry id="man.genrandom">
+ <refentryinfo>
+ <date>Feb 19, 2009</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>genrandom</application></refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>genrandom</application></refname>
+ <refpurpose>generate a file containing random data</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2009</year>
+ <year>2010</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>genrandom</command>
+ <arg><option>-n <replaceable class="parameter">number</replaceable></option></arg>
+ <arg choice="req"><replaceable class="parameter">size</replaceable></arg>
+ <arg choice="req"><replaceable class="parameter">filename</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para>
+ <command>genrandom</command>
+ generates a file or a set of files containing a specified quantity
+ of pseudo-random data, which can be used as a source of entropy for
+ other commands on systems with no random device.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>ARGUMENTS</title>
+ <variablelist>
+ <varlistentry>
+ <term>-n <replaceable class="parameter">number</replaceable></term>
+ <listitem>
+ <para>
+ In place of generating one file, generates <option>number</option>
+ (from 2 to 9) files, appending <option>number</option> to the name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>size</term>
+ <listitem>
+ <para>
+ The size of the file, in kilobytes, to generate.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>domain</term>
+ <listitem>
+ <para>
+ The file name into which random data should be written.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>rand</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>arc4random</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>AUTHOR</title>
+ <para><corpauthor>Internet Systems Consortium</corpauthor>
+ </para>
+ </refsect1>
+
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->
diff --git a/bin/tools/genrandom.html b/bin/tools/genrandom.html
new file mode 100644
index 000000000000..c14af9bbd0e0
--- /dev/null
+++ b/bin/tools/genrandom.html
@@ -0,0 +1,73 @@
+<!--
+ - Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: genrandom.html,v 1.8 2010-05-19 01:14:14 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>genrandom</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
+<a name="man.genrandom"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">genrandom</span> &#8212; generate a file containing random data</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">genrandom</code> [<code class="option">-n <em class="replaceable"><code>number</code></em></code>] {<em class="replaceable"><code>size</code></em>} {<em class="replaceable"><code>filename</code></em>}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543363"></a><h2>DESCRIPTION</h2>
+<p>
+ <span><strong class="command">genrandom</strong></span>
+ generates a file or a set of files containing a specified quantity
+ of pseudo-random data, which can be used as a source of entropy for
+ other commands on systems with no random device.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543376"></a><h2>ARGUMENTS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-n <em class="replaceable"><code>number</code></em></span></dt>
+<dd><p>
+ In place of generating one file, generates <code class="option">number</code>
+ (from 2 to 9) files, appending <code class="option">number</code> to the name.
+ </p></dd>
+<dt><span class="term">size</span></dt>
+<dd><p>
+ The size of the file, in kilobytes, to generate.
+ </p></dd>
+<dt><span class="term">domain</span></dt>
+<dd><p>
+ The file name into which random data should be written.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543436"></a><h2>SEE ALSO</h2>
+<p>
+ <span class="citerefentry"><span class="refentrytitle">rand</span>(3)</span>,
+ <span class="citerefentry"><span class="refentrytitle">arc4random</span>(3)</span>
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543463"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div></body>
+</html>
diff --git a/bin/tools/isc-hmac-fixup.8 b/bin/tools/isc-hmac-fixup.8
new file mode 100644
index 000000000000..99c58c8304cf
--- /dev/null
+++ b/bin/tools/isc-hmac-fixup.8
@@ -0,0 +1,61 @@
+.\" Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: isc-hmac-fixup.8,v 1.4 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: isc\-hmac\-fixup
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: January 5, 2010
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "ISC\-HMAC\-FIXUP" "1" "January 5, 2010" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+isc\-hmac\-fixup \- fixes HMAC keys generated by older versions of BIND
+.SH "SYNOPSIS"
+.HP 15
+\fBisc\-hmac\-fixup\fR {\fIalgorithm\fR} {\fIsecret\fR}
+.SH "DESCRIPTION"
+.PP
+Versions of BIND 9 up to and including BIND 9.6 had a bug causing HMAC\-SHA* TSIG keys which were longer than the digest length of the hash algorithm (i.e., SHA1 keys longer than 160 bits, SHA256 keys longer than 256 bits, etc) to be used incorrectly, generating a message authentication code that was incompatible with other DNS implementations.
+.PP
+This bug has been fixed in BIND 9.7. However, the fix may cause incompatibility between older and newer versions of BIND, when using long keys.
+\fBisc\-hmac\-fixup\fR
+modifies those keys to restore compatibility.
+.PP
+To modify a key, run
+\fBisc\-hmac\-fixup\fR
+and specify the key's algorithm and secret on the command line. If the secret is longer than the digest length of the algorithm (64 bytes for SHA1 through SHA256, or 128 bytes for SHA384 and SHA512), then a new secret will be generated consisting of a hash digest of the old secret. (If the secret did not require conversion, then it will be printed without modification.)
+.SH "SECURITY CONSIDERATIONS"
+.PP
+Secrets that have been converted by
+\fBisc\-hmac\-fixup\fR
+are shortened, but as this is how the HMAC protocol works in operation anyway, it does not affect security. RFC 2104 notes, "Keys longer than [the digest length] are acceptable but the extra length would not significantly increase the function strength."
+.SH "SEE ALSO"
+.PP
+BIND 9 Administrator Reference Manual,
+RFC 2104.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2010 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/tools/isc-hmac-fixup.c b/bin/tools/isc-hmac-fixup.c
new file mode 100644
index 000000000000..09cb85deeebc
--- /dev/null
+++ b/bin/tools/isc-hmac-fixup.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: isc-hmac-fixup.c,v 1.4 2010-03-10 02:17:52 marka Exp $ */
+
+#include <config.h>
+
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/md5.h>
+#include <isc/region.h>
+#include <isc/result.h>
+#include <isc/sha1.h>
+#include <isc/sha2.h>
+#include <isc/stdio.h>
+#include <isc/string.h>
+
+#define HMAC_LEN 64
+
+int
+main(int argc, char **argv) {
+ isc_buffer_t buf;
+ unsigned char key[1024];
+ char secret[1024];
+ char base64[(1024*4)/3];
+ isc_region_t r;
+ isc_result_t result;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage:\t%s algorithm secret\n", argv[0]);
+ fprintf(stderr, "\talgorithm: (MD5 | SHA1 | SHA224 | "
+ "SHA256 | SHA384 | SHA512)\n");
+ return (1);
+ }
+
+ isc_buffer_init(&buf, secret, sizeof(secret));
+ result = isc_base64_decodestring(argv[2], &buf);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "error: %s\n", isc_result_totext(result));
+ return (1);
+ }
+ isc__buffer_usedregion(&buf, &r);
+
+ if (!strcasecmp(argv[1], "md5") ||
+ !strcasecmp(argv[1], "hmac-md5")) {
+ if (r.length > HMAC_LEN) {
+ isc_md5_t md5ctx;
+ isc_md5_init(&md5ctx);
+ isc_md5_update(&md5ctx, r.base, r.length);
+ isc_md5_final(&md5ctx, key);
+
+ r.base = key;
+ r.length = ISC_MD5_DIGESTLENGTH;
+ }
+ } else if (!strcasecmp(argv[1], "sha1") ||
+ !strcasecmp(argv[1], "hmac-sha1")) {
+ if (r.length > ISC_SHA1_DIGESTLENGTH) {
+ isc_sha1_t sha1ctx;
+ isc_sha1_init(&sha1ctx);
+ isc_sha1_update(&sha1ctx, r.base, r.length);
+ isc_sha1_final(&sha1ctx, key);
+
+ r.base = key;
+ r.length = ISC_SHA1_DIGESTLENGTH;
+ }
+ } else if (!strcasecmp(argv[1], "sha224") ||
+ !strcasecmp(argv[1], "hmac-sha224")) {
+ if (r.length > ISC_SHA224_DIGESTLENGTH) {
+ isc_sha224_t sha224ctx;
+ isc_sha224_init(&sha224ctx);
+ isc_sha224_update(&sha224ctx, r.base, r.length);
+ isc_sha224_final(key, &sha224ctx);
+
+ r.base = key;
+ r.length = ISC_SHA224_DIGESTLENGTH;
+ }
+ } else if (!strcasecmp(argv[1], "sha256") ||
+ !strcasecmp(argv[1], "hmac-sha256")) {
+ if (r.length > ISC_SHA256_DIGESTLENGTH) {
+ isc_sha256_t sha256ctx;
+ isc_sha256_init(&sha256ctx);
+ isc_sha256_update(&sha256ctx, r.base, r.length);
+ isc_sha256_final(key, &sha256ctx);
+
+ r.base = key;
+ r.length = ISC_SHA256_DIGESTLENGTH;
+ }
+ } else if (!strcasecmp(argv[1], "sha384") ||
+ !strcasecmp(argv[1], "hmac-sha384")) {
+ if (r.length > ISC_SHA384_DIGESTLENGTH) {
+ isc_sha384_t sha384ctx;
+ isc_sha384_init(&sha384ctx);
+ isc_sha384_update(&sha384ctx, r.base, r.length);
+ isc_sha384_final(key, &sha384ctx);
+
+ r.base = key;
+ r.length = ISC_SHA384_DIGESTLENGTH;
+ }
+ } else if (!strcasecmp(argv[1], "sha512") ||
+ !strcasecmp(argv[1], "hmac-sha512")) {
+ if (r.length > ISC_SHA512_DIGESTLENGTH) {
+ isc_sha512_t sha512ctx;
+ isc_sha512_init(&sha512ctx);
+ isc_sha512_update(&sha512ctx, r.base, r.length);
+ isc_sha512_final(key, &sha512ctx);
+
+ r.base = key;
+ r.length = ISC_SHA512_DIGESTLENGTH;
+ }
+ } else {
+ fprintf(stderr, "unknown hmac/digest algorithm: %s\n", argv[1]);
+ return (1);
+ }
+
+ isc_buffer_init(&buf, base64, sizeof(base64));
+ result = isc_base64_totext(&r, 0, "", &buf);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "error: %s\n", isc_result_totext(result));
+ return (1);
+ }
+ fprintf(stdout, "%.*s\n", (int)isc_buffer_usedlength(&buf), base64);
+ return (0);
+}
diff --git a/bin/tools/isc-hmac-fixup.docbook b/bin/tools/isc-hmac-fixup.docbook
new file mode 100644
index 000000000000..a3039ee814d9
--- /dev/null
+++ b/bin/tools/isc-hmac-fixup.docbook
@@ -0,0 +1,109 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: isc-hmac-fixup.docbook,v 1.2 2010-01-07 21:52:11 each Exp $ -->
+<refentry id="man.isc-hmac-fixup">
+ <refentryinfo>
+ <date>January 5, 2010</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>isc-hmac-fixup</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>isc-hmac-fixup</application></refname>
+ <refpurpose>fixes HMAC keys generated by older versions of BIND</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2010</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>isc-hmac-fixup</command>
+ <arg choice="req"><replaceable class="parameter">algorithm</replaceable></arg>
+ <arg choice="req"><replaceable class="parameter">secret</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para>
+ Versions of BIND 9 up to and including BIND 9.6 had a bug causing
+ HMAC-SHA* TSIG keys which were longer than the digest length of the
+ hash algorithm (i.e., SHA1 keys longer than 160 bits, SHA256 keys
+ longer than 256 bits, etc) to be used incorrectly, generating a
+ message authentication code that was incompatible with other DNS
+ implementations.
+ </para>
+ <para>
+ This bug has been fixed in BIND 9.7. However, the fix may
+ cause incompatibility between older and newer versions of
+ BIND, when using long keys. <command>isc-hmac-fixup</command>
+ modifies those keys to restore compatibility.
+ </para>
+ <para>
+ To modify a key, run <command>isc-hmac-fixup</command> and
+ specify the key's algorithm and secret on the command line. If the
+ secret is longer than the digest length of the algorithm (64 bytes
+ for SHA1 through SHA256, or 128 bytes for SHA384 and SHA512), then a
+ new secret will be generated consisting of a hash digest of the old
+ secret. (If the secret did not require conversion, then it will be
+ printed without modification.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>SECURITY CONSIDERATIONS</title>
+ <para>
+ Secrets that have been converted by <command>isc-hmac-fixup</command>
+ are shortened, but as this is how the HMAC protocol works in
+ operation anyway, it does not affect security. RFC 2104 notes,
+ "Keys longer than [the digest length] are acceptable but the
+ extra length would not significantly increase the function
+ strength."
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para>
+ <citetitle>BIND 9 Administrator Reference Manual</citetitle>,
+ <citetitle>RFC 2104</citetitle>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>AUTHOR</title>
+ <para><corpauthor>Internet Systems Consortium</corpauthor>
+ </para>
+ </refsect1>
+
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->
diff --git a/bin/tools/isc-hmac-fixup.html b/bin/tools/isc-hmac-fixup.html
new file mode 100644
index 000000000000..8b70777cd792
--- /dev/null
+++ b/bin/tools/isc-hmac-fixup.html
@@ -0,0 +1,83 @@
+<!--
+ - Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: isc-hmac-fixup.html,v 1.4 2010-05-19 01:14:14 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>isc-hmac-fixup</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
+<a name="man.isc-hmac-fixup"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">isc-hmac-fixup</span> &#8212; fixes HMAC keys generated by older versions of BIND</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">isc-hmac-fixup</code> {<em class="replaceable"><code>algorithm</code></em>} {<em class="replaceable"><code>secret</code></em>}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543351"></a><h2>DESCRIPTION</h2>
+<p>
+ Versions of BIND 9 up to and including BIND 9.6 had a bug causing
+ HMAC-SHA* TSIG keys which were longer than the digest length of the
+ hash algorithm (i.e., SHA1 keys longer than 160 bits, SHA256 keys
+ longer than 256 bits, etc) to be used incorrectly, generating a
+ message authentication code that was incompatible with other DNS
+ implementations.
+ </p>
+<p>
+ This bug has been fixed in BIND 9.7. However, the fix may
+ cause incompatibility between older and newer versions of
+ BIND, when using long keys. <span><strong class="command">isc-hmac-fixup</strong></span>
+ modifies those keys to restore compatibility.
+ </p>
+<p>
+ To modify a key, run <span><strong class="command">isc-hmac-fixup</strong></span> and
+ specify the key's algorithm and secret on the command line. If the
+ secret is longer than the digest length of the algorithm (64 bytes
+ for SHA1 through SHA256, or 128 bytes for SHA384 and SHA512), then a
+ new secret will be generated consisting of a hash digest of the old
+ secret. (If the secret did not require conversion, then it will be
+ printed without modification.)
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543374"></a><h2>SECURITY CONSIDERATIONS</h2>
+<p>
+ Secrets that have been converted by <span><strong class="command">isc-hmac-fixup</strong></span>
+ are shortened, but as this is how the HMAC protocol works in
+ operation anyway, it does not affect security. RFC 2104 notes,
+ "Keys longer than [the digest length] are acceptable but the
+ extra length would not significantly increase the function
+ strength."
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543388"></a><h2>SEE ALSO</h2>
+<p>
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>,
+ <em class="citetitle">RFC 2104</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543405"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div></body>
+</html>
diff --git a/bin/tools/named-journalprint.8 b/bin/tools/named-journalprint.8
new file mode 100644
index 000000000000..347b67b1bacd
--- /dev/null
+++ b/bin/tools/named-journalprint.8
@@ -0,0 +1,60 @@
+.\" Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-journalprint.8,v 1.4 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: named\-journalprint
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: Feb 18, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "NAMED\-JOURNALPRINT" "8" "Feb 18, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+named\-journalprint \- print zone journal in human\-readable form
+.SH "SYNOPSIS"
+.HP 19
+\fBnamed\-journalprint\fR {\fIjournal\fR}
+.SH "DESCRIPTION"
+.PP
+\fBnamed\-journalprint\fR
+prints the contents of a zone journal file in a human\-readable form.
+.PP
+Journal files are automatically created by
+\fBnamed\fR
+when changes are made to dynamic zones (e.g., by
+\fBnsupdate\fR). They record each addition or deletion of a resource record, in binary format, allowing the changes to be re\-applied to the zone when the server is restarted after a shutdown or crash. By default, the name of the journal file is formed by appending the extension
+\fI.jnl\fR
+to the name of the corresponding zone file.
+.PP
+\fBnamed\-journalprint\fR
+converts the contents of a given journal file into a human\-readable text format. Each line begins with "add" or "del", to indicate whether the record was added or deleted, and continues with the resource record in master\-file format.
+.SH "SEE ALSO"
+.PP
+\fBnamed\fR(8),
+\fBnsupdate\fR(8),
+BIND 9 Administrator Reference Manual.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/tools/named-journalprint.c b/bin/tools/named-journalprint.c
new file mode 100644
index 000000000000..8a00aa7a85d9
--- /dev/null
+++ b/bin/tools/named-journalprint.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: named-journalprint.c,v 1.2 2009-12-04 21:59:23 marka Exp $ */
+
+/*! \file */
+#include <config.h>
+
+#include <isc/log.h>
+#include <isc/mem.h>
+#include <isc/util.h>
+
+#include <dns/journal.h>
+#include <dns/log.h>
+#include <dns/result.h>
+#include <dns/types.h>
+
+#include <stdlib.h>
+
+/*
+ * Setup logging to use stderr.
+ */
+static isc_result_t
+setup_logging(isc_mem_t *mctx, FILE *errout, 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);
+ dns_log_init(log);
+ dns_log_setcontext(log);
+
+ destination.file.stream = errout;
+ 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);
+}
+
+int
+main(int argc, char **argv) {
+ char *file;
+ isc_mem_t *mctx = NULL;
+ isc_result_t result;
+ isc_log_t *lctx = NULL;
+
+ if (argc != 2) {
+ printf("usage: %s journal\n", argv[0]);
+ return(1);
+ }
+
+ file = argv[1];
+
+ RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
+ RUNTIME_CHECK(setup_logging(mctx, stderr, &lctx) == ISC_R_SUCCESS);
+
+ result = dns_journal_print(mctx, file, stdout);
+ if (result == DNS_R_NOJOURNAL)
+ fprintf(stderr, "%s\n", dns_result_totext(result));
+ isc_log_destroy(&lctx);
+ isc_mem_detach(&mctx);
+ return(result != ISC_R_SUCCESS ? 1 : 0);
+}
diff --git a/bin/tools/named-journalprint.docbook b/bin/tools/named-journalprint.docbook
new file mode 100644
index 000000000000..d523f8c1aff2
--- /dev/null
+++ b/bin/tools/named-journalprint.docbook
@@ -0,0 +1,101 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-journalprint.docbook,v 1.2 2009-12-04 21:59:23 marka Exp $ -->
+<refentry id="man.named-journalprint">
+ <refentryinfo>
+ <date>Feb 18, 2009</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>named-journalprint</application></refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>named-journalprint</application></refname>
+ <refpurpose>print zone journal in human-readable form</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2009</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>named-journalprint</command>
+ <arg choice="req"><replaceable class="parameter">journal</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para>
+ <command>named-journalprint</command>
+ prints the contents of a zone journal file in a human-readable
+ form.
+ </para>
+ <para>
+ Journal files are automatically created by <command>named</command>
+ when changes are made to dynamic zones (e.g., by
+ <command>nsupdate</command>). They record each addition
+ or deletion of a resource record, in binary format, allowing the
+ changes to be re-applied to the zone when the server is
+ restarted after a shutdown or crash. By default, the name of
+ the journal file is formed by appending the extension
+ <filename>.jnl</filename> to the name of the corresponding
+ zone file.
+ </para>
+ <para>
+ <command>named-journalprint</command> converts the contents of a given
+ journal file into a human-readable text format. Each line begins
+ with "add" or "del", to indicate whether the record was added or
+ deleted, and continues with the resource record in master-file
+ format.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>named</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>nsupdate</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citetitle>BIND 9 Administrator Reference Manual</citetitle>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>AUTHOR</title>
+ <para><corpauthor>Internet Systems Consortium</corpauthor>
+ </para>
+ </refsect1>
+
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->
diff --git a/bin/tools/named-journalprint.html b/bin/tools/named-journalprint.html
new file mode 100644
index 000000000000..8878fc506555
--- /dev/null
+++ b/bin/tools/named-journalprint.html
@@ -0,0 +1,73 @@
+<!--
+ - Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-journalprint.html,v 1.4 2010-05-19 01:14:14 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>named-journalprint</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
+<a name="man.named-journalprint"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">named-journalprint</span> &#8212; print zone journal in human-readable form</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">named-journalprint</code> {<em class="replaceable"><code>journal</code></em>}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543342"></a><h2>DESCRIPTION</h2>
+<p>
+ <span><strong class="command">named-journalprint</strong></span>
+ prints the contents of a zone journal file in a human-readable
+ form.
+ </p>
+<p>
+ Journal files are automatically created by <span><strong class="command">named</strong></span>
+ when changes are made to dynamic zones (e.g., by
+ <span><strong class="command">nsupdate</strong></span>). They record each addition
+ or deletion of a resource record, in binary format, allowing the
+ changes to be re-applied to the zone when the server is
+ restarted after a shutdown or crash. By default, the name of
+ the journal file is formed by appending the extension
+ <code class="filename">.jnl</code> to the name of the corresponding
+ zone file.
+ </p>
+<p>
+ <span><strong class="command">named-journalprint</strong></span> converts the contents of a given
+ journal file into a human-readable text format. Each line begins
+ with "add" or "del", to indicate whether the record was added or
+ deleted, and continues with the resource record in master-file
+ format.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543378"></a><h2>SEE ALSO</h2>
+<p>
+ <span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
+ <span class="citerefentry"><span class="refentrytitle">nsupdate</span>(8)</span>,
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543409"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div></body>
+</html>
diff --git a/bin/tools/nsec3hash.8 b/bin/tools/nsec3hash.8
new file mode 100644
index 000000000000..6fba8c886cf9
--- /dev/null
+++ b/bin/tools/nsec3hash.8
@@ -0,0 +1,70 @@
+.\" Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+.\"
+.\" Permission to use, copy, modify, and/or distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $Id: nsec3hash.8,v 1.5 2010-05-19 01:14:14 tbox Exp $
+.\"
+.hy 0
+.ad l
+.\" Title: nsec3hash
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
+.\" Date: Feb 18, 2009
+.\" Manual: BIND9
+.\" Source: BIND9
+.\"
+.TH "NSEC3HASH" "8" "Feb 18, 2009" "BIND9" "BIND9"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+nsec3hash \- generate NSEC3 hash
+.SH "SYNOPSIS"
+.HP 10
+\fBnsec3hash\fR {\fIsalt\fR} {\fIalgorithm\fR} {\fIiterations\fR} {\fIdomain\fR}
+.SH "DESCRIPTION"
+.PP
+\fBnsec3hash\fR
+generates an NSEC3 hash based on a set of NSEC3 parameters. This can be used to check the validity of NSEC3 records in a signed zone.
+.SH "ARGUMENTS"
+.PP
+salt
+.RS 4
+The salt provided to the hash algorithm.
+.RE
+.PP
+algorithm
+.RS 4
+A number indicating the hash algorithm. Currently the only supported hash algorithm for NSEC3 is SHA\-1, which is indicated by the number 1; consequently "1" is the only useful value for this argument.
+.RE
+.PP
+iterations
+.RS 4
+The number of additional times the hash should be performed.
+.RE
+.PP
+domain
+.RS 4
+The domain name to be hashed.
+.RE
+.SH "SEE ALSO"
+.PP
+BIND 9 Administrator Reference Manual,
+RFC 5155.
+.SH "AUTHOR"
+.PP
+Internet Systems Consortium
+.SH "COPYRIGHT"
+Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC")
+.br
diff --git a/bin/tools/nsec3hash.c b/bin/tools/nsec3hash.c
new file mode 100644
index 000000000000..0e2a910c9150
--- /dev/null
+++ b/bin/tools/nsec3hash.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2006, 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: nsec3hash.c,v 1.6 2009-10-06 21:20:44 each Exp $ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <isc/base32.h>
+#include <isc/buffer.h>
+#include <isc/hex.h>
+#include <isc/iterated_hash.h>
+#include <isc/print.h>
+#include <isc/result.h>
+#include <isc/string.h>
+#include <isc/types.h>
+
+#include <dns/fixedname.h>
+#include <dns/name.h>
+#include <dns/nsec3.h>
+#include <dns/types.h>
+
+const char *program = "nsec3hash";
+
+ISC_PLATFORM_NORETURN_PRE static void
+fatal(const char *format, ...) ISC_PLATFORM_NORETURN_POST;
+
+static 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");
+ exit(1);
+}
+
+static void
+check_result(isc_result_t result, const char *message) {
+ if (result != ISC_R_SUCCESS)
+ fatal("%s: %s", message, isc_result_totext(result));
+}
+
+static void
+usage() {
+ fatal("salt hash iterations domain");
+}
+
+int
+main(int argc, char **argv) {
+ dns_fixedname_t fixed;
+ dns_name_t *name;
+ isc_buffer_t buffer;
+ isc_region_t region;
+ isc_result_t result;
+ unsigned char hash[NSEC3_MAX_HASH_LENGTH];
+ unsigned char salt[DNS_NSEC3_SALTSIZE];
+ unsigned char text[1024];
+ unsigned int hash_alg;
+ unsigned int length;
+ unsigned int iterations;
+ unsigned int salt_length;
+
+ if (argc != 5)
+ usage();
+
+ if (strcmp(argv[1], "-") == 0) {
+ salt_length = 0;
+ salt[0] = 0;
+ } else {
+ isc_buffer_init(&buffer, salt, sizeof(salt));
+ result = isc_hex_decodestring(argv[1], &buffer);
+ check_result(result, "isc_hex_decodestring(salt)");
+ salt_length = isc_buffer_usedlength(&buffer);
+ if (salt_length > DNS_NSEC3_SALTSIZE)
+ fatal("salt too long");
+ }
+ hash_alg = atoi(argv[2]);
+ if (hash_alg > 255U)
+ fatal("hash algorithm too large");
+ iterations = atoi(argv[3]);
+ if (iterations > 0xffffU)
+ fatal("iterations to large");
+
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+ isc_buffer_init(&buffer, argv[4], strlen(argv[4]));
+ isc_buffer_add(&buffer, strlen(argv[4]));
+ result = dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL);
+ check_result(result, "dns_name_fromtext() failed");
+
+ dns_name_downcase(name, name, NULL);
+ length = isc_iterated_hash(hash, hash_alg, iterations, salt,
+ salt_length, name->ndata, name->length);
+ if (length == 0)
+ fatal("isc_iterated_hash failed");
+ region.base = hash;
+ region.length = length;
+ isc_buffer_init(&buffer, text, sizeof(text));
+ isc_base32hex_totext(&region, 1, "", &buffer);
+ fprintf(stdout, "%.*s (salt=%s, hash=%u, iterations=%u)\n",
+ (int)isc_buffer_usedlength(&buffer), text, argv[1], hash_alg, iterations);
+ return(0);
+}
diff --git a/bin/tools/nsec3hash.docbook b/bin/tools/nsec3hash.docbook
new file mode 100644
index 000000000000..48eb4afb41ca
--- /dev/null
+++ b/bin/tools/nsec3hash.docbook
@@ -0,0 +1,125 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: nsec3hash.docbook,v 1.3 2009-03-02 23:47:43 tbox Exp $ -->
+<refentry id="man.nsec3hash">
+ <refentryinfo>
+ <date>Feb 18, 2009</date>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle><application>nsec3hash</application></refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>nsec3hash</application></refname>
+ <refpurpose>generate NSEC3 hash</refpurpose>
+ </refnamediv>
+
+ <docinfo>
+ <copyright>
+ <year>2009</year>
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+ </copyright>
+ </docinfo>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>nsec3hash</command>
+ <arg choice="req"><replaceable class="parameter">salt</replaceable></arg>
+ <arg choice="req"><replaceable class="parameter">algorithm</replaceable></arg>
+ <arg choice="req"><replaceable class="parameter">iterations</replaceable></arg>
+ <arg choice="req"><replaceable class="parameter">domain</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para>
+ <command>nsec3hash</command> generates an NSEC3 hash based on
+ a set of NSEC3 parameters. This can be used to check the validity
+ of NSEC3 records in a signed zone.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>ARGUMENTS</title>
+ <variablelist>
+ <varlistentry>
+ <term>salt</term>
+ <listitem>
+ <para>
+ The salt provided to the hash algorithm.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>algorithm</term>
+ <listitem>
+ <para>
+ A number indicating the hash algorithm. Currently the
+ only supported hash algorithm for NSEC3 is SHA-1, which is
+ indicated by the number 1; consequently "1" is the only
+ useful value for this argument.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>iterations</term>
+ <listitem>
+ <para>
+ The number of additional times the hash should be performed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>domain</term>
+ <listitem>
+ <para>
+ The domain name to be hashed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para>
+ <citetitle>BIND 9 Administrator Reference Manual</citetitle>,
+ <citetitle>RFC 5155</citetitle>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>AUTHOR</title>
+ <para><corpauthor>Internet Systems Consortium</corpauthor>
+ </para>
+ </refsect1>
+
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->
diff --git a/bin/tools/nsec3hash.html b/bin/tools/nsec3hash.html
new file mode 100644
index 000000000000..e6c09959f153
--- /dev/null
+++ b/bin/tools/nsec3hash.html
@@ -0,0 +1,78 @@
+<!--
+ - Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: nsec3hash.html,v 1.5 2010-05-19 01:14:14 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>nsec3hash</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
+<a name="man.nsec3hash"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">nsec3hash</span> &#8212; generate NSEC3 hash</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">nsec3hash</code> {<em class="replaceable"><code>salt</code></em>} {<em class="replaceable"><code>algorithm</code></em>} {<em class="replaceable"><code>iterations</code></em>} {<em class="replaceable"><code>domain</code></em>}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543367"></a><h2>DESCRIPTION</h2>
+<p>
+ <span><strong class="command">nsec3hash</strong></span> generates an NSEC3 hash based on
+ a set of NSEC3 parameters. This can be used to check the validity
+ of NSEC3 records in a signed zone.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543380"></a><h2>ARGUMENTS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">salt</span></dt>
+<dd><p>
+ The salt provided to the hash algorithm.
+ </p></dd>
+<dt><span class="term">algorithm</span></dt>
+<dd><p>
+ A number indicating the hash algorithm. Currently the
+ only supported hash algorithm for NSEC3 is SHA-1, which is
+ indicated by the number 1; consequently "1" is the only
+ useful value for this argument.
+ </p></dd>
+<dt><span class="term">iterations</span></dt>
+<dd><p>
+ The number of additional times the hash should be performed.
+ </p></dd>
+<dt><span class="term">domain</span></dt>
+<dd><p>
+ The domain name to be hashed.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543442"></a><h2>SEE ALSO</h2>
+<p>
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>,
+ <em class="citetitle">RFC 5155</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2543459"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div></body>
+</html>
diff --git a/config.guess b/config.guess
index c79aebcb5668..f8d6eac4e842 100644
--- a/config.guess
+++ b/config.guess
@@ -3,7 +3,7 @@
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-timestamp='2004-09-07'
+timestamp='2009-01-17'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
diff --git a/config.h.in b/config.h.in
index aa1ba81a248b..01f8b166acb2 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,6 +1,6 @@
/* config.h.in. Generated from configure.in by autoheader. */
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,7 +16,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: config.h.in,v 1.106.40.24 2010-12-21 04:33:58 marka Exp $ */
+/* $Id: config.h.in,v 1.143.8.1 2011-02-03 05:52:35 marka Exp $ */
/*! \file */
@@ -147,6 +147,9 @@ int sigwait(const unsigned int *set, int *sig);
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
+/* Define to enable the "filter-aaaa-on-v4" option. */
+#undef ALLOW_FILTER_AAAA_ON_V4
+
/* Define if recvmsg() does not meet all of the BSD socket API specifications.
*/
#undef BROKEN_RECVMSG
@@ -157,6 +160,12 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to enable "rrset-order fixed" syntax. */
#undef DNS_RDATASET_FIXED
+/* Define to enable rpz-nsdname rules. */
+#undef ENABLE_RPZ_NSDNAME
+
+/* Define to enable rpz-nsip rules. */
+#undef ENABLE_RPZ_NSIP
+
/* Solaris hack to get select_large_fdset. */
#undef FD_SETSIZE
@@ -175,9 +184,18 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the <devpoll.h> header file. */
#undef HAVE_DEVPOLL_H
+/* Define to 1 if you have the `dlclose' function. */
+#undef HAVE_DLCLOSE
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
+/* Define to 1 if you have the `dlopen' function. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the `dlsym' function. */
+#undef HAVE_DLSYM
+
/* Define to 1 if you have the `EVP_sha256' function. */
#undef HAVE_EVP_SHA256
@@ -190,9 +208,15 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
#undef HAVE_GSSAPI_GSSAPI_H
+/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
+#undef HAVE_GSSAPI_GSSAPI_KRB5_H
+
/* Define to 1 if you have the <gssapi.h> header file. */
#undef HAVE_GSSAPI_H
+/* Define to 1 if you have the <gssapi_krb5.h> header file. */
+#undef HAVE_GSSAPI_KRB5_H
+
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@@ -211,9 +235,15 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the `cap' library (-lcap). */
#undef HAVE_LIBCAP
+/* if system have backtrace function */
+#undef HAVE_LIBCTRACE
+
/* Define to 1 if you have the `c_r' library (-lc_r). */
#undef HAVE_LIBC_R
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
@@ -247,9 +277,27 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the <net/if6.h> header file. */
#undef HAVE_NET_IF6_H
+/* Define if your OpenSSL version supports GOST. */
+#undef HAVE_OPENSSL_GOST
+
+/* Define to 1 if you have the <regex.h> header file. */
+#undef HAVE_REGEX_H
+
+/* Define to 1 if you have the `setegid' function. */
+#undef HAVE_SETEGID
+
+/* Define to 1 if you have the `seteuid' function. */
+#undef HAVE_SETEUID
+
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE
+/* Define to 1 if you have the `setresgid' function. */
+#undef HAVE_SETRESGID
+
+/* Define to 1 if you have the `setresuid' function. */
+#undef HAVE_SETRESUID
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
@@ -304,6 +352,15 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* return type of gai_strerror */
+#undef IRS_GAISTRERROR_RETURN_T
+
+/* Define to the buffer length type used by getnameinfo(3). */
+#undef IRS_GETNAMEINFO_BUFLEN_T
+
+/* Define to the flags type used by getnameinfo(3). */
+#undef IRS_GETNAMEINFO_FLAGS_T
+
/* Defined if extern char *optarg is not declared. */
#undef NEED_OPTARG
@@ -361,11 +418,8 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
+/* Define to empty if your compiler does not support "static inline". */
#undef inline
-#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
diff --git a/configure.in b/configure.in
index 08f0bf33dc7a..d5fb15cfb909 100644
--- a/configure.in
+++ b/configure.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl
-AC_REVISION($Revision: 1.457.26.28 $)
+AC_REVISION($Revision: 1.512.8.1 $)
AC_INIT(lib/dns/name.c)
AC_PREREQ(2.59)
@@ -36,6 +36,7 @@ case $build_os in
sunos*)
# Just set the maximum command line length for sunos as it otherwise
# takes a exceptionally long time to work it out. Required for libtool.
+
lt_cv_sys_max_cmd_len=4096;
;;
esac
@@ -61,7 +62,6 @@ It is available from http://www.isc.org as a separate download.])
;;
esac
-
#
# Make very sure that these are the first files processed by
# config.status, since we use the processed output as the input for
@@ -111,6 +111,8 @@ AC_SUBST(ETAGS)
#
# Perl is optional; it is used only by some of the system test scripts.
+# Note: the backtrace feature (see below) uses perl to build the symbol table,
+# but it still compiles without perl, in which case an empty table will be used.
#
AC_PATH_PROGS(PERL, perl5 perl)
AC_SUBST(PERL)
@@ -269,7 +271,7 @@ esac
AC_HEADER_STDC
-AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,,
+AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,,
[$ac_includes_default
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
@@ -283,6 +285,12 @@ AC_CHECK_FUNC(sysctlbyname, AC_DEFINE(HAVE_SYSCTLBYNAME))
AC_C_FLEXIBLE_ARRAY_MEMBER
#
+# Older versions of HP/UX don't define seteuid() and setegid()
+#
+AC_CHECK_FUNCS(seteuid setresuid)
+AC_CHECK_FUNCS(setegid setresgid)
+
+#
# UnixWare 7.1.1 with the feature supplement to the UDK compiler
# is reported to not support "static inline" (RT #1212).
#
@@ -300,7 +308,7 @@ AC_TRY_COMPILE(, [
],
[AC_MSG_RESULT(no)],
[AC_MSG_RESULT(yes)
- AC_DEFINE(inline, )])
+ AC_DEFINE(inline, ,[Define to empty if your compiler does not support "static inline".])])
AC_TYPE_SIZE_T
AC_CHECK_TYPE(ssize_t, int)
@@ -332,6 +340,20 @@ AC_TRY_COMPILE([],[long long i = 0; return (0);],
AC_SUBST(ISC_PLATFORM_HAVELONGLONG)
#
+# check for GCC noreturn attribute
+#
+AC_MSG_CHECKING(for GCC noreturn attribute)
+AC_TRY_COMPILE([],[void foo() __attribute__((noreturn));],
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_NORETURN_PRE="#define ISC_PLATFORM_NORETURN_PRE"
+ ISC_PLATFORM_NORETURN_POST="#define ISC_PLATFORM_NORETURN_POST __attribute__((noreturn))"],
+ [AC_MSG_RESULT(no)
+ ISC_PLATFORM_NORETURN_PRE="#define ISC_PLATFORM_NORETURN_PRE"
+ ISC_PLATFORM_NORETURN_POST="#define ISC_PLATFORM_NORETURN_POST"])
+AC_SUBST(ISC_PLATFORM_NORETURN_PRE)
+AC_SUBST(ISC_PLATFORM_NORETURN_POST)
+
+#
# check if we have lifconf
#
AC_MSG_CHECKING(for struct lifconf)
@@ -495,6 +517,7 @@ then
fi
done
fi
+OPENSSL_GOST=""
case "$use_openssl" in
no)
AC_MSG_RESULT(no)
@@ -650,6 +673,42 @@ esac
AC_MSG_RESULT(no)
fi
AC_CHECK_FUNCS(EVP_sha256 EVP_sha512)
+
+ AC_MSG_CHECKING(for OpenSSL GOST support)
+ have_gost=""
+ AC_TRY_RUN([
+#include <openssl/conf.h>
+#include <openssl/engine.h>
+int main() {
+#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
+ ENGINE *e;
+
+ OPENSSL_config(NULL);
+
+ e = ENGINE_by_id("gost");
+ if (e == NULL)
+ return (1);
+ if (ENGINE_init(e) <= 0)
+ return (1);
+ return (0);
+#else
+ return (1);
+#endif
+}
+],
+ [AC_MSG_RESULT(yes)
+ have_gost="yes"],
+ [AC_MSG_RESULT(no)
+ have_gost="no"])
+ case $have_gost in
+ yes)
+ OPENSSL_GOST="yes"
+ AC_DEFINE(HAVE_OPENSSL_GOST, 1,
+ [Define if your OpenSSL version supports GOST.])
+ ;;
+ *)
+ ;;
+ esac
CFLAGS="$saved_cflags"
LIBS="$saved_libs"
OPENSSLLINKOBJS='${OPENSSLLINKOBJS}'
@@ -667,9 +726,34 @@ AC_SUBST(USE_OPENSSL)
AC_SUBST(DST_OPENSSL_INC)
AC_SUBST(OPENSSLLINKOBJS)
AC_SUBST(OPENSSLLINKSRCS)
+AC_SUBST(OPENSSL_GOST)
DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS"
#
+# Use OpenSSL for hash functions
+#
+
+AC_ARG_ENABLE(openssl-hash,
+ [ --enable-openssl-hash use OpenSSL for hash functions [[default=no]]],
+ want_openssl_hash="$enableval", want_openssl_hash="no")
+case $want_openssl_hash in
+ yes)
+ if test "$USE_OPENSSL" = ""
+ then
+ AC_MSG_ERROR([No OpenSSL for hash functions])
+ fi
+ ISC_PLATFORM_OPENSSLHASH="#define ISC_PLATFORM_OPENSSLHASH 1"
+ ISC_OPENSSL_INC="$DST_OPENSSL_INC"
+ ;;
+ no)
+ ISC_PLATFORM_OPENSSLHASH="#undef ISC_PLATFORM_OPENSSLHASH"
+ ISC_OPENSSL_INC=""
+ ;;
+esac
+AC_SUBST(ISC_PLATFORM_OPENSSLHASH)
+AC_SUBST(ISC_OPENSSL_INC)
+
+#
# PKCS11 (aka crypto hardware) support
#
# This works only with the right OpenSSL with PKCS11 engine!
@@ -677,21 +761,37 @@ DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS"
AC_MSG_CHECKING(for PKCS11 support)
AC_ARG_WITH(pkcs11,
-[ --with-pkcs11 Build with PKCS11 support],
- use_pkcs11="yes", use_pkcs11="no")
+[ --with-pkcs11[=PATH] Build with PKCS11 support [yes|no|path]
+ (PATH is for the PKCS11 provider)],
+ use_pkcs11="$withval", use_pkcs11="no")
case "$use_pkcs11" in
- no)
+ no|'')
AC_MSG_RESULT(disabled)
- USE_PKCS11=""
+ USE_PKCS11=''
+ PKCS11_TOOLS=''
;;
- yes)
+ yes|*)
AC_MSG_RESULT(using OpenSSL with PKCS11 support)
USE_PKCS11='-DUSE_PKCS11'
+ PKCS11_TOOLS=pkcs11
;;
esac
-
AC_SUBST(USE_PKCS11)
+AC_SUBST(PKCS11_TOOLS)
+
+AC_MSG_CHECKING(for PKCS11 tools)
+case "$use_pkcs11" in
+ no|yes|'')
+ AC_MSG_RESULT(disabled)
+ PKCS11_PROVIDER="undefined"
+ ;;
+ *)
+ AC_MSG_RESULT(PKCS11 provider is "$use_pkcs11")
+ PKCS11_PROVIDER="$use_pkcs11"
+ ;;
+esac
+AC_SUBST(PKCS11_PROVIDER)
AC_MSG_CHECKING(for GSSAPI library)
AC_ARG_WITH(gssapi,
@@ -731,6 +831,9 @@ case "$use_gssapi" in
AC_MSG_ERROR([gssapi.h not found])
fi
+ AC_CHECK_HEADERS(gssapi_krb5.h gssapi/gssapi_krb5.h,
+ [ISC_PLATFORM_GSSAPI_KRB5_HEADER="#define ISC_PLATFORM_GSSAPI_KRB5_HEADER <$ac_header>"])
+
AC_CHECK_HEADERS(krb5.h krb5/krb5.h kerberosv5/krb5.h,
[ISC_PLATFORM_KRB5HEADER="#define ISC_PLATFORM_KRB5HEADER <$ac_header>"])
@@ -775,7 +878,12 @@ case "$use_gssapi" in
# -L/usr/local/lib to LIBS, which can make the
# -lgssapi_krb5 test succeed with shared libraries even
# when you are trying to build with KTH in /usr/lib.
- LIBS="-L$use_gssapi/lib $TRY_LIBS"
+ if test "$use_gssapi" = "/usr"
+ then
+ LIBS="$TRY_LIBS"
+ else
+ LIBS="-L$use_gssapi/lib $TRY_LIBS"
+ fi
AC_MSG_CHECKING(linking as $TRY_LIBS)
AC_TRY_LINK( , [gss_acquire_cred();krb5_init_context()],
gssapi_linked=yes, gssapi_linked=no)
@@ -839,6 +947,7 @@ esac
AC_SUBST(ISC_PLATFORM_HAVEGSSAPI)
AC_SUBST(ISC_PLATFORM_GSSAPIHEADER)
+AC_SUBST(ISC_PLATFORM_GSSAPI_KRB5_HEADER)
AC_SUBST(ISC_PLATFORM_KRB5HEADER)
AC_SUBST(USE_GSSAPI)
@@ -1304,6 +1413,65 @@ case $use_libtool in
esac
#
+# enable/disable dumping stack backtrace. Also check if the system supports
+# glibc-compatible backtrace() function.
+#
+AC_ARG_ENABLE(backtrace,
+[ --enable-backtrace log stack backtrace on abort [[default=yes]]],
+ want_backtrace="$enableval", want_backtrace="yes")
+case $want_backtrace in
+yes)
+ ISC_PLATFORM_USEBACKTRACE="#define ISC_PLATFORM_USEBACKTRACE 1"
+ AC_TRY_LINK([#include <execinfo.h>],
+ [return (backtrace((void **)0, 0));],
+ [AC_DEFINE([HAVE_LIBCTRACE], [], [if system have backtrace function])],)
+ ;;
+*)
+ ISC_PLATFORM_USEBACKTRACE="#undef ISC_PLATFORM_USEBACKTRACE"
+ ;;
+esac
+AC_SUBST(ISC_PLATFORM_USEBACKTRACE)
+
+AC_ARG_ENABLE(symtable,
+[ --enable-symtable use internal symbol table for backtrace
+ [[all|minimal(default)|none]]],
+ want_symtable="$enableval", want_symtable="minimal")
+case $want_symtable in
+yes|all|minimal) # "yes" is a hidden value equivalent to "minimal"
+ if test "$PERL" = ""
+ then
+ AC_MSG_ERROR([Internal symbol table requires perl but no perl is found.
+Install perl or explicitly disable the feature by --disable-symtable.])
+ fi
+ if test "$use_libtool" = "yes"; then
+ AC_MSG_WARN([Internal symbol table does not work with libtool. Disabling symbol table.])
+ else
+ # we generate the internal symbol table only for those systems
+ # known to work to avoid unexpected build failure. Also, warn
+ # about unsupported systems when the feature is enabled
+ # manually.
+ case $host_os in
+ freebsd*|netbsd*|openbsd*|linux*|solaris*|darwin*)
+ MKSYMTBL_PROGRAM="$PERL"
+ if test $want_symtable = all; then
+ ALWAYS_MAKE_SYMTABLE="yes"
+ fi
+ ;;
+ *)
+ if test $want_symtable = yes -o $want_symtable = all
+ then
+ AC_MSG_WARN([this system is not known to generate internal symbol table safely; disabling it])
+ fi
+ esac
+ fi
+ ;;
+*)
+ ;;
+esac
+AC_SUBST(MKSYMTBL_PROGRAM)
+AC_SUBST(ALWAYS_MAKE_SYMTABLE)
+
+#
# File name extension for static archive files, for those few places
# where they are treated differently from dynamic ones.
#
@@ -1320,6 +1488,54 @@ AC_SUBST(LIBTOOL_ALLOW_UNDEFINED)
AC_SUBST(LIBTOOL_IN_MAIN)
#
+# build exportable DNS library?
+#
+AC_ARG_ENABLE(exportlib,
+ [ --enable-exportlib build exportable library (GNU make required)
+ [[default=no]]])
+case "$enable_exportlib" in
+ yes)
+ gmake=
+ for x in gmake gnumake make; do
+ if $x --version 2>/dev/null | grep GNU > /dev/null; then
+ gmake=$x
+ break;
+ fi
+ done
+ if test -z "$gmake"; then
+ AC_MSG_ERROR([exportlib requires GNU make. Install it or disable the feature.])
+ fi
+ LIBEXPORT=lib/export
+ AC_SUBST(LIBEXPORT)
+ BIND9_CO_RULE="%.$O: \${srcdir}/%.c"
+ ;;
+ no|*)
+ BIND9_CO_RULE=".c.$O:"
+ ;;
+esac
+AC_SUBST(BIND9_CO_RULE)
+
+AC_ARG_WITH(export-libdir,
+ [ --with-export-libdir[=PATH]
+ installation directory for the export library
+ [[EPREFIX/lib/bind9]]],
+ export_libdir="$withval",)
+if test -z "$export_libdir"; then
+ export_libdir="\${exec_prefix}/lib/bind9/"
+fi
+AC_SUBST(export_libdir)
+
+AC_ARG_WITH(export-includedir,
+ [ --with-export-includedir[=PATH]
+ installation directory for the header files of the
+ export library [[PREFIX/include/bind9]]],
+ export_includedir="$withval",)
+if test -z "$export_includedir"; then
+ export_includedir="\${prefix}/include/bind9/"
+fi
+AC_SUBST(export_includedir)
+
+#
# Here begins a very long section to determine the system's networking
# capabilities. The order of the tests is significant.
#
@@ -1703,10 +1919,13 @@ AC_TRY_COMPILE([
[struct addrinfo a; return (0);],
[AC_MSG_RESULT(yes)
ISC_LWRES_NEEDADDRINFO="#undef ISC_LWRES_NEEDADDRINFO"
+ ISC_IRS_NEEDADDRINFO="#undef ISC_IRS_NEEDADDRINFO"
AC_DEFINE(HAVE_ADDRINFO)],
[AC_MSG_RESULT(no)
- ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1"])
+ ISC_LWRES_NEEDADDRINFO="#define ISC_LWRES_NEEDADDRINFO 1"
+ ISC_IRS_NEEDADDRINFO="#define ISC_IRS_NEEDADDRINFO 1"])
AC_SUBST(ISC_LWRES_NEEDADDRINFO)
+AC_SUBST(ISC_IRS_NEEDADDRINFO)
#
# Check for rrsetinfo
@@ -1793,6 +2012,53 @@ AC_TRY_COMPILE([
ISC_LWRES_NEEDHERRNO="#define ISC_LWRES_NEEDHERRNO 1"])
AC_SUBST(ISC_LWRES_NEEDHERRNO)
+#
+# Sadly, the definitions of system-supplied getnameinfo(3) vary. Try to catch
+# known variations here:
+#
+AC_MSG_CHECKING(for getnameinfo prototype definitions)
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+int getnameinfo(const struct sockaddr *, socklen_t, char *,
+ socklen_t, char *, socklen_t, unsigned int);],
+[ return (0);],
+ [AC_MSG_RESULT(socklen_t for buflen; u_int for flags)
+ AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, socklen_t,
+ [Define to the buffer length type used by getnameinfo(3).])
+ AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, unsigned int,
+ [Define to the flags type used by getnameinfo(3).])],
+[AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+int getnameinfo(const struct sockaddr *, socklen_t, char *,
+ size_t, char *, size_t, int);],
+[ return (0);],
+ [AC_MSG_RESULT(size_t for buflen; int for flags)
+ AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, size_t)
+ AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, int)],
+[AC_MSG_RESULT(not match any subspecies; assume standard definition)
+AC_DEFINE(IRS_GETNAMEINFO_BUFLEN_T, socklen_t)
+AC_DEFINE(IRS_GETNAMEINFO_FLAGS_T, int)])])
+
+#
+# ...and same for gai_strerror().
+#
+AC_MSG_CHECKING(for gai_strerror prototype definitions)
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+char *gai_strerror(int ecode);],
+[ return (0); ],
+ [AC_MSG_RESULT(returning char *)
+ AC_DEFINE([IRS_GAISTRERROR_RETURN_T], [char *],
+ [return type of gai_strerror])],
+[AC_MSG_RESULT(not match any subspecies; assume standard definition)
+AC_DEFINE([IRS_GAISTRERROR_RETURN_T], [const char *])])
+
AC_CHECK_FUNC(getipnodebyname,
[ISC_LWRES_GETIPNODEPROTO="#undef ISC_LWRES_GETIPNODEPROTO"],
[ISC_LWRES_GETIPNODEPROTO="#define ISC_LWRES_GETIPNODEPROTO 1"])
@@ -1807,6 +2073,7 @@ AC_CHECK_FUNC(gai_strerror, AC_DEFINE(HAVE_GAISTRERROR))
AC_SUBST(ISC_LWRES_GETIPNODEPROTO)
AC_SUBST(ISC_LWRES_GETADDRINFOPROTO)
AC_SUBST(ISC_LWRES_GETNAMEINFOPROTO)
+AC_SUBST(ISC_IRS_GETNAMEINFOSOCKLEN)
AC_ARG_ENABLE(getifaddrs,
[ --enable-getifaddrs Enable the use of getifaddrs() [[yes|no]].],
@@ -2140,6 +2407,8 @@ AC_SUBST(ISC_PLATFORM_USEDECLSPEC)
ISC_PLATFORM_USEDECLSPEC="#undef ISC_PLATFORM_USEDECLSPEC"
AC_SUBST(LWRES_PLATFORM_USEDECLSPEC)
LWRES_PLATFORM_USEDECLSPEC="#undef LWRES_PLATFORM_USEDECLSPEC"
+AC_SUBST(IRS_PLATFORM_USEDECLSPEC)
+IRS_PLATFORM_USEDECLSPEC="#undef IRS_PLATFORM_USEDECLSPEC"
#
# Random remaining OS-specific issues involving compiler warnings.
@@ -2461,6 +2730,61 @@ case "$enable_fixed" in
esac
#
+# Enable response policy rewriting using NS IP addresses
+#
+AC_ARG_ENABLE(rpz-nsip,
+ [ --enable-rpz-nsip enable rpz-nsip rules [[default=no]]],
+ enable_nsip="$enableval",
+ enable_nsip="no")
+case "$enable_nsip" in
+ yes)
+ AC_DEFINE(ENABLE_RPZ_NSIP, 1,
+ [Define to enable rpz-nsip rules.])
+ ;;
+ no)
+ ;;
+ *)
+ ;;
+esac
+
+#
+# Enable response policy rewriting using NS name
+#
+AC_ARG_ENABLE(rpz-nsdname,
+ [ --enable-rpz-nsdname enable rpz-nsdname rules [[default=no]]],
+ enable_nsdname="$enableval",
+ enable_nsdname="no")
+case "$enable_nsdname" in
+ yes)
+ AC_DEFINE(ENABLE_RPZ_NSDNAME, 1,
+ [Define to enable rpz-nsdname rules.])
+ ;;
+ no)
+ ;;
+ *)
+ ;;
+esac
+
+#
+# Activate "filter-aaaa-on-v4" or not?
+#
+AC_ARG_ENABLE(filter-aaaa,
+ [ --enable-filter-aaaa enable filtering of AAAA records over IPv4
+ [[default=no]]],
+ enable_filter="$enableval",
+ enable_filter="no")
+case "$enable_filter" in
+ yes)
+ AC_DEFINE(ALLOW_FILTER_AAAA_ON_V4, 1,
+ [Define to enable the "filter-aaaa-on-v4" option.])
+ ;;
+ no)
+ ;;
+ *)
+ ;;
+esac
+
+#
# The following sets up how non-blocking i/o is established.
# Sunos, cygwin and solaris 2.x (x<5) require special handling.
#
@@ -2780,6 +3104,9 @@ LIBBIND9_API=$srcdir/lib/bind9/api
AC_SUBST_FILE(LIBLWRES_API)
LIBLWRES_API=$srcdir/lib/lwres/api
+AC_SUBST_FILE(LIBIRS_API)
+LIBIRS_API=$srcdir/lib/irs/api
+
#
# Configure any DLZ drivers.
#
@@ -2947,37 +3274,115 @@ AC_CONFIG_COMMANDS(
#
AC_CONFIG_FILES([
+ make/Makefile
+ make/mkdep
Makefile
- make/Makefile
- make/mkdep
+ bin/Makefile
+ bin/check/Makefile
+ bin/confgen/Makefile
+ bin/confgen/unix/Makefile
+ bin/dig/Makefile
+ bin/dnssec/Makefile
+ bin/named/Makefile
+ bin/named/unix/Makefile
+ bin/nsupdate/Makefile
+ bin/pkcs11/Makefile
+ bin/rndc/Makefile
+ bin/tests/Makefile
+ bin/tests/atomic/Makefile
+ bin/tests/db/Makefile
+ bin/tests/dst/Makefile
+ bin/tests/hashes/Makefile
+ bin/tests/headerdep_test.sh
+ bin/tests/master/Makefile
+ bin/tests/mem/Makefile
+ bin/tests/names/Makefile
+ bin/tests/net/Makefile
+ bin/tests/rbt/Makefile
+ bin/tests/resolver/Makefile
+ bin/tests/sockaddr/Makefile
+ bin/tests/system/Makefile
+ bin/tests/system/conf.sh
+ bin/tests/system/filter-aaaa/Makefile
+ bin/tests/system/gost/prereq.sh
+ bin/tests/system/lwresd/Makefile
+ bin/tests/system/rpz/Makefile
+ bin/tests/system/tkey/Makefile
+ bin/tests/tasks/Makefile
+ bin/tests/timers/Makefile
+ bin/tests/virtual-time/Makefile
+ bin/tests/virtual-time/conf.sh
+ bin/tools/Makefile
+ contrib/check-secure-delegation.pl
+ contrib/zone-edit.sh
+ doc/Makefile
+ doc/arm/Makefile
+ doc/doxygen/Doxyfile
+ doc/doxygen/Makefile
+ doc/doxygen/doxygen-input-filter
+ doc/misc/Makefile
+ doc/xsl/Makefile
+ doc/xsl/isc-docbook-chunk.xsl
+ doc/xsl/isc-docbook-html.xsl
+ doc/xsl/isc-docbook-latex.xsl
+ doc/xsl/isc-manpage.xsl
+ isc-config.sh
lib/Makefile
+ lib/bind9/Makefile
+ lib/bind9/include/Makefile
+ lib/bind9/include/bind9/Makefile
+ lib/dns/Makefile
+ lib/dns/include/Makefile
+ lib/dns/include/dns/Makefile
+ lib/dns/include/dst/Makefile
+ lib/export/Makefile
+ lib/export/dns/Makefile
+ lib/export/dns/include/Makefile
+ lib/export/dns/include/dns/Makefile
+ lib/export/dns/include/dst/Makefile
+ lib/export/irs/Makefile
+ lib/export/irs/include/Makefile
+ lib/export/irs/include/irs/Makefile
+ lib/export/isc/$thread_dir/Makefile
+ lib/export/isc/$thread_dir/include/Makefile
+ lib/export/isc/$thread_dir/include/isc/Makefile
+ lib/export/isc/Makefile
+ lib/export/isc/include/Makefile
+ lib/export/isc/include/isc/Makefile
+ lib/export/isc/nls/Makefile
+ lib/export/isc/unix/Makefile
+ lib/export/isc/unix/include/Makefile
+ lib/export/isc/unix/include/isc/Makefile
+ lib/export/isccfg/Makefile
+ lib/export/isccfg/include/Makefile
+ lib/export/isccfg/include/isccfg/Makefile
+ lib/export/samples/Makefile
+ lib/export/samples/Makefile-postinstall
+ lib/irs/Makefile
+ lib/irs/include/Makefile
+ lib/irs/include/irs/Makefile
+ lib/irs/include/irs/netdb.h
+ lib/irs/include/irs/platform.h
+ lib/isc/$arch/Makefile
+ lib/isc/$arch/include/Makefile
+ lib/isc/$arch/include/isc/Makefile
+ lib/isc/$thread_dir/Makefile
+ lib/isc/$thread_dir/include/Makefile
+ lib/isc/$thread_dir/include/isc/Makefile
lib/isc/Makefile
lib/isc/include/Makefile
lib/isc/include/isc/Makefile
lib/isc/include/isc/platform.h
+ lib/isc/nls/Makefile
lib/isc/unix/Makefile
lib/isc/unix/include/Makefile
lib/isc/unix/include/isc/Makefile
- lib/isc/nls/Makefile
- lib/isc/$thread_dir/Makefile
- lib/isc/$thread_dir/include/Makefile
- lib/isc/$thread_dir/include/isc/Makefile
- lib/isc/$arch/Makefile
- lib/isc/$arch/include/Makefile
- lib/isc/$arch/include/isc/Makefile
lib/isccc/Makefile
lib/isccc/include/Makefile
lib/isccc/include/isccc/Makefile
lib/isccfg/Makefile
lib/isccfg/include/Makefile
lib/isccfg/include/isccfg/Makefile
- lib/dns/Makefile
- lib/dns/include/Makefile
- lib/dns/include/dns/Makefile
- lib/dns/include/dst/Makefile
- lib/bind9/Makefile
- lib/bind9/include/Makefile
- lib/bind9/include/bind9/Makefile
lib/lwres/Makefile
lib/lwres/include/Makefile
lib/lwres/include/lwres/Makefile
@@ -2990,44 +3395,6 @@ AC_CONFIG_FILES([
lib/tests/Makefile
lib/tests/include/Makefile
lib/tests/include/tests/Makefile
- bin/Makefile
- bin/check/Makefile
- bin/named/Makefile
- bin/named/unix/Makefile
- bin/rndc/Makefile
- bin/rndc/unix/Makefile
- bin/dig/Makefile
- bin/nsupdate/Makefile
- bin/tests/Makefile
- bin/tests/names/Makefile
- bin/tests/master/Makefile
- bin/tests/rbt/Makefile
- bin/tests/db/Makefile
- bin/tests/tasks/Makefile
- bin/tests/timers/Makefile
- bin/tests/dst/Makefile
- bin/tests/mem/Makefile
- bin/tests/hashes/Makefile
- bin/tests/net/Makefile
- bin/tests/sockaddr/Makefile
- bin/tests/system/Makefile
- bin/tests/system/conf.sh
- bin/tests/system/lwresd/Makefile
- bin/tests/system/tkey/Makefile
- bin/tests/headerdep_test.sh
- bin/dnssec/Makefile
- doc/Makefile
- doc/arm/Makefile
- doc/misc/Makefile
- isc-config.sh
- doc/xsl/Makefile
- doc/xsl/isc-docbook-chunk.xsl
- doc/xsl/isc-docbook-html.xsl
- doc/xsl/isc-docbook-latex.xsl
- doc/xsl/isc-manpage.xsl
- doc/doxygen/Doxyfile
- doc/doxygen/Makefile
- doc/doxygen/doxygen-input-filter
])
#
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
index 0013c2e7f689..c3517843175d 100644
--- a/doc/arm/Bv9ARM-book.xml
+++ b/doc/arm/Bv9ARM-book.xml
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- File: $Id: Bv9ARM-book.xml,v 1.380.14.28 2010-08-20 01:38:26 marka Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.478.8.2.2.1 2011-06-09 03:17:11 marka Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
@@ -31,6 +31,7 @@
<year>2008</year>
<year>2009</year>
<year>2010</year>
+ <year>2011</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
@@ -69,7 +70,7 @@
</para>
<para>
- This version of the manual corresponds to BIND version 9.6.
+ This version of the manual corresponds to BIND version 9.7.
</para>
</sect1>
@@ -644,9 +645,9 @@
<para>
ISC <acronym>BIND</acronym> 9 compiles and runs on a large
number
- of Unix-like operating systems and on NT-derived versions of
- Microsoft Windows such as Windows 2000 and Windows XP. For an
- up-to-date
+ of Unix-like operating systems and on
+ Microsoft Windows Server 2003 and 2008, and Windows XP and Vista.
+ For an up-to-date
list of supported systems, see the README file in the top level
directory
of the BIND 9 source distribution.
@@ -680,10 +681,13 @@
// Two corporate subnets we wish to allow queries from.
acl corpnets { 192.168.4.0/24; 192.168.7.0/24; };
options {
- directory "/etc/namedb"; // Working directory
+ // Working directory
+ directory "/etc/namedb";
+
allow-query { corpnets; };
};
-// Provide a reverse mapping for the loopback address 127.0.0.1
+// Provide a reverse mapping for the loopback
+// address 127.0.0.1
zone "0.0.127.in-addr.arpa" {
type master;
file "localhost.rev";
@@ -703,13 +707,18 @@ zone "0.0.127.in-addr.arpa" {
<programlisting>
options {
- directory "/etc/namedb"; // Working directory
- allow-query-cache { none; }; // Do not allow access to cache
- allow-query { any; }; // This is the default
- recursion no; // Do not provide recursive service
+ // Working directory
+ directory "/etc/namedb";
+ // Do not allow access to cache
+ allow-query-cache { none; };
+ // This is the default
+ allow-query { any; };
+ // Do not provide recursive service
+ recursion no;
};
-// Provide a reverse mapping for the loopback address 127.0.0.1
+// Provide a reverse mapping for the loopback
+// address 127.0.0.1
zone "0.0.127.in-addr.arpa" {
type master;
file "localhost.rev";
@@ -719,7 +728,8 @@ zone "0.0.127.in-addr.arpa" {
zone "example.com" {
type master;
file "example.com.db";
- // IP addresses of slave servers allowed to transfer example.com
+ // IP addresses of slave servers allowed to
+ // transfer example.com
allow-transfer {
192.168.4.14;
192.168.5.53;
@@ -881,7 +891,7 @@ zone "eng.example.com" {
</para>
<para>
For more detail on ordering responses, check the
- <command>rrset-order</command> substatement in the
+ <command>rrset-order</command> sub-statement in the
<command>options</command> statement, see
<xref endterm="rrset_ordering_title" linkend="rrset_ordering"/>.
</para>
@@ -1162,7 +1172,62 @@ zone "eng.example.com" {
</varlistentry>
<varlistentry>
+ <term><userinput>sign <replaceable>zone</replaceable>
+ <optional><replaceable>class</replaceable>
+ <optional><replaceable>view</replaceable></optional></optional></userinput></term>
+ <listitem>
+ <para>
+ Fetch all DNSSEC keys for the given zone
+ from the key directory (see
+ <command>key-directory</command> in
+ <xref linkend="options"/>). If they are within
+ their publication period, merge them into the
+ zone's DNSKEY RRset. If the DNSKEY RRset
+ is changed, then the zone is automatically
+ re-signed with the new key set.
+ </para>
+ <para>
+ This command requires that the
+ <command>auto-dnssec</command> zone option to be set
+ to <literal>allow</literal>,
+ <literal>maintain</literal>, or
+ <literal>create</literal>, and also requires
+ the zone to be configured to allow dynamic DNS.
+ See <xref linkend="dynamic_update_policies"/> for
+ more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><userinput>loadkeys <replaceable>zone</replaceable>
+ <optional><replaceable>class</replaceable>
+ <optional><replaceable>view</replaceable></optional></optional></userinput></term>
+ <listitem>
+ <para>
+ Fetch all DNSSEC keys for the given zone
+ from the key directory (see
+ <command>key-directory</command> in
+ <xref linkend="options"/>). If they are within
+ their publication period, merge them into the
+ zone's DNSKEY RRset. Unlike <command>rndc
+ sign</command>, however, the zone is not
+ immediately re-signed by the new keys, but is
+ allowed to incrementally re-sign over time.
+ </para>
+ <para>
+ This command requires that the
+ <command>auto-dnssec</command> zone option to
+ be set to <literal>maintain</literal> or
+ <literal>create</literal>, and also requires
+ the zone to be configured to allow dynamic DNS.
+ See <xref linkend="dynamic_update_policies"/> for
+ more details.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><userinput>freeze
<optional><replaceable>zone</replaceable>
<optional><replaceable>class</replaceable>
@@ -1271,6 +1336,19 @@ zone "eng.example.com" {
</varlistentry>
<varlistentry>
+ <term><userinput>secroots
+ <optional><replaceable>view ...</replaceable></optional></userinput></term>
+ <listitem>
+ <para>
+ Dump the server's security roots to the secroots
+ file for the specified views. If no view is
+ specified, security roots for all
+ views are dumped.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><userinput>stop <optional>-p</optional></userinput></term>
<listitem>
<para>
@@ -1383,6 +1461,65 @@ zone "eng.example.com" {
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><userinput>addzone
+ <replaceable>zone</replaceable>
+ <optional><replaceable>class</replaceable>
+ <optional><replaceable>view</replaceable></optional></optional>
+ <replaceable>configuration</replaceable>
+ </userinput></term>
+ <listitem>
+ <para>
+ Add a zone while the server is running. This
+ command requires the
+ <command>allow-new-zones</command> option to be set
+ to <userinput>yes</userinput>. The
+ <replaceable>configuration</replaceable> string
+ specified on the command line is the zone
+ configuration text that would ordinarily be
+ placed in <filename>named.conf</filename>.
+ </para>
+ <para>
+ The configuration is saved in a file called
+ <filename><replaceable>hash</replaceable>.nzf</filename>,
+ where <replaceable>hash</replaceable> is a
+ cryptographic hash generated from the name of
+ the view. When <command>named</command> is
+ restarted, the file will be loaded into the view
+ configuration, so that zones that were added
+ can persist after a restart.
+ </para>
+ <para>
+ This sample <command>addzone</command> command
+ would add the zone <literal>example.com</literal>
+ to the default view:
+ </para>
+ <para>
+<prompt>$ </prompt><userinput>rndc addzone example.com '{ type master; file "example.com.db"; };'</userinput>
+ </para>
+ <para>
+ (Note the brackets and semi-colon around the zone
+ configuration text.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><userinput>delzone
+ <replaceable>zone</replaceable>
+ <optional><replaceable>class</replaceable>
+ <optional><replaceable>view</replaceable></optional></optional>
+ </userinput></term>
+ <listitem>
+ <para>
+ Delete a zone while the server is running.
+ Only zones that were originally added via
+ <command>rndc addzone</command> can be deleted
+ in this matter.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
<para>
@@ -1488,7 +1625,8 @@ zone "eng.example.com" {
<programlisting>
key rndc_key {
algorithm "hmac-md5";
- secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K";
+ secret
+ "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K";
};
options {
default-server 127.0.0.1;
@@ -1514,7 +1652,8 @@ options {
<programlisting>
controls {
- inet 127.0.0.1 allow { localhost; } keys { rndc_key; };
+ inet 127.0.0.1
+ allow { localhost; } keys { rndc_key; };
};
</programlisting>
@@ -1641,14 +1780,27 @@ controls {
<para>
Dynamic update is enabled by including an
- <command>allow-update</command> or <command>update-policy</command>
- clause in the <command>zone</command> statement. The
- <command>tkey-gssapi-credential</command> and
- <command>tkey-domain</command> clauses in the
- <command>options</command> statement enable the
- server to negotiate keys that can be matched against those
- in <command>update-policy</command> or
- <command>allow-update</command>.
+ <command>allow-update</command> or an <command>update-policy</command>
+ clause in the <command>zone</command> statement.
+ </para>
+
+ <para>
+ If the zone's <command>update-policy</command> is set to
+ <userinput>local</userinput>, updates to the zone
+ will be permitted for the key <varname>local-ddns</varname>,
+ which will be generated by <command>named</command> at startup.
+ See <xref linkend="dynamic_update_policies"/> for more details.
+ </para>
+
+ <para>
+ Dynamic updates using Kerberos signed requests can be made
+ using the TKEY/GSS protocol by setting either the
+ <command>tkey-gssapi-keytab</command> option, or alternatively
+ by setting both the <command>tkey-gssapi-credential</command>
+ and <command>tkey-domain</command> options. Once enabled,
+ Kerberos signed requests will be matched against the update
+ policies for the zone, using the Kerberos principal as the
+ signer for the request.
</para>
<para>
@@ -1660,7 +1812,7 @@ controls {
</para>
<sect2 id="journal">
- <title>The journal file</title>
+ <title>The journal file</title>
<para>
All changes made to a zone using dynamic update are stored
@@ -1814,7 +1966,7 @@ controls {
and <filename>site2.example.com</filename>, to the servers
in the
DMZ. These internal servers will have complete sets of information
- for <filename>site1.example.com</filename>, <filename>site2.example.com</filename>,<emphasis/> <filename>site1.internal</filename>,
+ for <filename>site1.example.com</filename>, <filename>site2.example.com</filename>, <filename>site1.internal</filename>,
and <filename>site2.internal</filename>.
</para>
<para>
@@ -1927,26 +2079,32 @@ options {
...
...
forward only;
- forwarders { // forward to external servers
+ // forward to external servers
+ forwarders {
<varname>bastion-ips-go-here</varname>;
};
- allow-transfer { none; }; // sample allow-transfer (no one)
- allow-query { internals; externals; }; // restrict query access
- allow-recursion { internals; }; // restrict recursion
+ // sample allow-transfer (no one)
+ allow-transfer { none; };
+ // restrict query access
+ allow-query { internals; externals; };
+ // restrict recursion
+ allow-recursion { internals; };
...
...
};
-zone "site1.example.com" { // sample master zone
+// sample master zone
+zone "site1.example.com" {
type master;
file "m/site1.example.com";
- forwarders { }; // do normal iterative
- // resolution (do not forward)
+ // do normal iterative resolution (do not forward)
+ forwarders { };
allow-query { internals; externals; };
allow-transfer { internals; };
};
-zone "site2.example.com" { // sample slave zone
+// sample slave zone
+zone "site2.example.com" {
type slave;
file "s/site2.example.com";
masters { 172.16.72.3; };
@@ -1985,15 +2143,20 @@ acl externals { bastion-ips-go-here; };
options {
...
...
- allow-transfer { none; }; // sample allow-transfer (no one)
- allow-query { any; }; // default query access
- allow-query-cache { internals; externals; }; // restrict cache access
- allow-recursion { internals; externals; }; // restrict recursion
+ // sample allow-transfer (no one)
+ allow-transfer { none; };
+ // default query access
+ allow-query { any; };
+ // restrict cache access
+ allow-query-cache { internals; externals; };
+ // restrict recursion
+ allow-recursion { internals; externals; };
...
...
};
-zone "site1.example.com" { // sample slave zone
+// sample slave zone
+zone "site1.example.com" {
type master;
file "m/site1.foo.com";
allow-transfer { internals; externals; };
@@ -2187,9 +2350,8 @@ allow-update { key host1-host2. ;};
</para>
<para>
- You may want to read about the more powerful
- <command>update-policy</command> statement in
- <xref linkend="dynamic_update_policies"/>.
+ See <xref linkend="dynamic_update_policies"/> for a discussion of
+ the more flexible <command>update-policy</command> statement.
</para>
</sect2>
@@ -2453,12 +2615,23 @@ allow-update { key host1-host2. ;};
<para>
To enable <command>named</command> to validate answers from
- other servers, the <command>dnssec-enable</command> and
- <command>dnssec-validation</command> options must both be
- set to yes (the default setting in <acronym>BIND</acronym> 9.5
- and later), and at least one trust anchor must be configured
- with a <command>trusted-keys</command> statement in
- <filename>named.conf</filename>.
+ other servers, the <command>dnssec-enable</command> option
+ must be set to <userinput>yes</userinput>, and the
+ <command>dnssec-validation</command> options must be set to
+ <userinput>yes</userinput> or <userinput>auto</userinput>.
+ </para>
+
+ <para>
+ If <command>dnssec-validation</command> is set to
+ <userinput>auto</userinput>, then a default
+ trust anchor for the DNS root zone will be used.
+ If it is set to <userinput>yes</userinput>, however,
+ then at least one trust anchor must be configured
+ with a <command>trusted-keys</command> or
+ <command>managed-keys</command> statement in
+ <filename>named.conf</filename>, or DNSSEC validation
+ will not occur. The default setting is
+ <userinput>yes</userinput>.
</para>
<para>
@@ -2471,7 +2644,14 @@ allow-update { key host1-host2. ;};
</para>
<para>
- <command>trusted-keys</command> are described in more detail
+ <command>managed-keys</command> are trusted keys which are
+ automatically kept up to date via RFC 5011 trust anchor
+ maintenance.
+ </para>
+
+ <para>
+ <command>trusted-keys</command> and
+ <command>managed-keys</command> are described in more detail
later in this document.
</para>
@@ -2484,45 +2664,59 @@ allow-update { key host1-host2. ;};
<para>
After DNSSEC gets established, a typical DNSSEC configuration
- will look something like the following. It has a one or
+ will look something like the following. It has one or
more public keys for the root. This allows answers from
outside the organization to be validated. It will also
have several keys for parts of the namespace the organization
- controls. These are here to ensure that <command>named</command> is immune
- to compromises in the DNSSEC components of the security
- of parent zones.
+ controls. These are here to ensure that <command>named</command>
+ is immune to compromises in the DNSSEC components of the security
+ of parent zones.
</para>
<programlisting>
-trusted-keys {
-
+managed-keys {
/* Root Key */
-"." 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwSJxrGkxJWoZu6I7PzJu/
- E9gx4UC1zGAHlXKdE4zYIpRhaBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3
- zy2Xy4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYghf+6fElrmLkdaz
- MQ2OCnACR817DF4BBa7UR/beDHyp5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M
- /lUUVRbkeg1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq66gKodQj+M
- iA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ97S+LKUTpQcq27R7AT3/V5hRQxScI
- Nqwcz4jYqZD2fQdgxbcDTClU0CRBdiieyLMNzXG3";
-
-/* Key for our organization's forward zone */
-example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM65KbhTjrW1ZaARmPhEZZe
- 3Y9ifgEuq7vZ/zGZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb4JKUbb
- OTcM8pwXlj0EiX3oDFVmjHO444gLkBO UKUf/mC7HvfwYH/Be22GnC
- lrinKJp1Og4ywzO9WglMk7jbfW33gUKvirTHr25GL7STQUzBb5Usxt
- 8lgnyTUHs1t3JwCY5hKZ6CqFxmAVZP20igTixin/1LcrgX/KMEGd/b
- iuvF4qJCyduieHukuY3H4XMAcR+xia2 nIUPvm/oyWR8BW/hWdzOvn
- SCThlHf3xiYleDbt/o1OTQ09A0=";
-
-/* Key for our reverse zone. */
-2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwcxOdNax071L18QqZnQQQA
- VVr+iLhGTnNGp3HoWQLUIzKrJVZ3zggy3WwNT6kZo6c0
- tszYqbtvchmgQC8CzKojM/W16i6MG/ea fGU3siaOdS0
- yOI6BgPsw+YZdzlYMaIJGf4M4dyoKIhzdZyQ2bYQrjyQ
- 4LB0lC7aOnsMyYKHHYeRv PxjIQXmdqgOJGq+vsevG06
- zW+1xgYJh9rCIfnm1GX/KMgxLPG2vXTD/RnLX+D3T3UL
- 7HJYHJhAZD5L59VvjSPsZJHeDCUyWYrvPZesZDIRvhDD
- 52SKvbheeTJUm6EhkzytNN2SN96QRk8j/iI8ib";
+ "." initial-key 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS
+ JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh
+ aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy
+ 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg
+ hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp
+ 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke
+ g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq
+ 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ
+ 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ
+ dgxbcDTClU0CRBdiieyLMNzXG3";
+};
+
+trusted-keys {
+ /* Key for our organization's forward zone */
+ example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM6
+ 5KbhTjrW1ZaARmPhEZZe3Y9ifgEuq7vZ/z
+ GZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb
+ 4JKUbbOTcM8pwXlj0EiX3oDFVmjHO444gL
+ kBOUKUf/mC7HvfwYH/Be22GnClrinKJp1O
+ g4ywzO9WglMk7jbfW33gUKvirTHr25GL7S
+ TQUzBb5Usxt8lgnyTUHs1t3JwCY5hKZ6Cq
+ FxmAVZP20igTixin/1LcrgX/KMEGd/biuv
+ F4qJCyduieHukuY3H4XMAcR+xia2nIUPvm
+ /oyWR8BW/hWdzOvnSCThlHf3xiYleDbt/o
+ 1OTQ09A0=";
+
+ /* Key for our reverse zone. */
+ 2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc
+ xOdNax071L18QqZnQQQAVVr+i
+ LhGTnNGp3HoWQLUIzKrJVZ3zg
+ gy3WwNT6kZo6c0tszYqbtvchm
+ gQC8CzKojM/W16i6MG/eafGU3
+ siaOdS0yOI6BgPsw+YZdzlYMa
+ IJGf4M4dyoKIhzdZyQ2bYQrjy
+ Q4LB0lC7aOnsMyYKHHYeRvPxj
+ IQXmdqgOJGq+vsevG06zW+1xg
+ YJh9rCIfnm1GX/KMgxLPG2vXT
+ D/RnLX+D3T3UL7HJYHJhAZD5L
+ 59VvjSPsZJHeDCUyWYrvPZesZ
+ DIRvhDD52SKvbheeTJUm6Ehkz
+ ytNN2SN96QRk8j/iI8ib";
};
options {
@@ -2575,6 +2769,13 @@ options {
</sect2>
</sect1>
+
+ <xi:include href="dnssec.xml"/>
+
+ <xi:include href="managed-keys.xml"/>
+
+ <xi:include href="pkcs11.xml"/>
+
<sect1>
<title>IPv6 Support in <acronym>BIND</acronym> 9</title>
@@ -2653,7 +2854,8 @@ host 3600 IN AAAA 2001:db8::1
<programlisting>
$ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
-1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR host.example.com.
+1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR (
+ host.example.com. )
</programlisting>
</sect2>
@@ -2831,6 +3033,19 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
<row rowsep="0">
<entry colname="1">
<para>
+ <varname>namelist</varname>
+ </para>
+ </entry>
+ <entry colname="2">
+ <para>
+ A list of one or more <varname>domain_name</varname>
+ elements.
+ </para>
+ </entry>
+ </row>
+ <row rowsep="0">
+ <entry colname="1">
+ <para>
<varname>dotted_decimal</varname>
</para>
</entry>
@@ -3224,7 +3439,8 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
<para>
<programlisting>/* This is a <acronym>BIND</acronym> comment as in C */</programlisting>
<programlisting>// This is a <acronym>BIND</acronym> comment as in C++</programlisting>
- <programlisting># This is a <acronym>BIND</acronym> comment as in common UNIX shells and perl</programlisting>
+ <programlisting># This is a <acronym>BIND</acronym> comment as in common UNIX shells
+# and perl</programlisting>
</para>
</sect3>
<sect3>
@@ -3439,6 +3655,17 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
</row>
<row rowsep="0">
<entry colname="1">
+ <para><command>managed-keys</command></para>
+ </entry>
+ <entry colname="2">
+ <para>
+ lists DNSSEC keys to be kept up to date
+ using RFC 5011 trust anchor maintenance.
+ </para>
+ </entry>
+ </row>
+ <row rowsep="0">
+ <entry colname="1">
<para><command>view</command></para>
</entry>
<entry colname="2">
@@ -3559,10 +3786,12 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
<title><command>controls</command> Statement Grammar</title>
<programlisting><command>controls</command> {
- [ inet ( ip_addr | * ) [ port ip_port ] allow { <replaceable> address_match_list </replaceable> }
+ [ inet ( ip_addr | * ) [ port ip_port ]
+ allow { <replaceable> address_match_list </replaceable> }
keys { <replaceable>key_list</replaceable> }; ]
[ inet ...; ]
- [ unix <replaceable>path</replaceable> perm <replaceable>number</replaceable> owner <replaceable>number</replaceable> group <replaceable>number</replaceable> keys { <replaceable>key_list</replaceable> }; ]
+ [ unix <replaceable>path</replaceable> perm <replaceable>number</replaceable> owner <replaceable>number</replaceable> group <replaceable>number</replaceable>
+ keys { <replaceable>key_list</replaceable> }; ]
[ unix ...; ]
};
</programlisting>
@@ -4031,32 +4260,30 @@ notrace</command>. All debugging messages in the server have a debug
</para>
<programlisting>channel default_syslog {
- syslog daemon; // send to syslog's daemon
- // facility
- severity info; // only send priority info
- // and higher
-};
+ // send to syslog's daemon facility
+ syslog daemon;
+ // only send priority info and higher
+ severity info;
channel default_debug {
- file "named.run"; // write to named.run in
- // the working directory
- // Note: stderr is used instead
- // of "named.run"
- // if the server is started
- // with the '-f' option.
- severity dynamic; // log at the server's
- // current debug level
+ // write to named.run in the working directory
+ // Note: stderr is used instead of "named.run" if
+ // the server is started with the '-f' option.
+ file "named.run";
+ // log at the server's current debug level
+ severity dynamic;
};
channel default_stderr {
- stderr; // writes to stderr
- severity info; // only send priority info
- // and higher
+ // writes to stderr
+ stderr;
+ // only send priority info and higher
+ severity info;
};
channel null {
- null; // toss anything sent to
- // this channel
+ // toss anything sent to this channel
+ null;
};
</programlisting>
@@ -4308,12 +4535,14 @@ category notify { null; };
<para>
The query log entry reports the client's IP
address and port number, and the query name,
- class and type. It also reports whether the
+ class and type. Next it reports whether the
Recursion Desired flag was set (+ if set, -
if not set), if the query was signed (S),
- EDNS was in use (E), if DO (DNSSEC Ok) was
- set (D), or if CD (Checking Disabled) was set
- (C).
+ EDNS was in use (E), if TCP was used (T), if
+ DO (DNSSEC Ok) was set (D), or if CD (Checking
+ Disabled) was set (C). After this the
+ destination address the query was sent to is
+ reported.
</para>
<para>
@@ -4453,7 +4682,13 @@ category notify { null; };
The log message will look like as follows:
</para>
<para>
- <computeroutput>fetch completed at resolver.c:2970 for www.example.com/A in 30.000183: timed out/success [domain:example.com,referral:2,restart:7,qrysent:8,timeout:5,lame:0,neterr:0,badresp:1,adberr:0,findfail:0,valfail:0]</computeroutput>
+<!-- NOTE: newlines and some spaces added so this would fit on page -->
+ <programlisting>
+fetch completed at resolver.c:2970 for www.example.com/A
+in 30.000183: timed out/success [domain:example.com,
+referral:2,restart:7,qrysent:8,timeout:5,lame:0,neterr:0,
+badresp:1,adberr:0,findfail:0,valfail:0]
+ </programlisting>
</para>
<para>
The first part before the colon shows that a recursive
@@ -4485,8 +4720,8 @@ category notify { null; };
<informaltable colsep="0" rowsep="0">
<tgroup cols="2" colsep="0" rowsep="0" tgroupstyle="4Level-table">
- <colspec colname="1" colnum="1" colsep="0" />
- <colspec colname="2" colnum="2" colsep="0" />
+ <colspec colname="1" colnum="1" colsep="0" colwidth="1.150in"/>
+ <colspec colname="2" colnum="2" colsep="0" colwidth="3.350in"/>
<tbody>
<row rowsep="0">
<entry colname="1">
@@ -4651,7 +4886,8 @@ category notify { null; };
</para>
<programlisting><command>lwres</command> {
- <optional> listen-on { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
+ <optional> listen-on { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ;
+ <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> view <replaceable>view_name</replaceable>; </optional>
<optional> search { <replaceable>domain_name</replaceable> ; <optional> <replaceable>domain_name</replaceable> ; ... </optional> }; </optional>
<optional> ndots <replaceable>number</replaceable>; </optional>
@@ -4718,7 +4954,8 @@ category notify { null; };
<title><command>masters</command> Statement Grammar</title>
<programlisting>
-<command>masters</command> <replaceable>name</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> };
+<command>masters</command> <replaceable>name</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>masters_list</replaceable> |
+ <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> };
</programlisting>
</sect2>
@@ -4741,17 +4978,21 @@ category notify { null; };
</para>
<programlisting><command>options</command> {
+ <optional> attach-cache <replaceable>cache_name</replaceable>; </optional>
<optional> version <replaceable>version_string</replaceable>; </optional>
<optional> hostname <replaceable>hostname_string</replaceable>; </optional>
<optional> server-id <replaceable>server_id_string</replaceable>; </optional>
<optional> directory <replaceable>path_name</replaceable>; </optional>
<optional> key-directory <replaceable>path_name</replaceable>; </optional>
+ <optional> managed-keys-directory <replaceable>path_name</replaceable>; </optional>
<optional> named-xfer <replaceable>path_name</replaceable>; </optional>
+ <optional> tkey-gssapi-keytab <replaceable>path_name</replaceable>; </optional>
<optional> tkey-gssapi-credential <replaceable>principal</replaceable>; </optional>
<optional> tkey-domain <replaceable>domainname</replaceable>; </optional>
<optional> tkey-dhkey <replaceable>key_name</replaceable> <replaceable>key_tag</replaceable>; </optional>
<optional> cache-file <replaceable>path_name</replaceable>; </optional>
<optional> dump-file <replaceable>path_name</replaceable>; </optional>
+ <optional> bindkeys-file <replaceable>path_name</replaceable>; </optional>
<optional> memstatistics <replaceable>yes_or_no</replaceable>; </optional>
<optional> memstatistics-file <replaceable>path_name</replaceable>; </optional>
<optional> pid-file <replaceable>path_name</replaceable>; </optional>
@@ -4776,8 +5017,9 @@ category notify { null; };
<optional> maintain-ixfr-base <replaceable>yes_or_no</replaceable>; </optional>
<optional> ixfr-from-differences (<replaceable>yes_or_no</replaceable> | <constant>master</constant> | <constant>slave</constant>); </optional>
<optional> dnssec-enable <replaceable>yes_or_no</replaceable>; </optional>
- <optional> dnssec-validation <replaceable>yes_or_no</replaceable>; </optional>
- <optional> dnssec-lookaside <replaceable>domain</replaceable> trust-anchor <replaceable>domain</replaceable>; </optional>
+ <optional> dnssec-validation (<replaceable>yes_or_no</replaceable> | <constant>auto</constant>); </optional>
+ <optional> dnssec-lookaside ( <replaceable>auto</replaceable> |
+ <replaceable>domain</replaceable> trust-anchor <replaceable>domain</replaceable> ); </optional>
<optional> dnssec-must-be-secure <replaceable>domain yes_or_no</replaceable>; </optional>
<optional> dnssec-accept-expired <replaceable>yes_or_no</replaceable>; </optional>
<optional> forward ( <replaceable>only</replaceable> | <replaceable>first</replaceable> ); </optional>
@@ -4788,12 +5030,14 @@ category notify { null; };
... }; </optional>
<optional> check-names ( <replaceable>master</replaceable> | <replaceable>slave</replaceable> | <replaceable>response</replaceable> )
( <replaceable>warn</replaceable> | <replaceable>fail</replaceable> | <replaceable>ignore</replaceable> ); </optional>
+ <optional> check-dup-records ( <replaceable>warn</replaceable> | <replaceable>fail</replaceable> | <replaceable>ignore</replaceable> ); </optional>
<optional> check-mx ( <replaceable>warn</replaceable> | <replaceable>fail</replaceable> | <replaceable>ignore</replaceable> ); </optional>
<optional> check-wildcard <replaceable>yes_or_no</replaceable>; </optional>
<optional> check-integrity <replaceable>yes_or_no</replaceable>; </optional>
<optional> check-mx-cname ( <replaceable>warn</replaceable> | <replaceable>fail</replaceable> | <replaceable>ignore</replaceable> ); </optional>
<optional> check-srv-cname ( <replaceable>warn</replaceable> | <replaceable>fail</replaceable> | <replaceable>ignore</replaceable> ); </optional>
<optional> check-sibling <replaceable>yes_or_no</replaceable>; </optional>
+ <optional> allow-new-zones { <replaceable>yes_or_no</replaceable> }; </optional>
<optional> allow-notify { <replaceable>address_match_list</replaceable> }; </optional>
<optional> allow-query { <replaceable>address_match_list</replaceable> }; </optional>
<optional> allow-query-on { <replaceable>address_match_list</replaceable> }; </optional>
@@ -4805,6 +5049,8 @@ category notify { null; };
<optional> allow-update { <replaceable>address_match_list</replaceable> }; </optional>
<optional> allow-update-forwarding { <replaceable>address_match_list</replaceable> }; </optional>
<optional> update-check-ksk <replaceable>yes_or_no</replaceable>; </optional>
+ <optional> dnssec-dnskey-kskonly <replaceable>yes_or_no</replaceable>; </optional>
+ <optional> dnssec-secure-to-insecure <replaceable>yes_or_no</replaceable> ;</optional>
<optional> try-tcp-refresh <replaceable>yes_or_no</replaceable>; </optional>
<optional> allow-v6-synthesis { <replaceable>address_match_list</replaceable> }; </optional>
<optional> blackhole { <replaceable>address_match_list</replaceable> }; </optional>
@@ -4816,12 +5062,12 @@ category notify { null; };
<optional> listen-on-v6 <optional> port <replaceable>ip_port</replaceable> </optional> { <replaceable>address_match_list</replaceable> }; </optional>
<optional> query-source ( ( <replaceable>ip4_addr</replaceable> | <replaceable>*</replaceable> )
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> |
- <optional> address ( <replaceable>ip4_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
- <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> ) ; </optional>
+ <optional> address ( <replaceable>ip4_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
+ <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> ) ; </optional>
<optional> query-source-v6 ( ( <replaceable>ip6_addr</replaceable> | <replaceable>*</replaceable> )
- <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> |
- <optional> address ( <replaceable>ip6_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
- <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> ) ; </optional>
+ <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> |
+ <optional> address ( <replaceable>ip6_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
+ <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> ) ; </optional>
<optional> use-queryport-pool <replaceable>yes_or_no</replaceable>; </optional>
<optional> queryport-pool-ports <replaceable>number</replaceable>; </optional>
<optional> queryport-pool-updateinterval <replaceable>number</replaceable>; </optional>
@@ -4842,13 +5088,15 @@ category notify { null; };
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> alt-transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
- <optional> alt-transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
+ <optional> alt-transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>)
+ <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> use-alt-transfer-source <replaceable>yes_or_no</replaceable>; </optional>
<optional> notify-delay <replaceable>seconds</replaceable> ; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-to-soa <replaceable>yes_or_no</replaceable> ; </optional>
- <optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
+ <optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ;
+ <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> max-ixfr-log-size <replaceable>number</replaceable>; </optional>
<optional> max-journal-size <replaceable>size_spec</replaceable>; </optional>
<optional> coresize <replaceable>size_spec</replaceable> ; </optional>
@@ -4884,12 +5132,25 @@ category notify { null; };
<optional> random-device <replaceable>path_name</replaceable> ; </optional>
<optional> max-cache-size <replaceable>size_spec</replaceable> ; </optional>
<optional> match-mapped-addresses <replaceable>yes_or_no</replaceable>; </optional>
+ <optional> filter-aaaa-on-v4 ( <replaceable>yes_or_no</replaceable> | <replaceable>break-dnssec</replaceable> ); </optional>
+ <optional> filter-aaaa { <replaceable>address_match_list</replaceable> }; </optional>
+ <optional> dns64 <replaceable>IPv6-prefix</replaceable> {
+ <optional> clients { <replaceable>address_match_list</replaceable> }; </optional>
+ <optional> mapped { <replaceable>address_match_list</replaceable> }; </optional>
+ <optional> exclude { <replaceable>address_match_list</replaceable> }; </optional>
+ <optional> suffix IPv6-address; </optional>
+ <optional> recursive-only <replaceable>yes_or_no</replaceable>; </optional>
+ <optional> break-dnssec <replaceable>yes_or_no</replaceable>; </optional>
+ }; </optional>;
+ <optional> dns64-server <replaceable>name</replaceable> </optional>
+ <optional> dns64-contact <replaceable>name</replaceable> </optional>
<optional> preferred-glue ( <replaceable>A</replaceable> | <replaceable>AAAA</replaceable> | <replaceable>NONE</replaceable> ); </optional>
<optional> edns-udp-size <replaceable>number</replaceable>; </optional>
<optional> max-udp-size <replaceable>number</replaceable>; </optional>
<optional> root-delegation-only <optional> exclude { <replaceable>namelist</replaceable> } </optional> ; </optional>
<optional> querylog <replaceable>yes_or_no</replaceable> ; </optional>
- <optional> disable-algorithms <replaceable>domain</replaceable> { <replaceable>algorithm</replaceable>; <optional> <replaceable>algorithm</replaceable>; </optional> }; </optional>
+ <optional> disable-algorithms <replaceable>domain</replaceable> { <replaceable>algorithm</replaceable>;
+ <optional> <replaceable>algorithm</replaceable>; </optional> }; </optional>
<optional> acache-enable <replaceable>yes_or_no</replaceable> ; </optional>
<optional> acache-cleaning-interval <replaceable>number</replaceable>; </optional>
<optional> max-acache-size <replaceable>size_spec</replaceable> ; </optional>
@@ -4902,6 +5163,10 @@ category notify { null; };
<optional> disable-empty-zone <replaceable>zone_name</replaceable> ; </optional>
<optional> zero-no-soa-ttl <replaceable>yes_or_no</replaceable> ; </optional>
<optional> zero-no-soa-ttl-cache <replaceable>yes_or_no</replaceable> ; </optional>
+ <optional> resolver-query-timeout <replaceable>number</replaceable> ; </optional>
+ <optional> deny-answer-addresses { <replaceable>address_match_list</replaceable> } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;</optional>
+ <optional> deny-answer-aliases { <replaceable>namelist</replaceable> } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;</optional>
+ <optional> response-policy { <replaceable>zone_name</replaceable> <optional> policy <replaceable>given</replaceable> | <replaceable>no-op</replaceable> | <replaceable>nxdomain</replaceable> | <replaceable>nodata</replaceable> | <replaceable>cname domain</replaceable> </optional> ; } ; </optional>
};
</programlisting>
@@ -4923,6 +5188,102 @@ category notify { null; };
<variablelist>
+ <varlistentry>
+ <term><command>attach-cache</command></term>
+ <listitem>
+ <para>
+ Allows multiple views to share a single cache
+ database.
+ Each view has its own cache database by default, but
+ if multiple views have the same operational policy
+ for name resolution and caching, those views can
+ share a single cache to save memory and possibly
+ improve resolution efficiency by using this option.
+ </para>
+
+ <para>
+ The <command>attach-cache</command> option
+ may also be specified in <command>view</command>
+ statements, in which case it overrides the
+ global <command>attach-cache</command> option.
+ </para>
+
+ <para>
+ The <replaceable>cache_name</replaceable> specifies
+ the cache to be shared.
+ When the <command>named</command> server configures
+ views which are supposed to share a cache, it
+ creates a cache with the specified name for the
+ first view of these sharing views.
+ The rest of the views will simply refer to the
+ already created cache.
+ </para>
+
+ <para>
+ One common configuration to share a cache would be to
+ allow all views to share a single cache.
+ This can be done by specifying
+ the <command>attach-cache</command> as a global
+ option with an arbitrary name.
+ </para>
+
+ <para>
+ Another possible operation is to allow a subset of
+ all views to share a cache while the others to
+ retain their own caches.
+ For example, if there are three views A, B, and C,
+ and only A and B should share a cache, specify the
+ <command>attach-cache</command> option as a view A (or
+ B)'s option, referring to the other view name:
+ </para>
+
+<programlisting>
+ view "A" {
+ // this view has its own cache
+ ...
+ };
+ view "B" {
+ // this view refers to A's cache
+ attach-cache "A";
+ };
+ view "C" {
+ // this view has its own cache
+ ...
+ };
+</programlisting>
+
+ <para>
+ Views that share a cache must have the same policy
+ on configurable parameters that may affect caching.
+ The current implementation requires the following
+ configurable options be consistent among these
+ views:
+ <command>check-names</command>,
+ <command>cleaning-interval</command>,
+ <command>dnssec-accept-expired</command>,
+ <command>dnssec-validation</command>,
+ <command>max-cache-ttl</command>,
+ <command>max-ncache-ttl</command>,
+ <command>max-cache-size</command>, and
+ <command>zero-no-soa-ttl</command>.
+ </para>
+
+ <para>
+ Note that there may be other parameters that may
+ cause confusion if they are inconsistent for
+ different views that share a single cache.
+ For example, if these views define different sets of
+ forwarders that can return different answers for the
+ same question, sharing the answer does not make
+ sense or could even be harmful.
+ It is administrator's responsibility to ensure
+ configuration differences in different views do
+ not cause disruption with a shared cache.
+ </para>
+ </listitem>
+
+ </varlistentry>
+
<varlistentry>
<term><command>directory</command></term>
<listitem>
@@ -4950,10 +5311,24 @@ category notify { null; };
When performing dynamic update of secure zones, the
directory where the public and private DNSSEC key files
should be found, if different than the current working
- directory. The directory specified must be an absolute
- path. (Note that this option has no effect on the paths
- for files containing non-DNSSEC keys such as the
- <filename>rndc.key</filename>.
+ directory. (Note that this option has no effect on the
+ paths for files containing non-DNSSEC keys such as
+ <filename>bind.keys</filename>,
+ <filename>rndc.key</filename> or
+ <filename>session.key</filename>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>managed-keys-directory</command></term>
+ <listitem>
+ <para>
+ The directory used to hold the files used to track managed keys.
+ By default it is the working directory. It there are no
+ views then the file <filename>managed-keys.bind</filename>
+ otherwise a SHA256 hash of the view name is used with
+ <filename>.mkeys</filename> extension added.
</para>
</listitem>
</varlistentry>
@@ -4973,19 +5348,33 @@ category notify { null; };
</varlistentry>
<varlistentry>
+ <term><command>tkey-gssapi-keytab</command></term>
+ <listitem>
+ <para>
+ The KRB5 keytab file to use for GSS-TSIG updates. If
+ this option is set and tkey-gssapi-credential is not
+ set, then updates will be allowed with any key
+ matching a principal in the specified keytab.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><command>tkey-gssapi-credential</command></term>
<listitem>
<para>
The security credential with which the server should
authenticate keys requested by the GSS-TSIG protocol.
Currently only Kerberos 5 authentication is available
- and the credential is a Kerberos principal which
- the server can acquire through the default system
- key file, normally <filename>/etc/krb5.keytab</filename>.
- Normally this principal is of the form
- "<userinput>DNS/</userinput><varname>server.domain</varname>".
- To use GSS-TSIG, <command>tkey-domain</command>
- must also be set.
+ and the credential is a Kerberos principal which the
+ server can acquire through the default system key
+ file, normally <filename>/etc/krb5.keytab</filename>.
+ The location keytab file can be overridden using the
+ tkey-gssapi-keytab option. Normally this principal is
+ of the form "<userinput>DNS/</userinput><varname>server.domain</varname>".
+ To use GSS-TSIG, <command>tkey-domain</command> must
+ also be set if a specific keytab is not set with
+ tkey-gssapi-keytab.
</para>
</listitem>
</varlistentry>
@@ -5007,7 +5396,8 @@ category notify { null; };
should be the server's domain name, or an otherwise
non-existent subdomain like
"_tkey.<varname>domainname</varname>". If you are
- using GSS-TSIG, this variable must be defined.
+ using GSS-TSIG, this variable must be defined, unless
+ you specify a specific keytab using tkey-gssapi-keytab.
</para>
</listitem>
</varlistentry>
@@ -5106,6 +5496,84 @@ category notify { null; };
</varlistentry>
<varlistentry>
+ <term><command>bindkeys-file</command></term>
+ <listitem>
+ <para>
+ The pathname of a file to override the built-in trusted
+ keys provided by <command>named</command>.
+ See the discussion of <command>dnssec-lookaside</command>
+ and <command>dnssec-validation</command> for details.
+ If not specified, the default is
+ <filename>/etc/bind.keys</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>secroots-file</command></term>
+ <listitem>
+ <para>
+ The pathname of the file the server dumps
+ security roots to when instructed to do so with
+ <command>rndc secroots</command>.
+ If not specified, the default is <filename>named.secroots</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>session-keyfile</command></term>
+ <listitem>
+ <para>
+ The pathname of the file into which to write a TSIG
+ session key generated by <command>named</command> for use by
+ <command>nsupdate -l</command>. If not specified, the
+ default is <filename>/var/run/named/session.key</filename>.
+ (See <xref linkend="dynamic_update_policies"/>, and in
+ particular the discussion of the
+ <command>update-policy</command> statement's
+ <userinput>local</userinput> option for more
+ information about this feature.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>session-keyname</command></term>
+ <listitem>
+ <para>
+ The key name to use for the TSIG session key.
+ If not specified, the default is "local-ddns".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>session-keyalg</command></term>
+ <listitem>
+ <para>
+ The algorithm to use for the TSIG session key.
+ Valid values are hmac-sha1, hmac-sha224, hmac-sha256,
+ hmac-sha384, hmac-sha512 and hmac-md5. If not
+ specified, the default is hmac-sha256.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>session-keyfile</command></term>
+ <listitem>
+ <para>
+ The pathname of the file into which to write a session TSIG
+ key for use by <command>nsupdate -l</command>. (See the
+ discussion of the <command>update-policy</command>
+ statement's <userinput>local</userinput> option for more
+ details on this feature.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><command>port</command></term>
<listitem>
<para>
@@ -5167,14 +5635,14 @@ category notify { null; };
<para>
DS queries are expected to be made to and be answered by
delegation only zones. Such queries and responses are
- treated as a exception to delegation-only processing
+ treated as an exception to delegation-only processing
and are not converted to NXDOMAIN responses provided
a CNAME is not discovered at the query name.
</para>
<para>
If a delegation only zone server also serves a child
zone it is not always possible to determine whether
- a answer comes from the delegation only zone or the
+ an answer comes from the delegation only zone or the
child zone. SOA NS and DNSKEY records are apex
only records and a matching response that contains
these records or DS is treated as coming from a
@@ -5223,21 +5691,46 @@ options {
<term><command>dnssec-lookaside</command></term>
<listitem>
<para>
- When set, <command>dnssec-lookaside</command>
- provides the
- validator with an alternate method to validate DNSKEY records
- at the
- top of a zone. When a DNSKEY is at or below a domain
- specified by the
- deepest <command>dnssec-lookaside</command>, and
- the normal DNSSEC validation
- has left the key untrusted, the trust-anchor will be append to
- the key
- name and a DLV record will be looked up to see if it can
- validate the
- key. If the DLV record validates a DNSKEY (similarly to the
- way a DS
+ When set, <command>dnssec-lookaside</command> provides the
+ validator with an alternate method to validate DNSKEY
+ records at the top of a zone. When a DNSKEY is at or
+ below a domain specified by the deepest
+ <command>dnssec-lookaside</command>, and the normal DNSSEC
+ validation has left the key untrusted, the trust-anchor
+ will be appended to the key name and a DLV record will be
+ looked up to see if it can validate the key. If the DLV
+ record validates a DNSKEY (similarly to the way a DS
record does) the DNSKEY RRset is deemed to be trusted.
+ </para>
+ <para>
+ If <command>dnssec-lookaside</command> is set to
+ <userinput>auto</userinput>, then built-in default
+ values for the DLV domain and trust anchor will be
+ used, along with a built-in key for validation.
+ </para>
+ <para>
+ The default DLV key is stored in the file
+ <filename>bind.keys</filename>;
+ <command>named</command> will load that key at
+ startup if <command>dnssec-lookaside</command> is set to
+ <constant>auto</constant>. A copy of the file is
+ installed along with <acronym>BIND</acronym> 9, and is
+ current as of the release date. If the DLV key expires, a
+ new copy of <filename>bind.keys</filename> can be downloaded
+ from <ulink>https://www.isc.org/solutions/dlv</ulink>.
+ </para>
+ <para>
+ (To prevent problems if <filename>bind.keys</filename> is
+ not found, the current key is also compiled in to
+ <command>named</command>. Relying on this is not
+ recommended, however, as it requires <command>named</command>
+ to be recompiled with a new key when the DLV key expires.)
+ </para>
+ <para>
+ NOTE: <command>named</command> only loads certain specific
+ keys from <filename>bind.keys</filename>: those for the
+ DLV zone and for the DNS root zone. The file cannot be
+ used to store keys for other zones.
</para>
</listitem>
</varlistentry>
@@ -5246,21 +5739,86 @@ options {
<term><command>dnssec-must-be-secure</command></term>
<listitem>
<para>
- Specify hierarchies which must be or may not be secure (signed and
- validated).
- If <userinput>yes</userinput>, then <command>named</command> will only accept
- answers if they
- are secure.
- If <userinput>no</userinput>, then normal DNSSEC validation
- applies
- allowing for insecure answers to be accepted.
- The specified domain must be under a <command>trusted-key</command> or
- <command>dnssec-lookaside</command> must be
- active.
+ Specify hierarchies which must be or may not be secure
+ (signed and validated). If <userinput>yes</userinput>,
+ then <command>named</command> will only accept answers if
+ they are secure. If <userinput>no</userinput>, then normal
+ DNSSEC validation applies allowing for insecure answers to
+ be accepted. The specified domain must be under a
+ <command>trusted-keys</command> or
+ <command>managed-keys</command> statement, or
+ <command>dnssec-lookaside</command> must be active.
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><command>dns64</command></term>
+ <listitem>
+ <para>
+ This directive instructs <command>named</command> to
+ return mapped IPv4 addresses to AAAA queries when
+ there are no AAAA records. It is intended to be
+ used in conjunction with a NAT64. Each
+ <command>dns64</command> defines one DNS64 prefix.
+ Multiple DNS64 prefixes can be defined.
+ </para>
+ <para>
+ Compatible IPv6 prefixes have lengths of 32, 40, 48, 56,
+ 64 and 96 as per RFC 6052.
+ </para>
+ <para>
+ Additionally a reverse IP6.ARPA zone will be created for
+ the prefix to provide a mapping from the IP6.ARPA names
+ to the corresponding IN-ADDR.ARPA names using synthesized
+ CNAMEs. <command>dns64-server</command> and
+ <command>dns64-contact</command> can be used to specify
+ the name of the server and contact for the zones. These
+ are settable at the view / options level. These are
+ not settable on a per-prefix basis.
+ </para>
+ <para>
+ Each <command>dns64</command> supports an optional
+ <command>clients</command> ACL that determines which
+ clients are affected by this directive. If not defined,
+ it defaults to <userinput>any;</userinput>.
+ </para>
+ <para>
+ Each <command>dns64</command> supports an optional
+ <command>mapped</command> ACL that selects which
+ IPv4 addresses are to be mapped in the corresponding
+ A RRset. If not defined it defaults to
+ <userinput>any;</userinput>.
+ </para>
+ <para>
+ Each <command>dns64</command> supports an optional
+ <command>exclude</command> ACL that selects which
+ IPv6 addresses will be ignored for the purposes
+ of determining whether dns64 is to be applied.
+ Any non-matching address will prevent further
+ DNS64 processing from occurring for this client.
+ </para>
+ <para>
+ A optional <command>suffix</command> can also
+ be defined to set the bits trailing the mapped
+ IPv4 address bits. By default these bits are
+ set to <userinput>::</userinput>. The bits
+ matching the prefix and mapped IPv4 address
+ must be zero.
+ </para>
+<programlisting>
+ acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
+
+ dns64 64:FF9B::/96 {
+ clients { any; };
+ mapped { !rfc1918; any; };
+ exclude { 64:FF9B::/96; ::ffff:0000:0000/96; };
+ suffix ::;
+ };
+</programlisting>
+ </listitem>
+ </varlistentry>
+
</variablelist>
<sect3 id="boolean_options">
@@ -5269,6 +5827,18 @@ options {
<variablelist>
<varlistentry>
+ <term><command>allow-new-zones</command></term>
+ <listitem>
+ <para>
+ If <userinput>yes</userinput>, then zones can be
+ added at runtime via <command>rndc addzone</command>
+ or deleted via <command>rndc delzone</command>.
+ The default is <userinput>no</userinput>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><command>auth-nxdomain</command></term>
<listitem>
<para>
@@ -5755,6 +6325,7 @@ options {
off
on a per-zone basis by specifying <command>zone-statistics no</command>
in the <command>zone</command> statement).
+ The default is <userinput>no</userinput>.
These statistics may be accessed
using <command>rndc stats</command>, which will
dump them to the file listed
@@ -5928,6 +6499,60 @@ options {
</varlistentry>
<varlistentry>
+ <term><command>filter-aaaa-on-v4</command></term>
+ <listitem>
+ <para>
+ This option is only available when
+ <acronym>BIND</acronym> 9 is compiled with the
+ <userinput>--enable-filter-aaaa</userinput> option on the
+ "configure" command line. It is intended to help the
+ transition from IPv4 to IPv6 by not giving IPv6 addresses
+ to DNS clients unless they have connections to the IPv6
+ Internet. This is not recommended unless absolutely
+ necessary. The default is <userinput>no</userinput>.
+ The <command>filter-aaaa-on-v4</command> option
+ may also be specified in <command>view</command> statements
+ to override the global <command>filter-aaaa-on-v4</command>
+ option.
+ </para>
+ <para>
+ If <userinput>yes</userinput>,
+ the DNS client is at an IPv4 address, in <command>filter-aaaa</command>,
+ and if the response does not include DNSSEC signatures,
+ then all AAAA records are deleted from the response.
+ This filtering applies to all responses and not only
+ authoritative responses.
+ </para>
+ <para>
+ If <userinput>break-dnssec</userinput>,
+ then AAAA records are deleted even when dnssec is enabled.
+ As suggested by the name, this makes the response not verify,
+ because the DNSSEC protocol is designed detect deletions.
+ </para>
+ <para>
+ This mechanism can erroneously cause other servers to
+ not give AAAA records to their clients.
+ A recursing server with both IPv6 and IPv4 network connections
+ that queries an authoritative server using this mechanism
+ via IPv4 will be denied AAAA records even if its client is
+ using IPv6.
+ </para>
+ <para>
+ This mechanism is applied to authoritative as well as
+ non-authoritative records.
+ A client using IPv4 that is not allowed recursion can
+ erroneously be given AAAA records because the server is not
+ allowed to check for A records.
+ </para>
+ <para>
+ Some AAAA records are given to IPv4 clients in glue records.
+ IPv4 clients that are servers can then erroneously
+ answer requests for AAAA records received via IPv4.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><command>ixfr-from-differences</command></term>
<listitem>
<para>
@@ -5996,7 +6621,15 @@ options {
Enable DNSSEC validation in <command>named</command>.
Note <command>dnssec-enable</command> also needs to be
set to <userinput>yes</userinput> to be effective.
- The default is <userinput>yes</userinput>.
+ If set to <userinput>no</userinput>, DNSSEC validation
+ is disabled. If set to <userinput>auto</userinput>,
+ DNSSEC validation is enabled, and a default
+ trust-anchor for the DNS root zone is used. If set to
+ <userinput>yes</userinput>, DNSSEC validation is enabled,
+ but a trust anchor must be manually configured using
+ a <command>trusted-keys</command> or
+ <command>managed-keys</command> statement. The default
+ is <userinput>yes</userinput>.
</para>
</listitem>
</varlistentry>
@@ -6007,7 +6640,9 @@ options {
<para>
Accept expired signatures when verifying DNSSEC signatures.
The default is <userinput>no</userinput>.
- Setting this option to "yes" leaves <command>named</command> vulnerable to replay attacks.
+ Setting this option to <userinput>yes</userinput>
+ leaves <command>named</command> vulnerable to
+ replay attacks.
</para>
</listitem>
</varlistentry>
@@ -6057,6 +6692,19 @@ options {
</varlistentry>
<varlistentry>
+ <term><command>check-dup-records</command></term>
+ <listitem>
+ <para>
+ Check master zones for records that are treated as different
+ by DNSSEC but are semantically equal in plain DNS. The
+ default is to <command>warn</command>. Other possible
+ values are <command>fail</command> and
+ <command>ignore</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><command>check-mx</command></term>
<listitem>
<para>
@@ -6161,13 +6809,49 @@ options {
<term><command>update-check-ksk</command></term>
<listitem>
<para>
- When regenerating the RRSIGs following a UPDATE
- request to a secure zone, check the KSK flag on
- the DNSKEY RR to determine if this key should be
- used to generate the RRSIG. This flag is ignored
- if there are not DNSKEY RRs both with and without
- a KSK.
- The default is <command>yes</command>.
+ When set to the default value of <literal>yes</literal>,
+ check the KSK bit in each key to determine how the key
+ should be used when generating RRSIGs for a secure zone.
+ </para>
+ <para>
+ Ordinarily, zone-signing keys (that is, keys without the
+ KSK bit set) are used to sign the entire zone, while
+ key-signing keys (keys with the KSK bit set) are only
+ used to sign the DNSKEY RRset at the zone apex.
+ However, if this option is set to <literal>no</literal>,
+ then the KSK bit is ignored; KSKs are treated as if they
+ were ZSKs and are used to sign the entire zone. This is
+ similar to the <command>dnssec-signzone -z</command>
+ command line option.
+ </para>
+ <para>
+ When this option is set to <literal>yes</literal>, there
+ must be at least two active keys for every algorithm
+ represented in the DNSKEY RRset: at least one KSK and one
+ ZSK per algorithm. If there is any algorithm for which
+ this requirement is not met, this option will be ignored
+ for that algorithm.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>dnssec-dnskey-kskonly</command></term>
+ <listitem>
+ <para>
+ When this option and <command>update-check-ksk</command>
+ are both set to <literal>yes</literal>, only key-signing
+ keys (that is, keys with the KSK bit set) will be used
+ to sign the DNSKEY RRset at the zone apex. Zone-signing
+ keys (keys without the KSK bit set) will be used to sign
+ the remainder of the zone, but not the DNSKEY RRset.
+ This is similar to the
+ <command>dnssec-signzone -x</command> command line option.
+ </para>
+ <para>
+ The default is <command>no</command>. If
+ <command>update-check-ksk</command> is set to
+ <literal>no</literal>, this option is ignored.
</para>
</listitem>
</varlistentry>
@@ -6183,6 +6867,34 @@ options {
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><command>dnssec-secure-to-insecure</command></term>
+ <listitem>
+ <para>
+ Allow a dynamic zone to transition from secure to
+ insecure (i.e., signed to unsigned) by deleting all
+ of the DNSKEY records. The default is <command>no</command>.
+ If set to <command>yes</command>, and if the DNSKEY RRset
+ at the zone apex is deleted, all RRSIG and NSEC records
+ will be removed from the zone as well.
+ </para>
+ <para>
+ If the zone uses NSEC3, then it is also necessary to
+ delete the NSEC3PARAM RRset from the zone apex; this will
+ cause the removal of all corresponding NSEC3 records.
+ (It is expected that this requirement will be eliminated
+ in a future release.)
+ </para>
+ <para>
+ Note that if a zone has been configured with
+ <command>auto-dnssec maintain</command> and the
+ private keys remain accessible in the key repository,
+ then the zone will be automatically signed again the
+ next time <command>named</command> is started.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</sect3>
@@ -6495,6 +7207,29 @@ options {
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><command>filter-aaaa</command></term>
+ <listitem>
+ <para>
+ Specifies a list of addresses to which
+ <command>filter-aaaa-on-v4</command>
+ is applies. The default is <userinput>any</userinput>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>resolver-query-timeout</command></term>
+ <listitem>
+ <para>
+ The amount of time the resolver will spend attempting
+ to resolve a recursive query before failing. The
+ default is <literal>10</literal> and the maximum is
+ <literal>30</literal>. Setting it to <literal>0</literal>
+ will result in the default being used.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</sect3>
@@ -7542,20 +8277,26 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</para>
<programlisting>sortlist {
- { localhost; // IF the local host
- { localnets; // THEN first fit on the
- 192.168.1/24; // following nets
+ // IF the local host
+ // THEN first fit on the following nets
+ { localhost;
+ { localnets;
+ 192.168.1/24;
{ 192.168.2/24; 192.168.3/24; }; }; };
- { 192.168.1/24; // IF on class C 192.168.1
- { 192.168.1/24; // THEN use .1, or .2 or .3
+ // IF on class C 192.168.1 THEN use .1, or .2 or .3
+ { 192.168.1/24;
+ { 192.168.1/24;
{ 192.168.2/24; 192.168.3/24; }; }; };
- { 192.168.2/24; // IF on class C 192.168.2
- { 192.168.2/24; // THEN use .2, or .1 or .3
+ // IF on class C 192.168.2 THEN use .2, or .1 or .3
+ { 192.168.2/24;
+ { 192.168.2/24;
{ 192.168.1/24; 192.168.3/24; }; }; };
- { 192.168.3/24; // IF on class C 192.168.3
- { 192.168.3/24; // THEN use .3, or .1 or .2
+ // IF on class C 192.168.3 THEN use .3, or .1 or .2
+ { 192.168.3/24;
+ { 192.168.3/24;
{ 192.168.1/24; 192.168.2/24; }; }; };
- { { 192.168.4/24; 192.168.5/24; }; // if .4 or .5, prefer that net
+ // IF .4 or .5 THEN prefer that net
+ { { 192.168.4/24; 192.168.5/24; };
};
};</programlisting>
@@ -7772,7 +8513,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
DNSSEC signatures automatically generated as a
result of dynamic updates (<xref
linkend="dynamic_update"/>) will expire. There
- is a optional second field which specifies how
+ is an optional second field which specifies how
long before expiry that the signatures will be
regenerated. If not specified, the signatures will
be regenerated at 1/4 of base interval. The second
@@ -7877,7 +8618,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
<para>
Sets the advertised EDNS UDP buffer size in bytes
to control the size of packets received.
- Valid values are 512 to 4096 (values outside this range
+ Valid values are 1024 to 4096 (values outside this range
will be silently adjusted). The default value
is 4096. The usual reason for setting
<command>edns-udp-size</command> to a non-default
@@ -7885,24 +8626,36 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
firewalls that block fragmented packets and/or
block UDP packets that are greater than 512 bytes.
</para>
+ <para>
+ <command>named</command> will fallback to using 512 bytes
+ if it get a series of timeout at the initial value. 512
+ bytes is not being offered to encourage sites to fix their
+ firewalls. Small EDNS UDP sizes will result in the
+ excessive use of TCP.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>max-udp-size</command></term>
- <listitem>
- <para>
- Sets the maximum EDNS UDP message size <command>named</command> will
- send in bytes. Valid values are 512 to 4096 (values outside
- this range will be silently adjusted). The default
+ <listitem>
+ <para>
+ Sets the maximum EDNS UDP message size
+ <command>named</command> will send in bytes.
+ Valid values are 512 to 4096 (values outside this
+ range will be silently adjusted). The default
value is 4096. The usual reason for setting
- <command>max-udp-size</command> to a non-default value is to get UDP
- answers to pass through broken firewalls that
- block fragmented packets and/or block UDP packets
- that are greater than 512 bytes.
+ <command>max-udp-size</command> to a non-default
+ value is to get UDP answers to pass through broken
+ firewalls that block fragmented packets and/or
+ block UDP packets that are greater than 512 bytes.
This is independent of the advertised receive
buffer (<command>edns-udp-size</command>).
</para>
+ <para>
+ Setting this to a low value will encourage additional
+ TCP traffic to the nameserver.
+ </para>
</listitem>
</varlistentry>
@@ -8081,7 +8834,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
<para>
Named will attempt to determine if a built-in zone already exists
or is active (covered by a forward-only forwarding declaration)
- and will not create a empty zone in that case.
+ and will not create an empty zone in that case.
</para>
<para>
The current list of empty zones is:
@@ -8308,6 +9061,282 @@ XXX: end of RFC1918 addresses #defined out -->
</sect3>
+ <sect3>
+ <title>Content Filtering</title>
+ <para>
+ <acronym>BIND</acronym> 9 provides the ability to filter
+ out DNS responses from external DNS servers containing
+ certain types of data in the answer section.
+ Specifically, it can reject address (A or AAAA) records if
+ the corresponding IPv4 or IPv6 addresses match the given
+ <varname>address_match_list</varname> of the
+ <command>deny-answer-addresses</command> option.
+ It can also reject CNAME or DNAME records if the "alias"
+ name (i.e., the CNAME alias or the substituted query name
+ due to DNAME) matches the
+ given <varname>namelist</varname> of the
+ <command>deny-answer-aliases</command> option, where
+ "match" means the alias name is a subdomain of one of
+ the <varname>name_list</varname> elements.
+ If the optional <varname>namelist</varname> is specified
+ with <command>except-from</command>, records whose query name
+ matches the list will be accepted regardless of the filter
+ setting.
+ Likewise, if the alias name is a subdomain of the
+ corresponding zone, the <command>deny-answer-aliases</command>
+ filter will not apply;
+ for example, even if "example.com" is specified for
+ <command>deny-answer-aliases</command>,
+ </para>
+<programlisting>www.example.com. CNAME xxx.example.com.</programlisting>
+
+ <para>
+ returned by an "example.com" server will be accepted.
+ </para>
+
+ <para>
+ In the <varname>address_match_list</varname> of the
+ <command>deny-answer-addresses</command> option, only
+ <varname>ip_addr</varname>
+ and <varname>ip_prefix</varname>
+ are meaningful;
+ any <varname>key_id</varname> will be silently ignored.
+ </para>
+
+ <para>
+ If a response message is rejected due to the filtering,
+ the entire message is discarded without being cached, and
+ a SERVFAIL error will be returned to the client.
+ </para>
+
+ <para>
+ This filtering is intended to prevent "DNS rebinding attacks," in
+ which an attacker, in response to a query for a domain name the
+ attacker controls, returns an IP address within your own network or
+ an alias name within your own domain.
+ A naive web browser or script could then serve as an
+ unintended proxy, allowing the attacker
+ to get access to an internal node of your local network
+ that couldn't be externally accessed otherwise.
+ See the paper available at
+ <ulink>
+ http://portal.acm.org/citation.cfm?id=1315245.1315298
+ </ulink>
+ for more details about the attacks.
+ </para>
+
+ <para>
+ For example, if you own a domain named "example.net" and
+ your internal network uses an IPv4 prefix 192.0.2.0/24,
+ you might specify the following rules:
+ </para>
+
+<programlisting>deny-answer-addresses { 192.0.2.0/24; } except-from { "example.net"; };
+deny-answer-aliases { "example.net"; };
+</programlisting>
+
+ <para>
+ If an external attacker lets a web browser in your local
+ network look up an IPv4 address of "attacker.example.com",
+ the attacker's DNS server would return a response like this:
+ </para>
+
+<programlisting>attacker.example.com. A 192.0.2.1</programlisting>
+
+ <para>
+ in the answer section.
+ Since the rdata of this record (the IPv4 address) matches
+ the specified prefix 192.0.2.0/24, this response will be
+ ignored.
+ </para>
+
+ <para>
+ On the other hand, if the browser looks up a legitimate
+ internal web server "www.example.net" and the
+ following response is returned to
+ the <acronym>BIND</acronym> 9 server
+ </para>
+
+<programlisting>www.example.net. A 192.0.2.2</programlisting>
+
+ <para>
+ it will be accepted since the owner name "www.example.net"
+ matches the <command>except-from</command> element,
+ "example.net".
+ </para>
+
+ <para>
+ Note that this is not really an attack on the DNS per se.
+ In fact, there is nothing wrong for an "external" name to
+ be mapped to your "internal" IP address or domain name
+ from the DNS point of view.
+ It might actually be provided for a legitimate purpose,
+ such as for debugging.
+ As long as the mapping is provided by the correct owner,
+ it is not possible or does not make sense to detect
+ whether the intent of the mapping is legitimate or not
+ within the DNS.
+ The "rebinding" attack must primarily be protected at the
+ application that uses the DNS.
+ For a large site, however, it may be difficult to protect
+ all possible applications at once.
+ This filtering feature is provided only to help such an
+ operational environment;
+ it is generally discouraged to turn it on unless you are
+ very sure you have no other choice and the attack is a
+ real threat for your applications.
+ </para>
+
+ <para>
+ Care should be particularly taken if you want to use this
+ option for addresses within 127.0.0.0/8.
+ These addresses are obviously "internal", but many
+ applications conventionally rely on a DNS mapping from
+ some name to such an address.
+ Filtering out DNS records containing this address
+ spuriously can break such applications.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Response Policy Zone (RPZ) Rewriting</title>
+ <para>
+ <acronym>BIND</acronym> 9 includes an intentionally limited
+ mechanism to modify DNS responses for recursive requests
+ similar to email anti-spam DNS blacklists.
+ All response policy zones are named in the
+ <command>response-policy</command> option for the view or among the
+ global options if there is no response-policy option for the view.
+ </para>
+
+ <para>
+ The rules encoded in a response policy zone (RPZ) are applied
+ only to responses to queries that ask for recursion (RD=1).
+ RPZs are normal DNS zones containing RRsets
+ that can be queried normally if allowed.
+ It is usually best to restrict those queries with something like
+ <command>allow-query {none; };</command> or
+ <command>allow-query { 127.0.0.1; };</command>.
+ </para>
+
+ <para>
+ There are four kinds of RPZ rewrite rules. QNAME rules are
+ applied to query names in requests and to targets of CNAME
+ records resolved in the process of generating the response.
+ The owner name of a QNAME rule is the query name relativized
+ to the RPZ.
+ The records in a rewrite rule are usually A, AAAA, or special
+ CNAMEs, but can be any type except DNAME.
+ </para>
+
+ <para>
+ IP rules are triggered by addresses in A and AAAA records.
+ All IP addresses in A or AAAA RRsets are tested and the rule
+ longest prefix is applied. Ties between rules with equal prefixes
+ are broken in favor of the first RPZ mentioned in the
+ response-policy option.
+ The rule matching the smallest IP address is chosen among equal
+ prefix rules from a single RPZ.
+ IP rules are expressed in RRsets with owner names that are
+ subdomains of rpz-ip and encoding an IP address block, reversed
+ as in IN-ARPA.
+ prefix.B.B.B.B with prefix between 1 and 32 and B between 1 and 255
+ encodes an IPv4 address.
+ IPv6 addresses are encoded by with prefix.W.W.W.W.W.W.W.W or
+ prefix.WORDS.zz.WORDS. The words in the standard IPv6 text
+ representation are reversed, "::" is replaced with ".zz.",
+ and ":" becomes ".".
+ </para>
+
+ <para>
+ NSDNAME rules match names in NS RRsets for the response or a
+ parent. They are encoded as subdomains of rpz-nsdomain relativized
+ to the RPZ origin name.
+ </para>
+
+ <para>
+ NSIP rules match IP addresses in A and AAAA RRsets for names of
+ responsible servers or the names that can be matched by NSDNAME
+ rules. The are encoded like IP rules except as subdomains of
+ rpz-nsip.
+ </para>
+
+ <para>
+ Authority verification issues and variations in authority data in
+ the current version of <acronym>BIND</acronym> 9 can cause
+ inconsistent results from NSIP and NSDNAME. So they are available
+ only when <acronym>BIND</acronym> is built with the
+ <userinput>--enable-rpz-nsip</userinput> or
+ <userinput>--enable-rpz-nsdname</userinput> options
+ on the "configure" command line.
+ </para>
+
+ <para>
+ Four policies can be expressed.
+ The <command>NXDOMAIN</command> policy causes a NXDOMAIN response
+ and is expressed with an RRset consisting of a single CNAME
+ whose target is the root domain (.).
+ <command>NODATA</command> generates NODATA or ANCOUNT=1 regardless
+ of query type.
+ It is expressed with a CNAME whose target is the wildcard
+ top-level domain (*.).
+ The <command>NO-OP</command> policy does not change the response
+ and is used to "poke holes" in policies for larger CIDR blocks or in
+ zones named later in the <command>response-policy</command> option.
+ The NO-OP policy is expressed by a CNAME with a target consisting
+ of the variable part of the owner name, such as "example.com." for
+ a QNAME rule or "128.1.0.0.127." for an IP rule.
+ The <command>CNAME</command> policy is used to replace the RRsets
+ of response.
+ A and AAAA RRsets are most common and useful to capture
+ an evil domain in a walled garden, but any valid set of RRsets
+ is possible.
+ </para>
+
+ <para>
+ All of the policies in an RPZ can be overridden with a
+ <command>policy</command> clause.
+ <command>given</command> says "do not override."
+ <command>no-op</command> says "do nothing" regardless of the policy
+ in RPZ records.
+ <command>nxdomain</command> causes all RPZ rules to generate
+ NXDOMAIN results.
+ <command>nodata</command> gives nodata.
+ <command>cname domain</command> causes all RPZ rules to act as if
+ the consisted of a "cname domain" record.
+ </para>
+
+ <para>
+ For example, you might use this option statement
+ </para>
+<programlisting>response-policy { zone "bl"; };</programlisting>
+ <para>
+ and this zone statement
+ </para>
+<programlisting>zone "bl" {type master; file "example/bl"; allow-query {none;}; };</programlisting>
+ <para>
+ with this zone file
+ </para>
+<programlisting>$TTL 1H
+@ SOA LOCALHOST. named-mgr.example.com (1 1h 15m 30d 2h)
+
+; QNAME rules
+nxdomain.domain.com CNAME .
+nodata.domain.com CNAME *.
+bad.domain.com A 10.0.0.1
+ AAAA 2001:2::1
+ok.domain.com CNAME ok.domain.com.
+*.badzone.domain.com CNAME garden.example.com.
+
+; IP rules rewriting all answers for 127/8 except 127.0.0.1
+8.0.0.0.127.ip CNAME .
+32.1.0.0.127.ip CNAME 32.1.0.0.127.
+
+; NSDNAME and NSIP rules
+ns.domain.com.rpz-nsdname CNAME .
+48.zz.2.2001.rpz-nsip CNAME .
+</programlisting>
+ </sect3>
</sect2>
<sect2 id="server_statement_grammar">
@@ -8327,8 +9356,10 @@ XXX: end of RFC1918 addresses #defined out -->
<optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
- <optional> query-source <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional> <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
- <optional> query-source-v6 <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional> <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
+ <optional> query-source <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
+ <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
+ <optional> query-source-v6 <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
+ <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
<optional> use-queryport-pool <replaceable>yes_or_no</replaceable>; </optional>
<optional> queryport-pool-ports <replaceable>number</replaceable>; </optional>
<optional> queryport-pool-updateinterval <replaceable>number</replaceable>; </optional>
@@ -8526,7 +9557,8 @@ XXX: end of RFC1918 addresses #defined out -->
<title><command>statistics-channels</command> Statement Grammar</title>
<programlisting><command>statistics-channels</command> {
- [ inet ( ip_addr | * ) [ port ip_port ] [allow { <replaceable> address_match_list </replaceable> } ]; ]
+ [ inet ( ip_addr | * ) [ port ip_port ]
+ [ allow { <replaceable> address_match_list </replaceable> } ]; ]
[ inet ...; ]
};
</programlisting>
@@ -8590,7 +9622,7 @@ XXX: end of RFC1918 addresses #defined out -->
</sect2>
- <sect2>
+ <sect2 id="trusted-keys">
<title><command>trusted-keys</command> Statement Grammar</title>
<programlisting><command>trusted-keys</command> {
@@ -8632,6 +9664,136 @@ XXX: end of RFC1918 addresses #defined out -->
in the key data, so the configuration may be split up into
multiple lines.
</para>
+ <para>
+ <command>trusted-keys</command> may be set at the top level
+ of <filename>named.conf</filename> or within a view. If it is
+ set in both places, they are additive: keys defined at the top
+ level are inherited by all views, but keys defined in a view
+ are only used within that view.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><command>managed-keys</command> Statement Grammar</title>
+
+<programlisting><command>managed-keys</command> {
+ <replaceable>string</replaceable> initial-key <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>string</replaceable> ;
+ <optional> <replaceable>string</replaceable> initial-key <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>string</replaceable> ; <optional>...</optional></optional>
+};
+</programlisting>
+
+ </sect2>
+ <sect2 id="managed-keys">
+ <title><command>managed-keys</command> Statement Definition
+ and Usage</title>
+ <para>
+ The <command>managed-keys</command> statement, like
+ <command>trusted-keys</command>, defines DNSSEC
+ security roots. The difference is that
+ <command>managed-keys</command> can be kept up to date
+ automatically, without intervention from the resolver
+ operator.
+ </para>
+ <para>
+ Suppose, for example, that a zone's key-signing
+ key was compromised, and the zone owner had to revoke and
+ replace the key. A resolver which had the old key in a
+ <command>trusted-keys</command> statement would be
+ unable to validate this zone any longer; it would
+ reply with a SERVFAIL response code. This would
+ continue until the resolver operator had updated the
+ <command>trusted-keys</command> statement with the new key.
+ </para>
+ <para>
+ If, however, the zone were listed in a
+ <command>managed-keys</command> statement instead, then the
+ zone owner could add a "stand-by" key to the zone in advance.
+ <command>named</command> would store the stand-by key, and
+ when the original key was revoked, <command>named</command>
+ would be able to transition smoothly to the new key. It would
+ also recognize that the old key had been revoked, and cease
+ using that key to validate answers, minimizing the damage that
+ the compromised key could do.
+ </para>
+ <para>
+ A <command>managed-keys</command> statement contains a list of
+ the keys to be managed, along with information about how the
+ keys are to be initialized for the first time. The only
+ initialization method currently supported (as of
+ <acronym>BIND</acronym> 9.7.0) is <literal>initial-key</literal>.
+ This means the <command>managed-keys</command> statement must
+ contain a copy of the initializing key. (Future releases may
+ allow keys to be initialized by other methods, eliminating this
+ requirement.)
+ </para>
+ <para>
+ Consequently, a <command>managed-keys</command> statement
+ appears similar to a <command>trusted-keys</command>, differing
+ in the presence of the second field, containing the keyword
+ <literal>initial-key</literal>. The difference is, whereas the
+ keys listed in a <command>trusted-keys</command> continue to be
+ trusted until they are removed from
+ <filename>named.conf</filename>, an initializing key listed
+ in a <command>managed-keys</command> statement is only trusted
+ <emphasis>once</emphasis>: for as long as it takes to load the
+ managed key database and start the RFC 5011 key maintenance
+ process.
+ </para>
+ <para>
+ The first time <command>named</command> runs with a managed key
+ configured in <filename>named.conf</filename>, it fetches the
+ DNSKEY RRset directly from the zone apex, and validates it
+ using the key specified in the <command>managed-keys</command>
+ statement. If the DNSKEY RRset is validly signed, then it is
+ used as the basis for a new managed keys database.
+ </para>
+ <para>
+ From that point on, whenever <command>named</command> runs, it
+ sees the <command>managed-keys</command> statement, checks to
+ make sure RFC 5011 key maintenance has already been initialized
+ for the specified domain, and if so, it simply moves on. The
+ key specified in the <command>managed-keys</command> is not
+ used to validate answers; it has been superseded by the key or
+ keys stored in the managed keys database.
+ </para>
+ <para>
+ The next time <command>named</command> runs after a name
+ has been <emphasis>removed</emphasis> from the
+ <command>managed-keys</command> statement, the corresponding
+ zone will be removed from the managed keys database,
+ and RFC 5011 key maintenance will no longer be used for that
+ domain.
+ </para>
+ <para>
+ <command>named</command> only maintains a single managed keys
+ database; consequently, unlike <command>trusted-keys</command>,
+ <command>managed-keys</command> may only be set at the top
+ level of <filename>named.conf</filename>, not within a view.
+ </para>
+ <para>
+ In the current implementation, the managed keys database is
+ stored as a master-format zone file called
+ <filename>managed-keys.bind</filename>. When the key database
+ is changed, the zone is updated. As with any other dynamic
+ zone, changes will be written into a journal file,
+ <filename>managed-keys.bind.jnl</filename>. They are committed
+ to the master file as soon as possible afterward; in the case
+ of the managed key database, this will usually occur within 30
+ seconds. So, whenever <command>named</command> is using
+ automatic key maintenance, those two files can be expected to
+ exist in the working directory. (For this reason among others,
+ the working directory should be always be writable by
+ <command>named</command>.)
+ </para>
+ <para>
+ If the <command>dnssec-lookaside</command> option is
+ set to <userinput>auto</userinput>, <command>named</command>
+ will automatically initialize a managed key for the
+ zone <literal>dlv.isc.org</literal>. The key that is
+ used to initialize the key maintenance process is built
+ into <command>named</command>, and can be overridden
+ from <command>bindkeys-file</command>.
+ </para>
</sect2>
<sect2 id="view_statement_grammar">
@@ -8746,11 +9908,12 @@ XXX: end of RFC1918 addresses #defined out -->
// This should match our internal networks.
match-clients { 10.0.0.0/8; };
- // Provide recursive service to internal clients only.
+ // Provide recursive service to internal
+ // clients only.
recursion yes;
- // Provide a complete view of the example.com zone
- // including addresses of internal hosts.
+ // Provide a complete view of the example.com
+ // zone including addresses of internal hosts.
zone "example.com" {
type master;
file "example-internal.db";
@@ -8758,14 +9921,15 @@ XXX: end of RFC1918 addresses #defined out -->
};
view "external" {
- // Match all clients not matched by the previous view.
+ // Match all clients not matched by the
+ // previous view.
match-clients { any; };
// Refuse recursive service to external clients.
recursion no;
- // Provide a restricted view of the example.com zone
- // containing only publicly accessible hosts.
+ // Provide a restricted view of the example.com
+ // zone containing only publicly accessible hosts.
zone "example.com" {
type master;
file "example-external.db";
@@ -8784,8 +9948,9 @@ view "external" {
<optional> allow-query-on { <replaceable>address_match_list</replaceable> }; </optional>
<optional> allow-transfer { <replaceable>address_match_list</replaceable> }; </optional>
<optional> allow-update { <replaceable>address_match_list</replaceable> }; </optional>
- <optional> update-policy { <replaceable>update_policy_rule</replaceable> <optional>...</optional> }; </optional>
- <optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
+ <optional> update-policy <replaceable>local</replaceable> | { <replaceable>update_policy_rule</replaceable> <optional>...</optional> }; </optional>
+ <optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ;
+ <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> check-names (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; </optional>
<optional> check-mx (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; </optional>
<optional> check-wildcard <replaceable>yes_or_no</replaceable>; </optional>
@@ -8821,6 +9986,7 @@ view "external" {
<optional> min-retry-time <replaceable>number</replaceable> ; </optional>
<optional> max-retry-time <replaceable>number</replaceable> ; </optional>
<optional> key-directory <replaceable>path_name</replaceable>; </optional>
+ <optional> auto-dnssec <constant>allow</constant>|<constant>maintain</constant>|<constant>create</constant>|<constant>off</constant>; </optional>
<optional> zero-no-soa-ttl <replaceable>yes_or_no</replaceable> ; </optional>
};
@@ -8832,8 +9998,11 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<optional> allow-transfer { <replaceable>address_match_list</replaceable> }; </optional>
<optional> allow-update-forwarding { <replaceable>address_match_list</replaceable> }; </optional>
<optional> update-check-ksk <replaceable>yes_or_no</replaceable>; </optional>
+ <optional> dnssec-dnskey-kskonly <replaceable>yes_or_no</replaceable>; </optional>
+ <optional> dnssec-secure-to-insecure <replaceable>yes_or_no</replaceable> ; </optional>
<optional> try-tcp-refresh <replaceable>yes_or_no</replaceable>; </optional>
- <optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
+ <optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ;
+ <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
<optional> check-names (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; </optional>
<optional> dialup <replaceable>dialup_option</replaceable> ; </optional>
<optional> file <replaceable>string</replaceable> ; </optional>
@@ -8846,7 +10015,9 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<optional> ixfr-from-differences <replaceable>yes_or_no</replaceable>; </optional>
<optional> ixfr-tmp-file <replaceable>string</replaceable> ; </optional>
<optional> maintain-ixfr-base <replaceable>yes_or_no</replaceable> ; </optional>
- <optional> masters <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> }; </optional>
+ <optional> masters <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable>
+ <optional>port <replaceable>ip_port</replaceable></optional>
+ <optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> }; </optional>
<optional> max-ixfr-log-size <replaceable>number</replaceable> ; </optional>
<optional> max-transfer-idle-in <replaceable>number</replaceable> ; </optional>
<optional> max-transfer-idle-out <replaceable>number</replaceable> ; </optional>
@@ -8859,7 +10030,8 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> alt-transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
- <optional> alt-transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
+ <optional> alt-transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>)
+ <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> use-alt-transfer-source <replaceable>yes_or_no</replaceable>; </optional>
<optional> notify-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> notify-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
@@ -8877,7 +10049,7 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
type hint;
file <replaceable>string</replaceable> ;
<optional> delegation-only <replaceable>yes_or_no</replaceable> ; </optional>
- <optional> check-names (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; // Not Implemented. </optional>
+ <optional> check-names (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; </optional> // Not Implemented.
};
zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replaceable></optional> {
@@ -8891,14 +10063,18 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<optional> masterfile-format (<constant>text</constant>|<constant>raw</constant>) ; </optional>
<optional> forward (<constant>only</constant>|<constant>first</constant>) ; </optional>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
- <optional> masters <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> }; </optional>
+ <optional> masters <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable>
+ <optional>port <replaceable>ip_port</replaceable></optional>
+ <optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> }; </optional>
<optional> max-transfer-idle-in <replaceable>number</replaceable> ; </optional>
<optional> max-transfer-time-in <replaceable>number</replaceable> ; </optional>
<optional> pubkey <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>number</replaceable> <replaceable>string</replaceable> ; </optional>
<optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
- <optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
+ <optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>)
+ <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> alt-transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
- <optional> alt-transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
+ <optional> alt-transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>)
+ <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
<optional> use-alt-transfer-source <replaceable>yes_or_no</replaceable>; </optional>
<optional> zone-statistics <replaceable>yes_or_no</replaceable> ; </optional>
<optional> database <replaceable>string</replaceable> ; </optional>
@@ -8910,6 +10086,14 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
};
zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replaceable></optional> {
+ type static-stub;
+ <optional> allow-query { <replaceable>address_match_list</replaceable> }; </optional>
+ <optional> server-addresses { <optional> <replaceable>ip_addr</replaceable> ; ... </optional> }; </optional>
+ <optional> server-names { <optional> <replaceable>namelist</replaceable> </optional> }; </optional>
+ <optional> zone-statistics <replaceable>yes_or_no</replaceable> ; </optional>
+};
+
+zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replaceable></optional> {
type forward;
<optional> forward (<constant>only</constant>|<constant>first</constant>) ; </optional>
<optional> forwarders { <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
@@ -9056,6 +10240,55 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<row rowsep="0">
<entry colname="1">
<para>
+ <varname>static-stub</varname>
+ </para>
+ </entry>
+ <entry colname="2">
+ <para>
+ A static-stub zone is similar to a stub zone
+ with the following exceptions:
+ the zone data is statically configured, rather
+ than transferred from a master server;
+ when recursion is necessary for a query that
+ matches a static-stub zone, the locally
+ configured data (nameserver names and glue addresses)
+ is always used even if different authoritative
+ information is cached.
+ </para>
+ <para>
+ Zone data is configured via the
+ <command>server-addresses</command> and
+ <command>server-names</command> zone options.
+ </para>
+ <para>
+ The zone data is maintained in the form of NS
+ and (if necessary) glue A or AAAA RRs
+ internally, which can be seen by dumping zone
+ databases by <command>rndc dumpdb -all</command>.
+ The configured RRs are considered local configuration
+ parameters rather than public data.
+ Non recursive queries (i.e., those with the RD
+ bit off) to a static-stub zone are therefore
+ prohibited and will be responded with REFUSED.
+ </para>
+ <para>
+ Since the data is statically configured, no
+ zone maintenance action takes place for a static-stub
+ zone.
+ For example, there is no periodic refresh
+ attempt, and an incoming notify message
+ will be rejected with an rcode of NOTAUTH.
+ </para>
+ <para>
+ Each static-stub zone is configured with
+ internally generated NS and (if necessary)
+ glue A or AAAA RRs
+ </para>
+ </entry>
+ </row>
+ <row rowsep="0">
+ <entry colname="1">
+ <para>
<varname>forward</varname>
</para>
</entry>
@@ -9270,6 +10503,7 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
received from the
network. The default varies according to zone type. For <command>master</command> zones the default is <command>fail</command>. For <command>slave</command>
zones the default is <command>warn</command>.
+ It is not implemented for <command>hint</command> zones.
</para>
</listitem>
</varlistentry>
@@ -9335,6 +10569,16 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
</varlistentry>
<varlistentry>
+ <term><command>dnssec-dnskey-kskonly</command></term>
+ <listitem>
+ <para>
+ See the description of
+ <command>dnssec-dnskey-kskonly</command> in <xref linkend="boolean_options"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><command>try-tcp-refresh</command></term>
<listitem>
<para>
@@ -9569,6 +10813,84 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
</varlistentry>
<varlistentry>
+ <term><command>server-addresses</command></term>
+ <listitem>
+ <para>
+ Only meaningful for static-stub zones.
+ This is a list of IP addresses to which queries
+ should be sent in recursive resolution for the
+ zone.
+ A non empty list for this option will internally
+ configure the apex NS RR with associated glue A or
+ AAAA RRs.
+ </para>
+ <para>
+ For example, if "example.com" is configured as a
+ static-stub zone with 192.0.2.1 and 2001:db8::1234
+ in a <command>server-addresses</command> option,
+ the following RRs will be internally configured.
+ </para>
+<programlisting>example.com. NS example.com.
+example.com. A 192.0.2.1
+example.com. AAAA 2001:db8::1234</programlisting>
+ <para>
+ These records are internally used to resolve
+ names under the static-stub zone.
+ For instance, if the server receives a query for
+ "www.example.com" with the RD bit on, the server
+ will initiate recursive resolution and send
+ queries to 192.0.2.1 and/or 2001:db8::1234.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>server-names</command></term>
+ <listitem>
+ <para>
+ Only meaningful for static-stub zones.
+ This is a list of domain names of nameservers that
+ act as authoritative servers of the static-stub
+ zone.
+ These names will be resolved to IP addresses when
+ <command>named</command> needs to send queries to
+ these servers.
+ To make this supplemental resolution successful,
+ these names must not be a subdomain of the origin
+ name of static-stub zone.
+ That is, when "example.net" is the origin of a
+ static-stub zone, "ns.example" and
+ "master.example.com" can be specified in the
+ <command>server-names</command> option, but
+ "ns.example.net" cannot, and will be rejected by
+ the configuration parser.
+ </para>
+ <para>
+ A non empty list for this option will internally
+ configure the apex NS RR with the specified names.
+ For example, if "example.com" is configured as a
+ static-stub zone with "ns1.example.net" and
+ "ns2.example.net"
+ in a <command>server-names</command> option,
+ the following RRs will be internally configured.
+ </para>
+<programlisting>example.com. NS ns1.example.net.
+example.com. NS ns2.example.net.
+</programlisting>
+ <para>
+ These records are internally used to resolve
+ names under the static-stub zone.
+ For instance, if the server receives a query for
+ "www.example.com" with the RD bit on, the server
+ initiate recursive resolution,
+ resolve "ns1.example.net" and/or
+ "ns2.example.net" to IP addresses, and then send
+ queries to (one or more of) these addresses.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><command>sig-validity-interval</command></term>
<listitem>
<para>
@@ -9716,6 +11038,51 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
</varlistentry>
<varlistentry>
+ <term><command>auto-dnssec</command></term>
+ <listitem>
+ <para>
+ Zones configured for dynamic DNS may also use this
+ option to allow varying levels of automatic DNSSEC key
+ management. There are four possible settings:
+ </para>
+ <para>
+ <command>auto-dnssec allow;</command> permits
+ keys to be updated and the zone fully re-signed
+ whenever the user issues the command <command>rndc sign
+ <replaceable>zonename</replaceable></command>.
+ </para>
+ <para>
+ <command>auto-dnssec maintain;</command> includes the
+ above, but also automatically adjusts the zone's DNSSEC
+ keys on schedule, according to the keys' timing metadata
+ (see <xref linkend="man.dnssec-keygen"/> and
+ <xref linkend="man.dnssec-settime"/>). The command
+ <command>rndc sign
+ <replaceable>zonename</replaceable></command> causes
+ <command>named</command> to load keys from the key
+ repository and sign the zone with all keys that are
+ active.
+ <command>rndc loadkeys
+ <replaceable>zonename</replaceable></command> causes
+ <command>named</command> to load keys from the key
+ repository and schedule key maintenance events to occur
+ in the future, but it does not sign the full zone
+ immediately.
+ </para>
+ <para>
+ <command>auto-dnssec create;</command> includes the
+ above, but also allows <command>named</command>
+ to create new keys in the key repository when needed.
+ (NOTE: This option is not yet implemented; the syntax is
+ being reserved for future use.)
+ </para>
+ <para>
+ The default setting is <command>auto-dnssec off</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><command>multi-master</command></term>
<listitem>
<para>
@@ -9735,6 +11102,16 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><command>dnssec-secure-to-insecure</command></term>
+ <listitem>
+ <para>
+ See the description of
+ <command>dnssec-secure-to-insecure</command> in <xref linkend="boolean_options"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</sect3>
@@ -9753,15 +11130,14 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
record of any name in the zone.
</para>
<para>
- The <command>update-policy</command> clause is new
- in <acronym>BIND</acronym> 9 and allows more fine-grained
- control over what updates are allowed. A set of rules
- is specified, where each rule either grants or denies
- permissions for one or more names to be updated by
- one or more identities. If the dynamic update request
- message is signed (that is, it includes either a TSIG
- or SIG(0) record), the identity of the signer can be
- determined.
+ The <command>update-policy</command> clause
+ allows more fine-grained control over what updates are
+ allowed. A set of rules is specified, where each rule
+ either grants or denies permissions for one or more
+ names to be updated by one or more identities. If
+ the dynamic update request message is signed (that is,
+ it includes either a TSIG or SIG(0) record), the
+ identity of the signer can be determined.
</para>
<para>
Rules are specified in the <command>update-policy</command>
@@ -9773,24 +11149,53 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
only examines the signer of a message; the source
address is not relevant.
</para>
+ <para>
+ There is a pre-defined <command>update-policy</command>
+ rule which can be switched on with the command
+ <command>update-policy local;</command>.
+ Switching on this rule in a zone causes
+ <command>named</command> to generate a TSIG session
+ key and place it in a file, and to allow that key
+ to update the zone. (By default, the file is
+ <filename>/var/run/named/session.key</filename>, the key
+ name is "local-ddns" and the key algorithm is HMAC-SHA256,
+ but these values are configurable with the
+ <command>session-keyfile</command>,
+ <command>session-keyname</command> and
+ <command>session-keyalg</command> options, respectively).
+ </para>
+ <para>
+ A client running on the local system, and with appropriate
+ permissions, may read that file and use the key to sign update
+ requests. The zone's update policy will be set to allow that
+ key to change any record within the zone. Assuming the
+ key name is "local-ddns", this policy is equivalent to:
+ </para>
+
+ <programlisting>update-policy { grant local-ddns zonesub any; };
+ </programlisting>
<para>
- This is how a rule definition looks:
+ The command <command>nsupdate -l</command> sends update
+ requests to localhost, and signs them using the session key.
+ </para>
+
+ <para>
+ Other rule definitions look like this:
</para>
<programlisting>
-( <command>grant</command> | <command>deny</command> ) <replaceable>identity</replaceable> <replaceable>nametype</replaceable> <replaceable>name</replaceable> <optional> <replaceable>types</replaceable> </optional>
+( <command>grant</command> | <command>deny</command> ) <replaceable>identity</replaceable> <replaceable>nametype</replaceable> <optional> <replaceable>name</replaceable> </optional> <optional> <replaceable>types</replaceable> </optional>
</programlisting>
<para>
Each rule grants or denies privileges. Once a message has
successfully matched a rule, the operation is immediately
- granted
- or denied and no further rules are examined. A rule is matched
- when the signer matches the identity field, the name matches the
- name field in accordance with the nametype field, and the type
- matches
- the types specified in the type field.
+ granted or denied and no further rules are examined. A rule
+ is matched when the signer matches the identity field, the
+ name matches the name field in accordance with the nametype
+ field, and the type matches the types specified in the type
+ field.
</para>
<para>
No signer is required for <replaceable>tcp-self</replaceable>
@@ -9817,7 +11222,7 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
</para>
<para>
- The <replaceable>nametype</replaceable> field has 12
+ The <replaceable>nametype</replaceable> field has 13
values:
<varname>name</varname>, <varname>subdomain</varname>,
<varname>wildcard</varname>, <varname>self</varname>,
@@ -9825,7 +11230,8 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<varname>krb5-self</varname>, <varname>ms-self</varname>,
<varname>krb5-subdomain</varname>,
<varname>ms-subdomain</varname>,
- <varname>tcp-self</varname> and <varname>6to4-self</varname>.
+ <varname>tcp-self</varname>, <varname>6to4-self</varname>,
+ <varname>zonesub</varname>, and <varname>external</varname>.
</para>
<informaltable>
<tgroup cols="2" colsep="0" rowsep="0" tgroupstyle="4Level-table">
@@ -9863,6 +11269,28 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
<row rowsep="0">
<entry colname="1">
<para>
+ <varname>zonesub</varname>
+ </para>
+ </entry> <entry colname="2">
+ <para>
+ This rule is similar to subdomain, except that
+ it matches when the name being updated is a
+ subdomain of the zone in which the
+ <command>update-policy</command> statement
+ appears. This obviates the need to type the zone
+ name twice, and enables the use of a standard
+ <command>update-policy</command> statement in
+ multiple zones without modification.
+ </para>
+ <para>
+ When this rule is used, the
+ <replaceable>name</replaceable> field is omitted.
+ </para>
+ </entry>
+ </row>
+ <row rowsep="0">
+ <entry colname="1">
+ <para>
<varname>wildcard</varname>
</para>
</entry> <entry colname="2">
@@ -9950,7 +11378,7 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
</entry> <entry colname="2">
<para>
Allow the 6to4 prefix to be update by any TCP
- conection from the 6to4 network or from the
+ connection from the 6to4 network or from the
corresponding IPv4 address. This is intended
to allow NS or DNAME RRsets to be added to the
reverse tree.
@@ -9961,14 +11389,56 @@ zone <replaceable>zone_name</replaceable> <optional><replaceable>class</replacea
</note>
</entry>
</row>
+ <row rowsep="0">
+ <entry colname="1">
+ <para>
+ <varname>external</varname>
+ </para>
+ </entry> <entry colname="2">
+ <para>
+ This rule allows <command>named</command>
+ to defer the decision of whether to allow a
+ given update to an external daemon.
+ </para>
+ <para>
+ The method of communicating with the daemon is
+ specified in the <replaceable>identity</replaceable>
+ field, the format of which is
+ "<constant>local:</constant><replaceable>path</replaceable>",
+ where <replaceable>path</replaceable> is the location
+ of a UNIX-domain socket. (Currently, "local" is the
+ only supported mechanism.)
+ </para>
+ <para>
+ Requests to the external daemon are sent over the
+ UNIX-domain socket as datagrams with the following
+ format:
+ </para>
+ <programlisting>
+ Protocol version number (4 bytes, network byte order, currently 1)
+ Request length (4 bytes, network byte order)
+ Signer (null-terminated string)
+ Name (null-terminated string)
+ TCP source address (null-terminated string)
+ Rdata type (null-terminated string)
+ Key (null-terminated string)
+ TKEY token length (4 bytes, network byte order)
+ TKEY token (remainder of packet)</programlisting>
+ <para>
+ The daemon replies with a four-byte value in
+ network byte order, containing either 0 or 1; 0
+ indicates that the specified update is not
+ permitted, and 1 indicates that it is.
+ </para>
+ </entry>
+ </row>
</tbody>
</tgroup>
</informaltable>
<para>
In all cases, the <replaceable>name</replaceable>
- field must
- specify a fully-qualified domain name.
+ field must specify a fully-qualified domain name.
</para>
<para>
@@ -11381,7 +12851,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
</para>
<programlisting>$ORIGIN 0.0.192.IN-ADDR.ARPA.
-$GENERATE 1-2 0 NS SERVER$.EXAMPLE.
+$GENERATE 1-2 @ NS SERVER$.EXAMPLE.
$GENERATE 1-127 $ CNAME $.0</programlisting>
<para>
@@ -11396,6 +12866,32 @@ $GENERATE 1-127 $ CNAME $.0</programlisting>
127.0.0.192.IN-ADDR.ARPA. CNAME 127.0.0.0.192.IN-ADDR.ARPA.
</programlisting>
+ <para>
+ Generate a set of A and MX records. Note the MX's right hand
+ side is a quoted string. The quotes will be stripped when the
+ right hand side is processed.
+ </para>
+
+<programlisting>
+$ORIGIN EXAMPLE.
+$GENERATE 1-127 HOST-$ A 1.2.3.$
+$GENERATE 1-127 HOST-$ MX "0 ."</programlisting>
+
+ <para>
+ is equivalent to
+ </para>
+
+<programlisting>HOST-1.EXAMPLE. A 1.2.3.1
+HOST-1.EXAMPLE. MX 0 .
+HOST-2.EXAMPLE. A 1.2.3.2
+HOST-2.EXAMPLE. MX 0 .
+HOST-3.EXAMPLE. A 1.2.3.3
+HOST-3.EXAMPLE. MX 0 .
+...
+HOST-127.EXAMPLE. A 1.2.3.127
+HOST-127.EXAMPLE. MX 0 .
+</programlisting>
+
<informaltable colsep="0" rowsep="0">
<tgroup cols="2" colsep="0" rowsep="0" tgroupstyle="3Level-table">
<colspec colname="1" colnum="1" colsep="0" colwidth="0.875in"/>
@@ -11445,20 +12941,30 @@ $GENERATE 1-127 $ CNAME $.0</programlisting>
Available output forms are decimal
(<command>d</command>), octal
- (<command>o</command>) and hexadecimal
+ (<command>o</command>), hexadecimal
(<command>x</command> or <command>X</command>
- for uppercase). The default modifier is
+ for uppercase) and nibble
+ (<command>n</command> or <command>N</command>\
+ for uppercase). The default modifier is
<command>${0,0,d}</command>. If the
<command>lhs</command> is not absolute, the
current <command>$ORIGIN</command> is appended
to the name.
</para>
- <para>
- For compatibility with earlier versions, <command>$$</command> is still
- recognized as indicating a literal $ in the output.
- </para>
- </entry>
- </row>
+ <para>
+ In nibble mode the value will be treated as
+ if it was a reversed hexadecimal string
+ with each hexadecimal digit as a separate
+ label. The width field includes the label
+ separator.
+ </para>
+ <para>
+ For compatibility with earlier versions,
+ <command>$$</command> is still recognized as
+ indicating a literal $ in the output.
+ </para>
+ </entry>
+ </row>
<row rowsep="0">
<entry colname="1">
<para><command>ttl</command></para>
@@ -11497,8 +13003,7 @@ $GENERATE 1-127 $ CNAME $.0</programlisting>
</entry>
<entry colname="2">
<para>
- At present the only supported types are
- PTR, CNAME, DNAME, A, AAAA and NS.
+ Any valid type.
</para>
</entry>
</row>
@@ -11508,8 +13013,7 @@ $GENERATE 1-127 $ CNAME $.0</programlisting>
</entry>
<entry colname="2">
<para>
- <command>rhs</command> is a domain name. It is processed
- similarly to lhs.
+ <command>rhs</command>, optionally, quoted string.
</para>
</entry>
</row>
@@ -11668,9 +13172,12 @@ $GENERATE 1-127 $ CNAME $.0</programlisting>
</entry>
<entry colname="2">
<para>
- The number of RRsets per RR type (positive
- or negative) and nonexistent names stored in the
- cache database.
+ The number of RRsets per RR type and nonexistent
+ names stored in the cache database.
+ If the exclamation mark (!) is printed for a RR
+ type, it means that particular type of RRset is
+ known to be nonexistent (this is also known as
+ "NXRRSET").
Maintained per view.
</para>
</entry>
@@ -12639,6 +14146,13 @@ $GENERATE 1-127 $ CNAME $.0</programlisting>
<entry colname="3">
<para>
Mismatch responses received.
+ The DNS ID, response's source address,
+ and/or the response's source port does not
+ match what was expected.
+ (The port must be 53 or as defined by
+ the <command>port</command> option.)
+ This may be an indication of a cache
+ poisoning attempt.
</para>
</entry>
</row>
@@ -13106,14 +14620,17 @@ $GENERATE 1-127 $ CNAME $.0</programlisting>
</para>
<programlisting>
-// Set up an ACL named "bogusnets" that will block RFC1918 space
-// and some reserved space, which is commonly used in spoofing attacks.
+// Set up an ACL named "bogusnets" that will block
+// RFC1918 space and some reserved space, which is
+// commonly used in spoofing attacks.
acl bogusnets {
- 0.0.0.0/8; 1.0.0.0/8; 2.0.0.0/8; 192.0.2.0/24; 224.0.0.0/3;
- 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;
+ 0.0.0.0/8; 1.0.0.0/8; 2.0.0.0/8; 192.0.2.0/24;
+ 224.0.0.0/3; 10.0.0.0/8; 172.16.0.0/12;
+ 192.168.0.0/16;
};
-// Set up an ACL called our-nets. Replace this with the real IP numbers.
+// Set up an ACL called our-nets. Replace this with the
+// real IP numbers.
acl our-nets { x.x.x.x/24; x.x.x.x/21; };
options {
...
@@ -14756,8 +16273,12 @@ zone "example.com" {
</bibliography>
</sect2>
</sect1>
+
+ <xi:include href="libdns.xml"/>
+
</appendix>
+
<reference id="Bv9ARM.ch10">
<title>Manual pages</title>
<xi:include href="../../bin/dig/dig.docbook"/>
@@ -14765,15 +16286,23 @@ zone "example.com" {
<xi:include href="../../bin/dnssec/dnssec-dsfromkey.docbook"/>
<xi:include href="../../bin/dnssec/dnssec-keyfromlabel.docbook"/>
<xi:include href="../../bin/dnssec/dnssec-keygen.docbook"/>
+ <xi:include href="../../bin/dnssec/dnssec-revoke.docbook"/>
+ <xi:include href="../../bin/dnssec/dnssec-settime.docbook"/>
<xi:include href="../../bin/dnssec/dnssec-signzone.docbook"/>
<xi:include href="../../bin/check/named-checkconf.docbook"/>
<xi:include href="../../bin/check/named-checkzone.docbook"/>
<xi:include href="../../bin/named/named.docbook"/>
+ <xi:include href="../../bin/tools/named-journalprint.docbook"/>
<!-- named.conf.docbook and others? -->
<xi:include href="../../bin/nsupdate/nsupdate.docbook"/>
<xi:include href="../../bin/rndc/rndc.docbook"/>
<xi:include href="../../bin/rndc/rndc.conf.docbook"/>
- <xi:include href="../../bin/rndc/rndc-confgen.docbook"/>
+ <xi:include href="../../bin/confgen/rndc-confgen.docbook"/>
+ <xi:include href="../../bin/confgen/ddns-confgen.docbook"/>
+ <xi:include href="../../bin/tools/arpaname.docbook"/>
+ <xi:include href="../../bin/tools/genrandom.docbook"/>
+ <xi:include href="../../bin/tools/isc-hmac-fixup.docbook"/>
+ <xi:include href="../../bin/tools/nsec3hash.docbook"/>
</reference>
</book>
diff --git a/doc/arm/Bv9ARM.ch01.html b/doc/arm/Bv9ARM.ch01.html
index 4cdfb09427cd..ff2c5ceec6e4 100644
--- a/doc/arm/Bv9ARM.ch01.html
+++ b/doc/arm/Bv9ARM.ch01.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch01.html,v 1.43.48.4 2010-01-24 01:55:26 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch01.html,v 1.49 2011-01-05 01:14:07 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,17 +45,17 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2563412">Scope of Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564391">Organization of This Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564531">Conventions Used in This Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564712">The Domain Name System (<acronym class="acronym">DNS</acronym>)</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564371">Scope of Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564394">Organization of This Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564534">Conventions Used in This Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564715">The Domain Name System (<acronym class="acronym">DNS</acronym>)</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564733">DNS Fundamentals</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564768">Domains and Domain Names</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567173">Zones</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567250">Authoritative Name Servers</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567422">Caching Name Servers</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567553">Name Servers in Multiple Roles</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564737">DNS Fundamentals</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564771">Domains and Domain Names</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567176">Zones</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567253">Authoritative Name Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567426">Caching Name Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567556">Name Servers in Multiple Roles</a></span></dt>
</dl></dd>
</dl>
</div>
@@ -71,7 +71,7 @@
</p>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2563412"></a>Scope of Document</h2></div></div></div>
+<a name="id2564371"></a>Scope of Document</h2></div></div></div>
<p>
The Berkeley Internet Name Domain
(<acronym class="acronym">BIND</acronym>) implements a
@@ -82,12 +82,12 @@
system administrators.
</p>
<p>
- This version of the manual corresponds to BIND version 9.6.
+ This version of the manual corresponds to BIND version 9.7.
</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2564391"></a>Organization of This Document</h2></div></div></div>
+<a name="id2564394"></a>Organization of This Document</h2></div></div></div>
<p>
In this document, <span class="emphasis"><em>Chapter 1</em></span> introduces
the basic <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym> concepts. <span class="emphasis"><em>Chapter 2</em></span>
@@ -116,7 +116,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2564531"></a>Conventions Used in This Document</h2></div></div></div>
+<a name="id2564534"></a>Conventions Used in This Document</h2></div></div></div>
<p>
In this document, we use the following general typographic
conventions:
@@ -243,7 +243,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2564712"></a>The Domain Name System (<acronym class="acronym">DNS</acronym>)</h2></div></div></div>
+<a name="id2564715"></a>The Domain Name System (<acronym class="acronym">DNS</acronym>)</h2></div></div></div>
<p>
The purpose of this document is to explain the installation
and upkeep of the <acronym class="acronym">BIND</acronym> (Berkeley Internet
@@ -253,7 +253,7 @@
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2564733"></a>DNS Fundamentals</h3></div></div></div>
+<a name="id2564737"></a>DNS Fundamentals</h3></div></div></div>
<p>
The Domain Name System (DNS) is a hierarchical, distributed
database. It stores information for mapping Internet host names to
@@ -275,7 +275,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2564768"></a>Domains and Domain Names</h3></div></div></div>
+<a name="id2564771"></a>Domains and Domain Names</h3></div></div></div>
<p>
The data stored in the DNS is identified by <span class="emphasis"><em>domain names</em></span> that are organized as a tree according to
organizational or administrative boundaries. Each node of the tree,
@@ -321,7 +321,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567173"></a>Zones</h3></div></div></div>
+<a name="id2567176"></a>Zones</h3></div></div></div>
<p>
To properly operate a name server, it is important to understand
the difference between a <span class="emphasis"><em>zone</em></span>
@@ -374,7 +374,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567250"></a>Authoritative Name Servers</h3></div></div></div>
+<a name="id2567253"></a>Authoritative Name Servers</h3></div></div></div>
<p>
Each zone is served by at least
one <span class="emphasis"><em>authoritative name server</em></span>,
@@ -391,7 +391,7 @@
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2567273"></a>The Primary Master</h4></div></div></div>
+<a name="id2567276"></a>The Primary Master</h4></div></div></div>
<p>
The authoritative server where the master copy of the zone
data is maintained is called the
@@ -411,7 +411,7 @@
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2567303"></a>Slave Servers</h4></div></div></div>
+<a name="id2567374"></a>Slave Servers</h4></div></div></div>
<p>
The other authoritative servers, the <span class="emphasis"><em>slave</em></span>
servers (also known as <span class="emphasis"><em>secondary</em></span> servers)
@@ -427,7 +427,7 @@
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2567393"></a>Stealth Servers</h4></div></div></div>
+<a name="id2567396"></a>Stealth Servers</h4></div></div></div>
<p>
Usually all of the zone's authoritative servers are listed in
NS records in the parent zone. These NS records constitute
@@ -462,7 +462,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567422"></a>Caching Name Servers</h3></div></div></div>
+<a name="id2567426"></a>Caching Name Servers</h3></div></div></div>
<p>
The resolver libraries provided by most operating systems are
<span class="emphasis"><em>stub resolvers</em></span>, meaning that they are not
@@ -489,7 +489,7 @@
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2567526"></a>Forwarding</h4></div></div></div>
+<a name="id2567529"></a>Forwarding</h4></div></div></div>
<p>
Even a caching name server does not necessarily perform
the complete recursive lookup itself. Instead, it can
@@ -516,7 +516,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567553"></a>Name Servers in Multiple Roles</h3></div></div></div>
+<a name="id2567556"></a>Name Servers in Multiple Roles</h3></div></div></div>
<p>
The <acronym class="acronym">BIND</acronym> name server can
simultaneously act as
diff --git a/doc/arm/Bv9ARM.ch02.html b/doc/arm/Bv9ARM.ch02.html
index 5181a2a6cd4b..a9fde322a12c 100644
--- a/doc/arm/Bv9ARM.ch02.html
+++ b/doc/arm/Bv9ARM.ch02.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch02.html,v 1.38.56.3 2010-01-24 01:55:25 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch02.html,v 1.43 2011-01-05 01:14:07 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,16 +45,16 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567587">Hardware requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567613">CPU Requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567626">Memory Requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567721">Name Server Intensive Environment Issues</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567732">Supported Operating Systems</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567590">Hardware requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567617">CPU Requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567629">Memory Requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567724">Name Server Intensive Environment Issues</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567735">Supported Operating Systems</a></span></dt>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2567587"></a>Hardware requirements</h2></div></div></div>
+<a name="id2567590"></a>Hardware requirements</h2></div></div></div>
<p>
<acronym class="acronym">DNS</acronym> hardware requirements have
traditionally been quite modest.
@@ -73,7 +73,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2567613"></a>CPU Requirements</h2></div></div></div>
+<a name="id2567617"></a>CPU Requirements</h2></div></div></div>
<p>
CPU requirements for <acronym class="acronym">BIND</acronym> 9 range from
i486-class machines
@@ -84,7 +84,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2567626"></a>Memory Requirements</h2></div></div></div>
+<a name="id2567629"></a>Memory Requirements</h2></div></div></div>
<p>
The memory of the server has to be large enough to fit the
cache and zones loaded off disk. The <span><strong class="command">max-cache-size</strong></span>
@@ -107,7 +107,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2567721"></a>Name Server Intensive Environment Issues</h2></div></div></div>
+<a name="id2567724"></a>Name Server Intensive Environment Issues</h2></div></div></div>
<p>
For name server intensive environments, there are two alternative
configurations that may be used. The first is where clients and
@@ -124,13 +124,13 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2567732"></a>Supported Operating Systems</h2></div></div></div>
+<a name="id2567735"></a>Supported Operating Systems</h2></div></div></div>
<p>
ISC <acronym class="acronym">BIND</acronym> 9 compiles and runs on a large
number
- of Unix-like operating systems and on NT-derived versions of
- Microsoft Windows such as Windows 2000 and Windows XP. For an
- up-to-date
+ of Unix-like operating systems and on
+ Microsoft Windows Server 2003 and 2008, and Windows XP and Vista.
+ For an up-to-date
list of supported systems, see the README file in the top level
directory
of the BIND 9 source distribution.
diff --git a/doc/arm/Bv9ARM.ch03.html b/doc/arm/Bv9ARM.ch03.html
index 454fdd63d2c5..e01d69ec2992 100644
--- a/doc/arm/Bv9ARM.ch03.html
+++ b/doc/arm/Bv9ARM.ch03.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch03.html,v 1.71.48.4 2010-01-24 01:55:25 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch03.html,v 1.83 2011-01-21 01:14:13 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,14 +47,14 @@
<dl>
<dt><span class="sect1"><a href="Bv9ARM.ch03.html#sample_configuration">Sample Configurations</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567764">A Caching-only Name Server</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567780">An Authoritative-only Name Server</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567767">A Caching-only Name Server</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567988">An Authoritative-only Name Server</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568007">Load Balancing</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568361">Name Server Operations</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568010">Load Balancing</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568364">Name Server Operations</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2568366">Tools for Use With the Name Server Daemon</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2570006">Signals</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2568370">Tools for Use With the Name Server Daemon</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2570385">Signals</a></span></dt>
</dl></dd>
</dl>
</div>
@@ -68,7 +68,7 @@
<a name="sample_configuration"></a>Sample Configurations</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567764"></a>A Caching-only Name Server</h3></div></div></div>
+<a name="id2567767"></a>A Caching-only Name Server</h3></div></div></div>
<p>
The following sample configuration is appropriate for a caching-only
name server for use by clients internal to a corporation. All
@@ -82,10 +82,13 @@
// Two corporate subnets we wish to allow queries from.
acl corpnets { 192.168.4.0/24; 192.168.7.0/24; };
options {
- directory "/etc/namedb"; // Working directory
+ // Working directory
+ directory "/etc/namedb";
+
allow-query { corpnets; };
};
-// Provide a reverse mapping for the loopback address 127.0.0.1
+// Provide a reverse mapping for the loopback
+// address 127.0.0.1
zone "0.0.127.in-addr.arpa" {
type master;
file "localhost.rev";
@@ -95,7 +98,7 @@ zone "0.0.127.in-addr.arpa" {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2567780"></a>An Authoritative-only Name Server</h3></div></div></div>
+<a name="id2567988"></a>An Authoritative-only Name Server</h3></div></div></div>
<p>
This sample configuration is for an authoritative-only server
that is the master server for "<code class="filename">example.com</code>"
@@ -103,13 +106,18 @@ zone "0.0.127.in-addr.arpa" {
</p>
<pre class="programlisting">
options {
- directory "/etc/namedb"; // Working directory
- allow-query-cache { none; }; // Do not allow access to cache
- allow-query { any; }; // This is the default
- recursion no; // Do not provide recursive service
+ // Working directory
+ directory "/etc/namedb";
+ // Do not allow access to cache
+ allow-query-cache { none; };
+ // This is the default
+ allow-query { any; };
+ // Do not provide recursive service
+ recursion no;
};
-// Provide a reverse mapping for the loopback address 127.0.0.1
+// Provide a reverse mapping for the loopback
+// address 127.0.0.1
zone "0.0.127.in-addr.arpa" {
type master;
file "localhost.rev";
@@ -119,7 +127,8 @@ zone "0.0.127.in-addr.arpa" {
zone "example.com" {
type master;
file "example.com.db";
- // IP addresses of slave servers allowed to transfer example.com
+ // IP addresses of slave servers allowed to
+ // transfer example.com
allow-transfer {
192.168.4.14;
192.168.5.53;
@@ -137,7 +146,7 @@ zone "eng.example.com" {
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2568007"></a>Load Balancing</h2></div></div></div>
+<a name="id2568010"></a>Load Balancing</h2></div></div></div>
<p>
A primitive form of load balancing can be achieved in
the <acronym class="acronym">DNS</acronym> by using multiple records
@@ -273,17 +282,17 @@ zone "eng.example.com" {
</p>
<p>
For more detail on ordering responses, check the
- <span><strong class="command">rrset-order</strong></span> substatement in the
+ <span><strong class="command">rrset-order</strong></span> sub-statement in the
<span><strong class="command">options</strong></span> statement, see
<a href="Bv9ARM.ch06.html#rrset_ordering">RRset Ordering</a>.
</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2568361"></a>Name Server Operations</h2></div></div></div>
+<a name="id2568364"></a>Name Server Operations</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2568366"></a>Tools for Use With the Name Server Daemon</h3></div></div></div>
+<a name="id2568370"></a>Tools for Use With the Name Server Daemon</h3></div></div></div>
<p>
This section describes several indispensable diagnostic,
administrative and monitoring tools available to the system
@@ -463,6 +472,60 @@ zone "eng.example.com" {
<dd><p>
Retransfer the given zone from the master.
</p></dd>
+<dt><span class="term"><strong class="userinput"><code>sign <em class="replaceable"><code>zone</code></em>
+ [<span class="optional"><em class="replaceable"><code>class</code></em>
+ [<span class="optional"><em class="replaceable"><code>view</code></em></span>]</span>]</code></strong></span></dt>
+<dd>
+<p>
+ Fetch all DNSSEC keys for the given zone
+ from the key directory (see
+ <span><strong class="command">key-directory</strong></span> in
+ <a href="Bv9ARM.ch06.html#options" title="options Statement Definition and
+ Usage">the section called &#8220;<span><strong class="command">options</strong></span> Statement Definition and
+ Usage&#8221;</a>). If they are within
+ their publication period, merge them into the
+ zone's DNSKEY RRset. If the DNSKEY RRset
+ is changed, then the zone is automatically
+ re-signed with the new key set.
+ </p>
+<p>
+ This command requires that the
+ <span><strong class="command">auto-dnssec</strong></span> zone option to be set
+ to <code class="literal">allow</code>,
+ <code class="literal">maintain</code>, or
+ <code class="literal">create</code>, and also requires
+ the zone to be configured to allow dynamic DNS.
+ See <a href="Bv9ARM.ch06.html#dynamic_update_policies" title="Dynamic Update Policies">the section called &#8220;Dynamic Update Policies&#8221;</a> for
+ more details.
+ </p>
+</dd>
+<dt><span class="term"><strong class="userinput"><code>loadkeys <em class="replaceable"><code>zone</code></em>
+ [<span class="optional"><em class="replaceable"><code>class</code></em>
+ [<span class="optional"><em class="replaceable"><code>view</code></em></span>]</span>]</code></strong></span></dt>
+<dd>
+<p>
+ Fetch all DNSSEC keys for the given zone
+ from the key directory (see
+ <span><strong class="command">key-directory</strong></span> in
+ <a href="Bv9ARM.ch06.html#options" title="options Statement Definition and
+ Usage">the section called &#8220;<span><strong class="command">options</strong></span> Statement Definition and
+ Usage&#8221;</a>). If they are within
+ their publication period, merge them into the
+ zone's DNSKEY RRset. Unlike <span><strong class="command">rndc
+ sign</strong></span>, however, the zone is not
+ immediately re-signed by the new keys, but is
+ allowed to incrementally re-sign over time.
+ </p>
+<p>
+ This command requires that the
+ <span><strong class="command">auto-dnssec</strong></span> zone option to
+ be set to <code class="literal">maintain</code> or
+ <code class="literal">create</code>, and also requires
+ the zone to be configured to allow dynamic DNS.
+ See <a href="Bv9ARM.ch06.html#dynamic_update_policies" title="Dynamic Update Policies">the section called &#8220;Dynamic Update Policies&#8221;</a> for
+ more details.
+ </p>
+</dd>
<dt><span class="term"><strong class="userinput"><code>freeze
[<span class="optional"><em class="replaceable"><code>zone</code></em>
[<span class="optional"><em class="replaceable"><code>class</code></em>
@@ -536,6 +599,14 @@ zone "eng.example.com" {
specified, all
views are dumped.
</p></dd>
+<dt><span class="term"><strong class="userinput"><code>secroots
+ [<span class="optional"><em class="replaceable"><code>view ...</code></em></span>]</code></strong></span></dt>
+<dd><p>
+ Dump the server's security roots to the secroots
+ file for the specified views. If no view is
+ specified, security roots for all
+ views are dumped.
+ </p></dd>
<dt><span class="term"><strong class="userinput"><code>stop [<span class="optional">-p</span>]</code></strong></span></dt>
<dd><p>
Stop the server, making sure any recent changes
@@ -599,6 +670,57 @@ zone "eng.example.com" {
set to <strong class="userinput"><code>yes</code></strong> to be effective.
It defaults to enabled.
</p></dd>
+<dt><span class="term"><strong class="userinput"><code>addzone
+ <em class="replaceable"><code>zone</code></em>
+ [<span class="optional"><em class="replaceable"><code>class</code></em>
+ [<span class="optional"><em class="replaceable"><code>view</code></em></span>]</span>]
+ <em class="replaceable"><code>configuration</code></em>
+ </code></strong></span></dt>
+<dd>
+<p>
+ Add a zone while the server is running. This
+ command requires the
+ <span><strong class="command">allow-new-zones</strong></span> option to be set
+ to <strong class="userinput"><code>yes</code></strong>. The
+ <em class="replaceable"><code>configuration</code></em> string
+ specified on the command line is the zone
+ configuration text that would ordinarily be
+ placed in <code class="filename">named.conf</code>.
+ </p>
+<p>
+ The configuration is saved in a file called
+ <code class="filename"><em class="replaceable"><code>hash</code></em>.nzf</code>,
+ where <em class="replaceable"><code>hash</code></em> is a
+ cryptographic hash generated from the name of
+ the view. When <span><strong class="command">named</strong></span> is
+ restarted, the file will be loaded into the view
+ configuration, so that zones that were added
+ can persist after a restart.
+ </p>
+<p>
+ This sample <span><strong class="command">addzone</strong></span> command
+ would add the zone <code class="literal">example.com</code>
+ to the default view:
+ </p>
+<p>
+<code class="prompt">$ </code><strong class="userinput"><code>rndc addzone example.com '{ type master; file "example.com.db"; };'</code></strong>
+ </p>
+<p>
+ (Note the brackets and semi-colon around the zone
+ configuration text.)
+ </p>
+</dd>
+<dt><span class="term"><strong class="userinput"><code>delzone
+ <em class="replaceable"><code>zone</code></em>
+ [<span class="optional"><em class="replaceable"><code>class</code></em>
+ [<span class="optional"><em class="replaceable"><code>view</code></em></span>]</span>]
+ </code></strong></span></dt>
+<dd><p>
+ Delete a zone while the server is running.
+ Only zones that were originally added via
+ <span><strong class="command">rndc addzone</strong></span> can be deleted
+ in this matter.
+ </p></dd>
</dl></div>
<p>
A configuration file is required, since all
@@ -699,7 +821,8 @@ zone "eng.example.com" {
<pre class="programlisting">
key rndc_key {
algorithm "hmac-md5";
- secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K";
+ secret
+ "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K";
};
options {
default-server 127.0.0.1;
@@ -721,7 +844,8 @@ options {
</p>
<pre class="programlisting">
controls {
- inet 127.0.0.1 allow { localhost; } keys { rndc_key; };
+ inet 127.0.0.1
+ allow { localhost; } keys { rndc_key; };
};
</pre>
<p>
@@ -749,7 +873,7 @@ controls {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2570006"></a>Signals</h3></div></div></div>
+<a name="id2570385"></a>Signals</h3></div></div></div>
<p>
Certain UNIX signals cause the name server to take specific
actions, as described in the following table. These signals can
diff --git a/doc/arm/Bv9ARM.ch04.html b/doc/arm/Bv9ARM.ch04.html
index 7b8a200d8e5c..77b74cb43ad2 100644
--- a/doc/arm/Bv9ARM.ch04.html
+++ b/doc/arm/Bv9ARM.ch04.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch04.html,v 1.87.48.6 2010-01-24 01:55:26 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch04.html,v 1.125.8.1.2.1 2011-06-09 03:41:07 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -49,29 +49,59 @@
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#dynamic_update">Dynamic Update</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#journal">The journal file</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#incremental_zone_transfers">Incremental Zone Transfers (IXFR)</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2570492">Split DNS</a></span></dt>
-<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2570510">Example split DNS setup</a></span></dt></dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2570823">Split DNS</a></span></dt>
+<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2570841">Example split DNS setup</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#tsig">TSIG</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571082">Generate Shared Keys for Each Pair of Hosts</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571156">Copying the Shared Secret to Both Machines</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571166">Informing the Servers of the Key's Existence</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571203">Instructing the Server to Use the Key</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571260">TSIG Key Based Access Control</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571445">Errors</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571342">Generate Shared Keys for Each Pair of Hosts</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571553">Copying the Shared Secret to Both Machines</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571563">Informing the Servers of the Key's Existence</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571600">Instructing the Server to Use the Key</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571657">TSIG Key Based Access Control</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571706">Errors</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571459">TKEY</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571576">SIG(0)</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571720">TKEY</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2563987">SIG(0)</a></span></dt>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#DNSSEC">DNSSEC</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571644">Generating Keys</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571792">Signing the Zone</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571873">Configuring Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2564055">Generating Keys</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572189">Signing the Zone</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572270">Configuring Servers</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572110">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#dnssec.dynamic.zones">DNSSEC, Dynamic Zones, and Automatic Signing</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572172">Address Lookups Using AAAA Records</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572194">Address to Name Lookups Using Nibble Format</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607351">Converting from insecure to secure</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563493">Dynamic DNS update method</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563529">Fully automatic zone signing</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563611">Private-type records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563649">DNSKEY rollovers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563661">Dynamic DNS update method</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563763">Automatic key rollovers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563789">NSEC3PARAM rollovers via UPDATE</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563799">Converting from NSEC to NSEC3</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563809">Converting from NSEC3 to NSEC</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563821">Converting from secure to insecure</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563859">Periodic re-signing</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563868">NSEC3 and OPTOUT</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#rfc5011.support">Dynamic Trust Anchor Management</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607271">Validating Resolver</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607293">Authoritative Server</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#pkcs11">PKCS #11 (Cryptoki) support</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2609524">Prerequisites</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607678">Building BIND 9 with PKCS#11</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607842">PKCS #11 Tools</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607873">Using the HSM</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2609709">Specifying the engine on the command line</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2609755">Running named with automatic zone re-signing</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572490">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572757">Address Lookups Using AAAA Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572846">Address to Name Lookups Using Nibble Format</a></span></dt>
</dl></dd>
</dl>
</div>
@@ -113,14 +143,25 @@
</p>
<p>
Dynamic update is enabled by including an
- <span><strong class="command">allow-update</strong></span> or <span><strong class="command">update-policy</strong></span>
- clause in the <span><strong class="command">zone</strong></span> statement. The
- <span><strong class="command">tkey-gssapi-credential</strong></span> and
- <span><strong class="command">tkey-domain</strong></span> clauses in the
- <span><strong class="command">options</strong></span> statement enable the
- server to negotiate keys that can be matched against those
- in <span><strong class="command">update-policy</strong></span> or
- <span><strong class="command">allow-update</strong></span>.
+ <span><strong class="command">allow-update</strong></span> or an <span><strong class="command">update-policy</strong></span>
+ clause in the <span><strong class="command">zone</strong></span> statement.
+ </p>
+<p>
+ If the zone's <span><strong class="command">update-policy</strong></span> is set to
+ <strong class="userinput"><code>local</code></strong>, updates to the zone
+ will be permitted for the key <code class="varname">local-ddns</code>,
+ which will be generated by <span><strong class="command">named</strong></span> at startup.
+ See <a href="Bv9ARM.ch06.html#dynamic_update_policies" title="Dynamic Update Policies">the section called &#8220;Dynamic Update Policies&#8221;</a> for more details.
+ </p>
+<p>
+ Dynamic updates using Kerberos signed requests can be made
+ using the TKEY/GSS protocol by setting either the
+ <span><strong class="command">tkey-gssapi-keytab</strong></span> option, or alternatively
+ by setting both the <span><strong class="command">tkey-gssapi-credential</strong></span>
+ and <span><strong class="command">tkey-domain</strong></span> options. Once enabled,
+ Kerberos signed requests will be matched against the update
+ policies for the zone, using the Kerberos principal as the
+ signer for the request.
</p>
<p>
Updating of secure zones (zones using DNSSEC) follows RFC
@@ -215,7 +256,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2570492"></a>Split DNS</h2></div></div></div>
+<a name="id2570823"></a>Split DNS</h2></div></div></div>
<p>
Setting up different views, or visibility, of the DNS space to
internal and external resolvers is usually referred to as a
@@ -245,7 +286,7 @@
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2570510"></a>Example split DNS setup</h3></div></div></div>
+<a name="id2570841"></a>Example split DNS setup</h3></div></div></div>
<p>
Let's say a company named <span class="emphasis"><em>Example, Inc.</em></span>
(<code class="literal">example.com</code>)
@@ -275,7 +316,7 @@
and <code class="filename">site2.example.com</code>, to the servers
in the
DMZ. These internal servers will have complete sets of information
- for <code class="filename">site1.example.com</code>, <code class="filename">site2.example.com</code>,<span class="emphasis"><em></em></span> <code class="filename">site1.internal</code>,
+ for <code class="filename">site1.example.com</code>, <code class="filename">site2.example.com</code>, <code class="filename">site1.internal</code>,
and <code class="filename">site2.internal</code>.
</p>
<p>
@@ -373,26 +414,32 @@ options {
...
...
forward only;
- forwarders { // forward to external servers
+ // forward to external servers
+ forwarders {
<code class="varname">bastion-ips-go-here</code>;
};
- allow-transfer { none; }; // sample allow-transfer (no one)
- allow-query { internals; externals; }; // restrict query access
- allow-recursion { internals; }; // restrict recursion
+ // sample allow-transfer (no one)
+ allow-transfer { none; };
+ // restrict query access
+ allow-query { internals; externals; };
+ // restrict recursion
+ allow-recursion { internals; };
...
...
};
-zone "site1.example.com" { // sample master zone
+// sample master zone
+zone "site1.example.com" {
type master;
file "m/site1.example.com";
- forwarders { }; // do normal iterative
- // resolution (do not forward)
+ // do normal iterative resolution (do not forward)
+ forwarders { };
allow-query { internals; externals; };
allow-transfer { internals; };
};
-zone "site2.example.com" { // sample slave zone
+// sample slave zone
+zone "site2.example.com" {
type slave;
file "s/site2.example.com";
masters { 172.16.72.3; };
@@ -429,15 +476,20 @@ acl externals { bastion-ips-go-here; };
options {
...
...
- allow-transfer { none; }; // sample allow-transfer (no one)
- allow-query { any; }; // default query access
- allow-query-cache { internals; externals; }; // restrict cache access
- allow-recursion { internals; externals; }; // restrict recursion
+ // sample allow-transfer (no one)
+ allow-transfer { none; };
+ // default query access
+ allow-query { any; };
+ // restrict cache access
+ allow-query-cache { internals; externals; };
+ // restrict recursion
+ allow-recursion { internals; externals; };
...
...
};
-zone "site1.example.com" { // sample slave zone
+// sample slave zone
+zone "site1.example.com" {
type master;
file "m/site1.foo.com";
allow-transfer { internals; externals; };
@@ -491,7 +543,7 @@ nameserver 172.16.72.4
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571082"></a>Generate Shared Keys for Each Pair of Hosts</h3></div></div></div>
+<a name="id2571342"></a>Generate Shared Keys for Each Pair of Hosts</h3></div></div></div>
<p>
A shared secret is generated to be shared between <span class="emphasis"><em>host1</em></span> and <span class="emphasis"><em>host2</em></span>.
An arbitrary key name is chosen: "host1-host2.". The key name must
@@ -499,7 +551,7 @@ nameserver 172.16.72.4
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2571099"></a>Automatic Generation</h4></div></div></div>
+<a name="id2571360"></a>Automatic Generation</h4></div></div></div>
<p>
The following command will generate a 128-bit (16 byte) HMAC-SHA256
key as described above. Longer keys are better, but shorter keys
@@ -523,7 +575,7 @@ nameserver 172.16.72.4
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2571138"></a>Manual Generation</h4></div></div></div>
+<a name="id2571398"></a>Manual Generation</h4></div></div></div>
<p>
The shared secret is simply a random sequence of bits, encoded
in base-64. Most ASCII strings are valid base-64 strings (assuming
@@ -538,7 +590,7 @@ nameserver 172.16.72.4
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571156"></a>Copying the Shared Secret to Both Machines</h3></div></div></div>
+<a name="id2571553"></a>Copying the Shared Secret to Both Machines</h3></div></div></div>
<p>
This is beyond the scope of DNS. A secure transport mechanism
should be used. This could be secure FTP, ssh, telephone, etc.
@@ -546,7 +598,7 @@ nameserver 172.16.72.4
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571166"></a>Informing the Servers of the Key's Existence</h3></div></div></div>
+<a name="id2571563"></a>Informing the Servers of the Key's Existence</h3></div></div></div>
<p>
Imagine <span class="emphasis"><em>host1</em></span> and <span class="emphasis"><em>host 2</em></span>
are
@@ -573,7 +625,7 @@ key host1-host2. {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571203"></a>Instructing the Server to Use the Key</h3></div></div></div>
+<a name="id2571600"></a>Instructing the Server to Use the Key</h3></div></div></div>
<p>
Since keys are shared between two hosts only, the server must
be told when keys are to be used. The following is added to the <code class="filename">named.conf</code> file
@@ -605,7 +657,7 @@ server 10.1.2.3 {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571260"></a>TSIG Key Based Access Control</h3></div></div></div>
+<a name="id2571657"></a>TSIG Key Based Access Control</h3></div></div></div>
<p>
<acronym class="acronym">BIND</acronym> allows IP addresses and ranges
to be specified in ACL
@@ -626,14 +678,13 @@ allow-update { key host1-host2. ;};
was signed by a key named "<span><strong class="command">host1-host2.</strong></span>".
</p>
<p>
- You may want to read about the more powerful
- <span><strong class="command">update-policy</strong></span> statement in
- <a href="Bv9ARM.ch06.html#dynamic_update_policies" title="Dynamic Update Policies">the section called &#8220;Dynamic Update Policies&#8221;</a>.
+ See <a href="Bv9ARM.ch06.html#dynamic_update_policies" title="Dynamic Update Policies">the section called &#8220;Dynamic Update Policies&#8221;</a> for a discussion of
+ the more flexible <span><strong class="command">update-policy</strong></span> statement.
</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571445"></a>Errors</h3></div></div></div>
+<a name="id2571706"></a>Errors</h3></div></div></div>
<p>
The processing of TSIG signed messages can result in
several errors. If a signed message is sent to a non-TSIG aware
@@ -659,7 +710,7 @@ allow-update { key host1-host2. ;};
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2571459"></a>TKEY</h2></div></div></div>
+<a name="id2571720"></a>TKEY</h2></div></div></div>
<p><span><strong class="command">TKEY</strong></span>
is a mechanism for automatically generating a shared secret
between two hosts. There are several "modes" of
@@ -695,7 +746,7 @@ allow-update { key host1-host2. ;};
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2571576"></a>SIG(0)</h2></div></div></div>
+<a name="id2563987"></a>SIG(0)</h2></div></div></div>
<p>
<acronym class="acronym">BIND</acronym> 9 partially supports DNSSEC SIG(0)
transaction signatures as specified in RFC 2535 and RFC 2931.
@@ -756,7 +807,7 @@ allow-update { key host1-host2. ;};
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571644"></a>Generating Keys</h3></div></div></div>
+<a name="id2564055"></a>Generating Keys</h3></div></div></div>
<p>
The <span><strong class="command">dnssec-keygen</strong></span> program is used to
generate keys.
@@ -812,7 +863,7 @@ allow-update { key host1-host2. ;};
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571792"></a>Signing the Zone</h3></div></div></div>
+<a name="id2572189"></a>Signing the Zone</h3></div></div></div>
<p>
The <span><strong class="command">dnssec-signzone</strong></span> program is used
to sign a zone.
@@ -854,7 +905,7 @@ allow-update { key host1-host2. ;};
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2571873"></a>Configuring Servers</h3></div></div></div>
+<a name="id2572270"></a>Configuring Servers</h3></div></div></div>
<p>
To enable <span><strong class="command">named</strong></span> to respond appropriately
to DNS requests from DNSSEC aware clients,
@@ -863,12 +914,22 @@ allow-update { key host1-host2. ;};
</p>
<p>
To enable <span><strong class="command">named</strong></span> to validate answers from
- other servers, the <span><strong class="command">dnssec-enable</strong></span> and
- <span><strong class="command">dnssec-validation</strong></span> options must both be
- set to yes (the default setting in <acronym class="acronym">BIND</acronym> 9.5
- and later), and at least one trust anchor must be configured
- with a <span><strong class="command">trusted-keys</strong></span> statement in
- <code class="filename">named.conf</code>.
+ other servers, the <span><strong class="command">dnssec-enable</strong></span> option
+ must be set to <strong class="userinput"><code>yes</code></strong>, and the
+ <span><strong class="command">dnssec-validation</strong></span> options must be set to
+ <strong class="userinput"><code>yes</code></strong> or <strong class="userinput"><code>auto</code></strong>.
+ </p>
+<p>
+ If <span><strong class="command">dnssec-validation</strong></span> is set to
+ <strong class="userinput"><code>auto</code></strong>, then a default
+ trust anchor for the DNS root zone will be used.
+ If it is set to <strong class="userinput"><code>yes</code></strong>, however,
+ then at least one trust anchor must be configured
+ with a <span><strong class="command">trusted-keys</strong></span> or
+ <span><strong class="command">managed-keys</strong></span> statement in
+ <code class="filename">named.conf</code>, or DNSSEC validation
+ will not occur. The default setting is
+ <strong class="userinput"><code>yes</code></strong>.
</p>
<p>
<span><strong class="command">trusted-keys</strong></span> are copies of DNSKEY RRs
@@ -879,7 +940,13 @@ allow-update { key host1-host2. ;};
to validated the DNSKEY RRset that they are from.
</p>
<p>
- <span><strong class="command">trusted-keys</strong></span> are described in more detail
+ <span><strong class="command">managed-keys</strong></span> are trusted keys which are
+ automatically kept up to date via RFC 5011 trust anchor
+ maintenance.
+ </p>
+<p>
+ <span><strong class="command">trusted-keys</strong></span> and
+ <span><strong class="command">managed-keys</strong></span> are described in more detail
later in this document.
</p>
<p>
@@ -890,44 +957,58 @@ allow-update { key host1-host2. ;};
</p>
<p>
After DNSSEC gets established, a typical DNSSEC configuration
- will look something like the following. It has a one or
+ will look something like the following. It has one or
more public keys for the root. This allows answers from
outside the organization to be validated. It will also
have several keys for parts of the namespace the organization
- controls. These are here to ensure that <span><strong class="command">named</strong></span> is immune
- to compromises in the DNSSEC components of the security
+ controls. These are here to ensure that <span><strong class="command">named</strong></span>
+ is immune to compromises in the DNSSEC components of the security
of parent zones.
</p>
<pre class="programlisting">
-trusted-keys {
-
+managed-keys {
/* Root Key */
-"." 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwSJxrGkxJWoZu6I7PzJu/
- E9gx4UC1zGAHlXKdE4zYIpRhaBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3
- zy2Xy4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYghf+6fElrmLkdaz
- MQ2OCnACR817DF4BBa7UR/beDHyp5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M
- /lUUVRbkeg1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq66gKodQj+M
- iA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ97S+LKUTpQcq27R7AT3/V5hRQxScI
- Nqwcz4jYqZD2fQdgxbcDTClU0CRBdiieyLMNzXG3";
+ "." initial-key 257 3 3 "BNY4wrWM1nCfJ+CXd0rVXyYmobt7sEEfK3clRbGaTwS
+ JxrGkxJWoZu6I7PzJu/E9gx4UC1zGAHlXKdE4zYIpRh
+ aBKnvcC2U9mZhkdUpd1Vso/HAdjNe8LmMlnzY3zy2Xy
+ 4klWOADTPzSv9eamj8V18PHGjBLaVtYvk/ln5ZApjYg
+ hf+6fElrmLkdaz MQ2OCnACR817DF4BBa7UR/beDHyp
+ 5iWTXWSi6XmoJLbG9Scqc7l70KDqlvXR3M/lUUVRbke
+ g1IPJSidmK3ZyCllh4XSKbje/45SKucHgnwU5jefMtq
+ 66gKodQj+MiA21AfUVe7u99WzTLzY3qlxDhxYQQ20FQ
+ 97S+LKUTpQcq27R7AT3/V5hRQxScINqwcz4jYqZD2fQ
+ dgxbcDTClU0CRBdiieyLMNzXG3";
+};
-/* Key for our organization's forward zone */
-example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM65KbhTjrW1ZaARmPhEZZe
- 3Y9ifgEuq7vZ/zGZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb4JKUbb
- OTcM8pwXlj0EiX3oDFVmjHO444gLkBO UKUf/mC7HvfwYH/Be22GnC
- lrinKJp1Og4ywzO9WglMk7jbfW33gUKvirTHr25GL7STQUzBb5Usxt
- 8lgnyTUHs1t3JwCY5hKZ6CqFxmAVZP20igTixin/1LcrgX/KMEGd/b
- iuvF4qJCyduieHukuY3H4XMAcR+xia2 nIUPvm/oyWR8BW/hWdzOvn
- SCThlHf3xiYleDbt/o1OTQ09A0=";
+trusted-keys {
+ /* Key for our organization's forward zone */
+ example.com. 257 3 5 "AwEAAaxPMcR2x0HbQV4WeZB6oEDX+r0QM6
+ 5KbhTjrW1ZaARmPhEZZe3Y9ifgEuq7vZ/z
+ GZUdEGNWy+JZzus0lUptwgjGwhUS1558Hb
+ 4JKUbbOTcM8pwXlj0EiX3oDFVmjHO444gL
+ kBOUKUf/mC7HvfwYH/Be22GnClrinKJp1O
+ g4ywzO9WglMk7jbfW33gUKvirTHr25GL7S
+ TQUzBb5Usxt8lgnyTUHs1t3JwCY5hKZ6Cq
+ FxmAVZP20igTixin/1LcrgX/KMEGd/biuv
+ F4qJCyduieHukuY3H4XMAcR+xia2nIUPvm
+ /oyWR8BW/hWdzOvnSCThlHf3xiYleDbt/o
+ 1OTQ09A0=";
-/* Key for our reverse zone. */
-2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwcxOdNax071L18QqZnQQQA
- VVr+iLhGTnNGp3HoWQLUIzKrJVZ3zggy3WwNT6kZo6c0
- tszYqbtvchmgQC8CzKojM/W16i6MG/ea fGU3siaOdS0
- yOI6BgPsw+YZdzlYMaIJGf4M4dyoKIhzdZyQ2bYQrjyQ
- 4LB0lC7aOnsMyYKHHYeRv PxjIQXmdqgOJGq+vsevG06
- zW+1xgYJh9rCIfnm1GX/KMgxLPG2vXTD/RnLX+D3T3UL
- 7HJYHJhAZD5L59VvjSPsZJHeDCUyWYrvPZesZDIRvhDD
- 52SKvbheeTJUm6EhkzytNN2SN96QRk8j/iI8ib";
+ /* Key for our reverse zone. */
+ 2.0.192.IN-ADDRPA.NET. 257 3 5 "AQOnS4xn/IgOUpBPJ3bogzwc
+ xOdNax071L18QqZnQQQAVVr+i
+ LhGTnNGp3HoWQLUIzKrJVZ3zg
+ gy3WwNT6kZo6c0tszYqbtvchm
+ gQC8CzKojM/W16i6MG/eafGU3
+ siaOdS0yOI6BgPsw+YZdzlYMa
+ IJGf4M4dyoKIhzdZyQ2bYQrjy
+ Q4LB0lC7aOnsMyYKHHYeRvPxj
+ IQXmdqgOJGq+vsevG06zW+1xg
+ YJh9rCIfnm1GX/KMgxLPG2vXT
+ D/RnLX+D3T3UL7HJYHJhAZD5L
+ 59VvjSPsZJHeDCUyWYrvPZesZ
+ DIRvhDD52SKvbheeTJUm6Ehkz
+ ytNN2SN96QRk8j/iI8ib";
};
options {
@@ -979,7 +1060,698 @@ options {
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2572110"></a>IPv6 Support in <acronym class="acronym">BIND</acronym> 9</h2></div></div></div>
+<a name="dnssec.dynamic.zones"></a>DNSSEC, Dynamic Zones, and Automatic Signing</h2></div></div></div>
+<p>As of BIND 9.7.0 it is possible to change a dynamic zone
+ from insecure to signed and back again. A secure zone can use
+ either NSEC or NSEC3 chains.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2607351"></a>Converting from insecure to secure</h3></div></div></div></div>
+<p>Changing a zone from insecure to secure can be done in two
+ ways: using a dynamic DNS update, or the
+ <span><strong class="command">auto-dnssec</strong></span> zone option.</p>
+<p>For either method, you need to configure
+ <span><strong class="command">named</strong></span> so that it can see the
+ <code class="filename">K*</code> files which contain the public and private
+ parts of the keys that will be used to sign the zone. These files
+ will have been generated by
+ <span><strong class="command">dnssec-keygen</strong></span>. You can do this by placing them
+ in the key-directory, as specified in
+ <code class="filename">named.conf</code>:</p>
+<pre class="programlisting">
+ zone example.net {
+ type master;
+ update-policy local;
+ file "dynamic/example.net/example.net";
+ key-directory "dynamic/example.net";
+ };
+</pre>
+<p>If one KSK and one ZSK DNSKEY key have been generated, this
+ configuration will cause all records in the zone to be signed
+ with the ZSK, and the DNSKEY RRset to be signed with the KSK as
+ well. An NSEC chain will be generated as part of the initial
+ signing process.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563493"></a>Dynamic DNS update method</h3></div></div></div></div>
+<p>To insert the keys via dynamic update:</p>
+<pre class="screen">
+ % nsupdate
+ &gt; ttl 3600
+ &gt; update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
+ &gt; update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
+ &gt; send
+</pre>
+<p>While the update request will complete almost immediately,
+ the zone will not be completely signed until
+ <span><strong class="command">named</strong></span> has had time to walk the zone and
+ generate the NSEC and RRSIG records. The NSEC record at the apex
+ will be added last, to signal that there is a complete NSEC
+ chain.</p>
+<p>If you wish to sign using NSEC3 instead of NSEC, you should
+ add an NSEC3PARAM record to the initial update request. If you
+ wish the NSEC3 chain to have the OPTOUT bit set, set it in the
+ flags field of the NSEC3PARAM record.</p>
+<pre class="screen">
+ % nsupdate
+ &gt; ttl 3600
+ &gt; update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
+ &gt; update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
+ &gt; update add example.net NSEC3PARAM 1 1 100 1234567890
+ &gt; send
+</pre>
+<p>Again, this update request will complete almost
+ immediately; however, the record won't show up until
+ <span><strong class="command">named</strong></span> has had a chance to build/remove the
+ relevant chain. A private type record will be created to record
+ the state of the operation (see below for more details), and will
+ be removed once the operation completes.</p>
+<p>While the initial signing and NSEC/NSEC3 chain generation
+ is happening, other updates are possible as well.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563529"></a>Fully automatic zone signing</h3></div></div></div></div>
+<p>To enable automatic signing, add the
+ <span><strong class="command">auto-dnssec</strong></span> option to the zone statement in
+ <code class="filename">named.conf</code>.
+ <span><strong class="command">auto-dnssec</strong></span> has two possible arguments:
+ <code class="constant">allow</code> or
+ <code class="constant">maintain</code>.</p>
+<p>With
+ <span><strong class="command">auto-dnssec allow</strong></span>,
+ <span><strong class="command">named</strong></span> can search the key directory for keys
+ matching the zone, insert them into the zone, and use them to
+ sign the zone. It will do so only when it receives an
+ <span><strong class="command">rndc sign &lt;zonename&gt;</strong></span> or
+ <span><strong class="command">rndc loadkeys &lt;zonename&gt;</strong></span> command.</p>
+<p>
+
+ <span><strong class="command">auto-dnssec maintain</strong></span> includes the above
+ functionality, but will also automatically adjust the zone's
+ DNSKEY records on schedule according to the keys' timing metadata.
+ (See <a href="man.dnssec-keygen.html" title="dnssec-keygen"><span class="refentrytitle"><span class="application">dnssec-keygen</span></span>(8)</a> and
+ <a href="man.dnssec-settime.html" title="dnssec-settime"><span class="refentrytitle"><span class="application">dnssec-settime</span></span>(8)</a> for more information.)
+ If keys are present in the key directory the first time the zone
+ is loaded, it will be signed immediately, without waiting for an
+ <span><strong class="command">rndc sign</strong></span> or <span><strong class="command">rndc loadkeys</strong></span>
+ command. (Those commands can still be used when there are unscheduled
+ key changes, however.)
+ </p>
+<p>Using the
+ <span><strong class="command">auto-dnssec</strong></span> option requires the zone to be
+ configured to allow dynamic updates, by adding an
+ <span><strong class="command">allow-update</strong></span> or
+ <span><strong class="command">update-policy</strong></span> statement to the zone
+ configuration. If this has not been done, the configuration will
+ fail.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563611"></a>Private-type records</h3></div></div></div></div>
+<p>The state of the signing process is signaled by
+ private-type records (with a default type value of 65534). When
+ signing is complete, these records will have a nonzero value for
+ the final octet (for those records which have a nonzero initial
+ octet).</p>
+<p>The private type record format: If the first octet is
+ non-zero then the record indicates that the zone needs to be
+ signed with the key matching the record, or that all signatures
+ that match the record should be removed.</p>
+<p>
+ </p>
+<div class="literallayout"><p><br>
+<br>
+  algorithm (octet 1)<br>
+  key id in network order (octet 2 and 3)<br>
+  removal flag (octet 4)<br>
+  complete flag (octet 5)<br>
+</p></div>
+<p>
+ </p>
+<p>Only records flagged as "complete" can be removed via
+ dynamic update. Attempts to remove other private type records
+ will be silently ignored.</p>
+<p>If the first octet is zero (this is a reserved algorithm
+ number that should never appear in a DNSKEY record) then the
+ record indicates changes to the NSEC3 chains are in progress. The
+ rest of the record contains an NSEC3PARAM record. The flag field
+ tells what operation to perform based on the flag bits.</p>
+<p>
+ </p>
+<div class="literallayout"><p><br>
+<br>
+  0x01 OPTOUT<br>
+  0x80 CREATE<br>
+  0x40 REMOVE<br>
+  0x20 NONSEC<br>
+</p></div>
+<p>
+ </p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563649"></a>DNSKEY rollovers</h3></div></div></div></div>
+<p>As with insecure-to-secure conversions, rolling DNSSEC
+ keys can be done in two ways: using a dynamic DNS update, or the
+ <span><strong class="command">auto-dnssec</strong></span> zone option.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563661"></a>Dynamic DNS update method</h3></div></div></div></div>
+<p> To perform key rollovers via dynamic update, you need to add
+ the <code class="filename">K*</code> files for the new keys so that
+ <span><strong class="command">named</strong></span> can find them. You can then add the new
+ DNSKEY RRs via dynamic update.
+ <span><strong class="command">named</strong></span> will then cause the zone to be signed
+ with the new keys. When the signing is complete the private type
+ records will be updated so that the last octet is non
+ zero.</p>
+<p>If this is for a KSK you need to inform the parent and any
+ trust anchor repositories of the new KSK.</p>
+<p>You should then wait for the maximum TTL in the zone before
+ removing the old DNSKEY. If it is a KSK that is being updated,
+ you also need to wait for the DS RRset in the parent to be
+ updated and its TTL to expire. This ensures that all clients will
+ be able to verify at least one signature when you remove the old
+ DNSKEY.</p>
+<p>The old DNSKEY can be removed via UPDATE. Take care to
+ specify the correct key.
+ <span><strong class="command">named</strong></span> will clean out any signatures generated
+ by the old key after the update completes.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563763"></a>Automatic key rollovers</h3></div></div></div></div>
+<p>When a new key reaches its activation date (as set by
+ <span><strong class="command">dnssec-keygen</strong></span> or <span><strong class="command">dnssec-settime</strong></span>),
+ if the <span><strong class="command">auto-dnssec</strong></span> zone option is set to
+ <code class="constant">maintain</code>, <span><strong class="command">named</strong></span> will
+ automatically carry out the key rollover. If the key's algorithm
+ has not previously been used to sign the zone, then the zone will
+ be fully signed as quickly as possible. However, if the new key
+ is replacing an existing key of the same algorithm, then the
+ zone will be re-signed incrementally, with signatures from the
+ old key being replaced with signatures from the new key as their
+ signature validity periods expire. By default, this rollover
+ completes in 30 days, after which it will be safe to remove the
+ old key from the DNSKEY RRset.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563789"></a>NSEC3PARAM rollovers via UPDATE</h3></div></div></div></div>
+<p>Add the new NSEC3PARAM record via dynamic update. When the
+ new NSEC3 chain has been generated, the NSEC3PARAM flag field
+ will be zero. At this point you can remove the old NSEC3PARAM
+ record. The old chain will be removed after the update request
+ completes.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563799"></a>Converting from NSEC to NSEC3</h3></div></div></div></div>
+<p>To do this, you just need to add an NSEC3PARAM record. When
+ the conversion is complete, the NSEC chain will have been removed
+ and the NSEC3PARAM record will have a zero flag field. The NSEC3
+ chain will be generated before the NSEC chain is
+ destroyed.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563809"></a>Converting from NSEC3 to NSEC</h3></div></div></div></div>
+<p>To do this, use <span><strong class="command">nsupdate</strong></span> to
+ remove all NSEC3PARAM records with a zero flag
+ field. The NSEC chain will be generated before the NSEC3 chain is
+ removed.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563821"></a>Converting from secure to insecure</h3></div></div></div></div>
+<p>To convert a signed zone to unsigned using dynamic DNS,
+ delete all the DNSKEY records from the zone apex using
+ <span><strong class="command">nsupdate</strong></span>. All signatures, NSEC or NSEC3 chains,
+ and associated NSEC3PARAM records will be removed automatically.
+ This will take place after the update request completes.</p>
+<p> This requires the
+ <span><strong class="command">dnssec-secure-to-insecure</strong></span> option to be set to
+ <strong class="userinput"><code>yes</code></strong> in
+ <code class="filename">named.conf</code>.</p>
+<p>In addition, if the <span><strong class="command">auto-dnssec maintain</strong></span>
+ zone statement is used, it should be removed or changed to
+ <span><strong class="command">allow</strong></span> instead (or it will re-sign).
+ </p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563859"></a>Periodic re-signing</h3></div></div></div></div>
+<p>In any secure zone which supports dynamic updates, named
+ will periodically re-sign RRsets which have not been re-signed as
+ a result of some update action. The signature lifetimes will be
+ adjusted so as to spread the re-sign load over time rather than
+ all at once.</p>
+<div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title">
+<a name="id2563868"></a>NSEC3 and OPTOUT</h3></div></div></div></div>
+<p>
+ <span><strong class="command">named</strong></span> only supports creating new NSEC3 chains
+ where all the NSEC3 records in the zone have the same OPTOUT
+ state.
+ <span><strong class="command">named</strong></span> supports UPDATES to zones where the NSEC3
+ records in the chain have mixed OPTOUT state.
+ <span><strong class="command">named</strong></span> does not support changing the OPTOUT
+ state of an individual NSEC3 record, the entire chain needs to be
+ changed if the OPTOUT state of an individual NSEC3 needs to be
+ changed.</p>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="rfc5011.support"></a>Dynamic Trust Anchor Management</h2></div></div></div>
+<p>BIND 9.7.0 introduces support for RFC 5011, dynamic trust
+ anchor management. Using this feature allows
+ <span><strong class="command">named</strong></span> to keep track of changes to critical
+ DNSSEC keys without any need for the operator to make changes to
+ configuration files.</p>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2607271"></a>Validating Resolver</h3></div></div></div>
+<p>To configure a validating resolver to use RFC 5011 to
+ maintain a trust anchor, configure the trust anchor using a
+ <span><strong class="command">managed-keys</strong></span> statement. Information about
+ this can be found in
+ <a href="Bv9ARM.ch06.html#managed-keys" title="managed-keys Statement Definition
+ and Usage">the section called &#8220;<span><strong class="command">managed-keys</strong></span> Statement Definition
+ and Usage&#8221;</a>.</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2607293"></a>Authoritative Server</h3></div></div></div>
+<p>To set up an authoritative zone for RFC 5011 trust anchor
+ maintenance, generate two (or more) key signing keys (KSKs) for
+ the zone. Sign the zone with one of them; this is the "active"
+ KSK. All KSK's which do not sign the zone are "stand-by"
+ keys.</p>
+<p>Any validating resolver which is configured to use the
+ active KSK as an RFC 5011-managed trust anchor will take note
+ of the stand-by KSKs in the zone's DNSKEY RRset, and store them
+ for future reference. The resolver will recheck the zone
+ periodically, and after 30 days, if the new key is still there,
+ then the key will be accepted by the resolver as a valid trust
+ anchor for the zone. Any time after this 30-day acceptance
+ timer has completed, the active KSK can be revoked, and the
+ zone can be "rolled over" to the newly accepted key.</p>
+<p>The easiest way to place a stand-by key in a zone is to
+ use the "smart signing" features of
+ <span><strong class="command">dnssec-keygen</strong></span> and
+ <span><strong class="command">dnssec-signzone</strong></span>. If a key with a publication
+ date in the past, but an activation date which is unset or in
+ the future, "
+ <span><strong class="command">dnssec-signzone -S</strong></span>" will include the DNSKEY
+ record in the zone, but will not sign with it:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>dnssec-keygen -K keys -f KSK -P now -A now+2y example.net</code></strong>
+$ <strong class="userinput"><code>dnssec-signzone -S -K keys example.net</code></strong>
+</pre>
+<p>To revoke a key, the new command
+ <span><strong class="command">dnssec-revoke</strong></span> has been added. This adds the
+ REVOKED bit to the key flags and re-generates the
+ <code class="filename">K*.key</code> and
+ <code class="filename">K*.private</code> files.</p>
+<p>After revoking the active key, the zone must be signed
+ with both the revoked KSK and the new active KSK. (Smart
+ signing takes care of this automatically.)</p>
+<p>Once a key has been revoked and used to sign the DNSKEY
+ RRset in which it appears, that key will never again be
+ accepted as a valid trust anchor by the resolver. However,
+ validation can proceed using the new active key (which had been
+ accepted by the resolver when it was a stand-by key).</p>
+<p>See RFC 5011 for more details on key rollover
+ scenarios.</p>
+<p>When a key has been revoked, its key ID changes,
+ increasing by 128, and wrapping around at 65535. So, for
+ example, the key "<code class="filename">Kexample.com.+005+10000</code>" becomes
+ "<code class="filename">Kexample.com.+005+10128</code>".</p>
+<p>If two keys have ID's exactly 128 apart, and one is
+ revoked, then the two key ID's will collide, causing several
+ problems. To prevent this,
+ <span><strong class="command">dnssec-keygen</strong></span> will not generate a new key if
+ another key is present which may collide. This checking will
+ only occur if the new keys are written to the same directory
+ which holds all other keys in use for that zone.</p>
+<p>Older versions of BIND 9 did not have this precaution.
+ Exercise caution if using key revocation on keys that were
+ generated by previous releases, or if using keys stored in
+ multiple directories or on multiple machines.</p>
+<p>It is expected that a future release of BIND 9 will
+ address this problem in a different way, by storing revoked
+ keys with their original unrevoked key ID's.</p>
+</div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="pkcs11"></a>PKCS #11 (Cryptoki) support</h2></div></div></div>
+<p>PKCS #11 (Public Key Cryptography Standard #11) defines a
+ platform- independent API for the control of hardware security
+ modules (HSMs) and other cryptographic support devices.</p>
+<p>BIND 9 is known to work with two HSMs: The Sun SCA 6000
+ cryptographic acceleration board, tested under Solaris x86, and
+ the AEP Keyper network-attached key storage device, tested with
+ Debian Linux, Solaris x86 and Windows Server 2003.</p>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2609524"></a>Prerequisites</h3></div></div></div>
+<p>See the HSM vendor documentation for information about
+ installing, initializing, testing and troubleshooting the
+ HSM.</p>
+<p>BIND 9 uses OpenSSL for cryptography, but stock OpenSSL
+ does not yet fully support PKCS #11. However, a PKCS #11 engine
+ for OpenSSL is available from the OpenSolaris project. It has
+ been modified by ISC to work with with BIND 9, and to provide
+ new features such as PIN management and key by
+ reference.</p>
+<p>The patched OpenSSL depends on a "PKCS #11 provider".
+ This is a shared library object, providing a low-level PKCS #11
+ interface to the HSM hardware. It is dynamically loaded by
+ OpenSSL at runtime. The PKCS #11 provider comes from the HSM
+ vendor, and and is specific to the HSM to be controlled.</p>
+<p>There are two "flavors" of PKCS #11 support provided by
+ the patched OpenSSL, one of which must be chosen at
+ configuration time. The correct choice depends on the HSM
+ hardware:</p>
+<div class="itemizedlist"><ul type="disc">
+<li><p>Use 'crypto-accelerator' with HSMs that have hardware
+ cryptographic acceleration features, such as the SCA 6000
+ board. This causes OpenSSL to run all supported
+ cryptographic operations in the HSM.</p></li>
+<li><p>Use 'sign-only' with HSMs that are designed to
+ function primarily as secure key storage devices, but lack
+ hardware acceleration. These devices are highly secure, but
+ are not necessarily any faster at cryptography than the
+ system CPU &#8212; often, they are slower. It is therefore
+ most efficient to use them only for those cryptographic
+ functions that require access to the secured private key,
+ such as zone signing, and to use the system CPU for all
+ other computationally-intensive operations. The AEP Keyper
+ is an example of such a device.</p></li>
+</ul></div>
+<p>The modified OpenSSL code is included in the BIND 9.7.0
+ release, in the form of a context diff against the latest OpenSSL.
+ </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Note</h3>
+ The latest OpenSSL version at the time of the BIND release
+ is 0.9.8l.
+ ISC will provide an updated patch as new versions of OpenSSL
+ are released. The version number in the following examples
+ is expected to change.</div>
+<p>
+ Before building BIND 9 with PKCS #11 support, it will be
+ necessary to build OpenSSL with this patch in place and inform
+ it of the path to the HSM-specific PKCS #11 provider
+ library.</p>
+<p>Obtain OpenSSL 0.9.8l:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>wget <a href="" target="_top">http://www.openssl.org/source/openssl-0.9.8l.tar.gz</a></code></strong>
+</pre>
+<p>Extract the tarball:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>tar zxf openssl-0.9.8l.tar.gz</code></strong>
+</pre>
+<p>Apply the patch from the BIND 9 release:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>patch -p1 -d openssl-0.9.8l \
+ &lt; bind-9.7.0/bin/pkcs11/openssl-0.9.8l-patch</code></strong>
+</pre>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Note</h3>(Note that the patch file may not be compatible with the
+ "patch" utility on all operating systems. You may need to
+ install GNU patch.)</div>
+<p>When building OpenSSL, place it in a non-standard
+ location so that it does not interfere with OpenSSL libraries
+ elsewhere on the system. In the following examples, we choose
+ to install into "/opt/pkcs11/usr". We will use this location
+ when we configure BIND 9.</p>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2607504"></a>Building OpenSSL for the AEP Keyper on Linux</h4></div></div></div>
+<p>The AEP Keyper is a highly secure key storage device,
+ but does not provide hardware cryptographic acceleration. It
+ can carry out cryptographic operations, but it is probably
+ slower than your system's CPU. Therefore, we choose the
+ 'sign-only' flavor when building OpenSSL.</p>
+<p>The Keyper-specific PKCS #11 provider library is
+ delivered with the Keyper software. In this example, we place
+ it /opt/pkcs11/usr/lib:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>cp pkcs11.GCC4.0.2.so.4.05 /opt/pkcs11/usr/lib/libpkcs11.so</code></strong>
+</pre>
+<p>This library is only available for Linux as a 32-bit
+ binary. If we are compiling on a 64-bit Linux system, it is
+ necessary to force a 32-bit build, by specifying -m32 in the
+ build options.</p>
+<p>Finally, the Keyper library requires threads, so we
+ must specify -pthread.</p>
+<pre class="screen">
+$ <strong class="userinput"><code>cd openssl-0.9.8l</code></strong>
+$ <strong class="userinput"><code>./Configure linux-generic32 -m32 -pthread \
+ --pk11-libname=/opt/pkcs11/usr/lib/libpkcs11.so \
+ --pk11-flavor=sign-only \
+ --prefix=/opt/pkcs11/usr</code></strong>
+</pre>
+<p>After configuring, run "<span><strong class="command">make</strong></span>"
+ and "<span><strong class="command">make test</strong></span>". If "<span><strong class="command">make
+ test</strong></span>" fails with "pthread_atfork() not found", you forgot to
+ add the -pthread above.</p>
+</div>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2607573"></a>Building OpenSSL for the SCA 6000 on Solaris</h4></div></div></div>
+<p>The SCA-6000 PKCS #11 provider is installed as a system
+ library, libpkcs11. It is a true crypto accelerator, up to 4
+ times faster than any CPU, so the flavor shall be
+ 'crypto-accelerator'.</p>
+<p>In this example, we are building on Solaris x86 on an
+ AMD64 system.</p>
+<pre class="screen">
+$ <strong class="userinput"><code>cd openssl-0.9.8l</code></strong>
+$ <strong class="userinput"><code>./Configure solaris64-x86_64-cc \
+ --pk11-libname=/usr/lib/64/libpkcs11.so \
+ --pk11-flavor=crypto-accelerator \
+ --prefix=/opt/pkcs11/usr</code></strong>
+</pre>
+<p>(For a 32-bit build, use "solaris-x86-cc" and
+ /usr/lib/libpkcs11.so.)</p>
+<p>After configuring, run
+ <span><strong class="command">make</strong></span> and
+ <span><strong class="command">make test</strong></span>.</p>
+<p>Once you have built OpenSSL, run
+ "<span><strong class="command">apps/openssl engine pkcs11</strong></span>" to confirm
+ that PKCS #11 support was compiled in correctly. The output
+ should be one of the following lines, depending on the flavor
+ selected:</p>
+<pre class="screen">
+ (pkcs11) PKCS #11 engine support (sign only)
+</pre>
+<p>Or:</p>
+<pre class="screen">
+ (pkcs11) PKCS #11 engine support (crypto accelerator)
+</pre>
+<p>Next, run
+ "<span><strong class="command">apps/openssl engine pkcs11 -t</strong></span>". This will
+ attempt to initialize the PKCS #11 engine. If it is able to
+ do so successfully, it will report
+ &#8220;<span class="quote"><code class="literal">[ available ]</code></span>&#8221;.</p>
+<p>If the output is correct, run
+ "<span><strong class="command">make install</strong></span>" which will install the
+ modified OpenSSL suite to
+ <code class="filename">/opt/pkcs11/usr</code>.</p>
+</div>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2607678"></a>Building BIND 9 with PKCS#11</h3></div></div></div>
+<p>When building BIND 9, the location of the custom-built
+ OpenSSL library must be specified via configure.</p>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2607687"></a>Configuring BIND 9 for Linux</h4></div></div></div>
+<p>To link with the PKCS #11 provider, threads must be
+ enabled in the BIND 9 build.</p>
+<p>The PKCS #11 library for the AEP Keyper is currently
+ only available as a 32-bit binary. If we are building on a
+ 64-bit host, we must force a 32-bit build by adding "-m32" to
+ the CC options on the "configure" command line.</p>
+<pre class="screen">
+$ <strong class="userinput"><code>cd ../bind-9.7.0</code></strong>
+$ <strong class="userinput"><code>./configure CC="gcc -m32" --enable-threads \
+ --with-openssl=/opt/pkcs11/usr \
+ --with-pkcs11=/opt/pkcs11/usr/lib/libpkcs11.so</code></strong>
+</pre>
+</div>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2607786"></a>Configuring BIND 9 for Solaris</h4></div></div></div>
+<p>To link with the PKCS #11 provider, threads must be
+ enabled in the BIND 9 build.</p>
+<pre class="screen">
+$ <strong class="userinput"><code>cd ../bind-9.7.0</code></strong>
+$ <strong class="userinput"><code>./configure CC="cc -xarch=amd64" --enable-threads \
+ --with-openssl=/opt/pkcs11/usr \
+ --with-pkcs11=/usr/lib/64/libpkcs11.so</code></strong>
+</pre>
+<p>(For a 32-bit build, omit CC="cc -xarch=amd64".)</p>
+<p>If configure complains about OpenSSL not working, you
+ may have a 32/64-bit architecture mismatch. Or, you may have
+ incorrectly specified the path to OpenSSL (it should be the
+ same as the --prefix argument to the OpenSSL
+ Configure).</p>
+</div>
+<p>After configuring, run
+ "<span><strong class="command">make</strong></span>",
+ "<span><strong class="command">make test</strong></span>" and
+ "<span><strong class="command">make install</strong></span>".</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2607842"></a>PKCS #11 Tools</h3></div></div></div>
+<p>BIND 9 includes a minimal set of tools to operate the
+ HSM, including
+ <span><strong class="command">pkcs11-keygen</strong></span> to generate a new key pair
+ within the HSM,
+ <span><strong class="command">pkcs11-list</strong></span> to list objects currently
+ available, and
+ <span><strong class="command">pkcs11-destroy</strong></span> to remove objects.</p>
+<p>In UNIX/Linux builds, these tools are built only if BIND
+ 9 is configured with the --with-pkcs11 option. (NOTE: If
+ --with-pkcs11 is set to "yes", rather than to the path of the
+ PKCS #11 provider, then the tools will be built but the
+ provider will be left undefined. Use the -m option or the
+ PKCS11_PROVIDER environment variable to specify the path to the
+ provider.)</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2607873"></a>Using the HSM</h3></div></div></div>
+<p>First, we must set up the runtime environment so the
+ OpenSSL and PKCS #11 libraries can be loaded:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>export LD_LIBRARY_PATH=/opt/pkcs11/usr/lib:${LD_LIBRARY_PATH}</code></strong>
+</pre>
+<p>When operating an AEP Keyper, it is also necessary to
+ specify the location of the "machine" file, which stores
+ information about the Keyper for use by PKCS #11 provider
+ library. If the machine file is in
+ <code class="filename">/opt/Keyper/PKCS11Provider/machine</code>,
+ use:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>export KEYPER_LIBRARY_PATH=/opt/Keyper/PKCS11Provider</code></strong>
+</pre>
+<p>These environment variables must be set whenever running
+ any tool that uses the HSM, including
+ <span><strong class="command">pkcs11-keygen</strong></span>,
+ <span><strong class="command">pkcs11-list</strong></span>,
+ <span><strong class="command">pkcs11-destroy</strong></span>,
+ <span><strong class="command">dnssec-keyfromlabel</strong></span>,
+ <span><strong class="command">dnssec-signzone</strong></span>,
+ <span><strong class="command">dnssec-keygen</strong></span>(which will use the HSM for
+ random number generation), and
+ <span><strong class="command">named</strong></span>.</p>
+<p>We can now create and use keys in the HSM. In this case,
+ we will create a 2048 bit key and give it the label
+ "sample-ksk":</p>
+<pre class="screen">
+$ <strong class="userinput"><code>pkcs11-keygen -b 2048 -l sample-ksk</code></strong>
+</pre>
+<p>To confirm that the key exists:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>pkcs11-list</code></strong>
+Enter PIN:
+object[0]: handle 2147483658 class 3 label[8] 'sample-ksk' id[0]
+object[1]: handle 2147483657 class 2 label[8] 'sample-ksk' id[0]
+</pre>
+<p>Before using this key to sign a zone, we must create a
+ pair of BIND 9 key files. The "dnssec-keyfromlabel" utility
+ does this. In this case, we will be using the HSM key
+ "sample-ksk" as the key-signing key for "example.net":</p>
+<pre class="screen">
+$ <strong class="userinput"><code>dnssec-keyfromlabel -l sample-ksk -f KSK example.net</code></strong>
+</pre>
+<p>The resulting K*.key and K*.private files can now be used
+ to sign the zone. Unlike normal K* files, which contain both
+ public and private key data, these files will contain only the
+ public key data, plus an identifier for the private key which
+ remains stored within the HSM. The HSM handles signing with the
+ private key.</p>
+<p>If you wish to generate a second key in the HSM for use
+ as a zone-signing key, follow the same procedure above, using a
+ different keylabel, a smaller key size, and omitting "-f KSK"
+ from the dnssec-keyfromlabel arguments:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>pkcs11-keygen -b 1024 -l sample-zsk</code></strong>
+$ <strong class="userinput"><code>dnssec-keyfromlabel -l sample-zsk example.net</code></strong>
+</pre>
+<p>Alternatively, you may prefer to generate a conventional
+ on-disk key, using dnssec-keygen:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>dnssec-keygen example.net</code></strong>
+</pre>
+<p>This provides less security than an HSM key, but since
+ HSMs can be slow or cumbersome to use for security reasons, it
+ may be more efficient to reserve HSM keys for use in the less
+ frequent key-signing operation. The zone-signing key can be
+ rolled more frequently, if you wish, to compensate for a
+ reduction in key security.</p>
+<p>Now you can sign the zone. (Note: If not using the -S
+ option to
+ <span><strong class="command">dnssec-signzone</strong></span>, it will be necessary to add
+ the contents of both
+ <code class="filename">K*.key</code> files to the zone master file before
+ signing it.)</p>
+<pre class="screen">
+$ <strong class="userinput"><code>dnssec-signzone -S example.net</code></strong>
+Enter PIN:
+Verifying the zone using the following algorithms:
+NSEC3RSASHA1.
+Zone signing complete:
+Algorithm: NSEC3RSASHA1: ZSKs: 1, KSKs: 1 active, 0 revoked, 0 stand-by
+example.net.signed
+</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2609709"></a>Specifying the engine on the command line</h3></div></div></div>
+<p>The OpenSSL engine can be specified in
+ <span><strong class="command">named</strong></span> and all of the BIND
+ <span><strong class="command">dnssec-*</strong></span> tools by using the "-E
+ &lt;engine&gt;" command line option. If BIND 9 is built with
+ the --with-pkcs11 option, this option defaults to "pkcs11".
+ Specifying the engine will generally not be necessary unless
+ for some reason you wish to use a different OpenSSL
+ engine.</p>
+<p>If you wish to disable use of the "pkcs11" engine &#8212;
+ for troubleshooting purposes, or because the HSM is unavailable
+ &#8212; set the engine to the empty string. For example:</p>
+<pre class="screen">
+$ <strong class="userinput"><code>dnssec-signzone -E '' -S example.net</code></strong>
+</pre>
+<p>This causes
+ <span><strong class="command">dnssec-signzone</strong></span> to run as if it were compiled
+ without the --with-pkcs11 option.</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2609755"></a>Running named with automatic zone re-signing</h3></div></div></div>
+<p>If you want
+ <span><strong class="command">named</strong></span> to dynamically re-sign zones using HSM
+ keys, and/or to to sign new records inserted via nsupdate, then
+ named must have access to the HSM PIN. This can be accomplished
+ by placing the PIN into the openssl.cnf file (in the above
+ examples,
+ <code class="filename">/opt/pkcs11/usr/ssl/openssl.cnf</code>).</p>
+<p>The location of the openssl.cnf file can be overridden by
+ setting the OPENSSL_CONF environment variable before running
+ named.</p>
+<p>Sample openssl.cnf:</p>
+<pre class="programlisting">
+ openssl_conf = openssl_def
+ [ openssl_def ]
+ engines = engine_section
+ [ engine_section ]
+ pkcs11 = pkcs11_section
+ [ pkcs11_section ]
+ PIN = <em class="replaceable"><code>&lt;PLACE PIN HERE&gt;</code></em>
+</pre>
+<p>This will also allow the dnssec-* tools to access the HSM
+ without PIN entry. (The pkcs11-* tools access the HSM directly,
+ not via OpenSSL, so a PIN will still be required to use
+ them.)</p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Warning</h3>
+<p>Placing the HSM's PIN in a text file in
+ this manner may reduce the security advantage of using an
+ HSM. Be sure this is what you want to do before configuring
+ OpenSSL in this way.</p>
+</div>
+</div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="id2572490"></a>IPv6 Support in <acronym class="acronym">BIND</acronym> 9</h2></div></div></div>
<p>
<acronym class="acronym">BIND</acronym> 9 fully supports all currently
defined forms of IPv6 name to address and address to name
@@ -1017,7 +1789,7 @@ options {
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2572172"></a>Address Lookups Using AAAA Records</h3></div></div></div>
+<a name="id2572757"></a>Address Lookups Using AAAA Records</h3></div></div></div>
<p>
The IPv6 AAAA record is a parallel to the IPv4 A record,
and, unlike the deprecated A6 record, specifies the entire
@@ -1036,7 +1808,7 @@ host 3600 IN AAAA 2001:db8::1
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2572194"></a>Address to Name Lookups Using Nibble Format</h3></div></div></div>
+<a name="id2572846"></a>Address to Name Lookups Using Nibble Format</h3></div></div></div>
<p>
When looking up an address in nibble format, the address
components are simply reversed, just as in IPv4, and
@@ -1048,7 +1820,8 @@ host 3600 IN AAAA 2001:db8::1
</p>
<pre class="programlisting">
$ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
-1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR host.example.com.
+1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 14400 IN PTR (
+ host.example.com. )
</pre>
</div>
</div>
diff --git a/doc/arm/Bv9ARM.ch05.html b/doc/arm/Bv9ARM.ch05.html
index b0339b433dbc..3b60755fe0f9 100644
--- a/doc/arm/Bv9ARM.ch05.html
+++ b/doc/arm/Bv9ARM.ch05.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch05.html,v 1.71.48.6 2010-01-24 01:55:26 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch05.html,v 1.93 2011-01-05 01:14:08 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,13 +45,13 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2572227">The Lightweight Resolver Library</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2572880">The Lightweight Resolver Library</a></span></dt>
<dt><span class="sect1"><a href="Bv9ARM.ch05.html#lwresd">Running a Resolver Daemon</a></span></dt>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2572227"></a>The Lightweight Resolver Library</h2></div></div></div>
+<a name="id2572880"></a>The Lightweight Resolver Library</h2></div></div></div>
<p>
Traditionally applications have been linked with a stub resolver
library that sends recursive DNS queries to a local caching name
diff --git a/doc/arm/Bv9ARM.ch06.html b/doc/arm/Bv9ARM.ch06.html
index d969e4b3c044..35243484d128 100644
--- a/doc/arm/Bv9ARM.ch06.html
+++ b/doc/arm/Bv9ARM.ch06.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch06.html,v 1.201.14.21 2010-08-20 02:05:39 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch06.html,v 1.275.8.1.2.1 2011-06-09 03:41:07 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -48,55 +48,58 @@
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#configuration_file_elements">Configuration File Elements</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#address_match_lists">Address Match Lists</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2573606">Comment Syntax</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574290">Comment Syntax</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#Configuration_File_Grammar">Configuration File Grammar</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574305"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574944"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#acl"><span><strong class="command">acl</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574494"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575133"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#controls_statement_definition_and_usage"><span><strong class="command">controls</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574923"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574940"><span><strong class="command">include</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575425"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575442"><span><strong class="command">include</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574964"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574987"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575078"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575204"><span><strong class="command">logging</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575465"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575489"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575648"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575842"><span><strong class="command">logging</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577401"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577475"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577539"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577582"><span><strong class="command">masters</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577841"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577982"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2578046"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2578090"><span><strong class="command">masters</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577597"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2578105"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#options"><span><strong class="command">options</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_grammar"><span><strong class="command">server</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_definition_and_usage"><span><strong class="command">server</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#statschannels"><span><strong class="command">statistics-channels</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2586907"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589239"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587062"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587113"><span><strong class="command">trusted-keys</strong></span> Statement Definition
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#trusted-keys"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589379"><span><strong class="command">trusted-keys</strong></span> Statement Definition
+ and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589494"><span><strong class="command">managed-keys</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#managed-keys"><span><strong class="command">managed-keys</strong></span> Statement Definition
and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#view_statement_grammar"><span><strong class="command">view</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587195"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589851"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zone_statement_grammar"><span><strong class="command">zone</strong></span>
Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2588600"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2591396"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2591216">Zone File</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2594660">Zone File</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#types_of_resource_records_and_when_to_use_them">Types of Resource Records and When to Use Them</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593378">Discussion of MX Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2596822">Discussion of MX Records</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#Setting_TTLs">Setting TTLs</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593993">Inverse Mapping in IPv4</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594188">Other Zone File Directives</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594461"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2597574">Inverse Mapping in IPv4</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2597701">Other Zone File Directives</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2597974"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zonefile_format">Additional File Formats</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#statistics">BIND9 Statistics</a></span></dt>
@@ -193,6 +196,19 @@
<tr>
<td>
<p>
+ <code class="varname">namelist</code>
+ </p>
+ </td>
+<td>
+ <p>
+ A list of one or more <code class="varname">domain_name</code>
+ elements.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
<code class="varname">dotted_decimal</code>
</p>
</td>
@@ -461,7 +477,7 @@
<a name="address_match_lists"></a>Address Match Lists</h3></div></div></div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573372"></a>Syntax</h4></div></div></div>
+<a name="id2574056"></a>Syntax</h4></div></div></div>
<pre class="programlisting"><code class="varname">address_match_list</code> = address_match_list_element ;
[<span class="optional"> address_match_list_element; ... </span>]
<code class="varname">address_match_list_element</code> = [<span class="optional"> ! </span>] (ip_address [<span class="optional">/length</span>] |
@@ -470,7 +486,7 @@
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573468"></a>Definition and Usage</h4></div></div></div>
+<a name="id2574084"></a>Definition and Usage</h4></div></div></div>
<p>
Address match lists are primarily used to determine access
control for various server operations. They are also used in
@@ -554,7 +570,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2573606"></a>Comment Syntax</h3></div></div></div>
+<a name="id2574290"></a>Comment Syntax</h3></div></div></div>
<p>
The <acronym class="acronym">BIND</acronym> 9 comment syntax allows for
comments to appear
@@ -564,7 +580,7 @@
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573621"></a>Syntax</h4></div></div></div>
+<a name="id2574305"></a>Syntax</h4></div></div></div>
<p>
</p>
<pre class="programlisting">/* This is a <acronym class="acronym">BIND</acronym> comment as in C */</pre>
@@ -573,13 +589,14 @@
<pre class="programlisting">// This is a <acronym class="acronym">BIND</acronym> comment as in C++</pre>
<p>
</p>
-<pre class="programlisting"># This is a <acronym class="acronym">BIND</acronym> comment as in common UNIX shells and perl</pre>
+<pre class="programlisting"># This is a <acronym class="acronym">BIND</acronym> comment as in common UNIX shells
+# and perl</pre>
<p>
</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2573651"></a>Definition and Usage</h4></div></div></div>
+<a name="id2574334"></a>Definition and Usage</h4></div></div></div>
<p>
Comments may appear anywhere that whitespace may appear in
a <acronym class="acronym">BIND</acronym> configuration file.
@@ -792,6 +809,17 @@
</tr>
<tr>
<td>
+ <p><span><strong class="command">managed-keys</strong></span></p>
+ </td>
+<td>
+ <p>
+ lists DNSSEC keys to be kept up to date
+ using RFC 5011 trust anchor maintenance.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
<p><span><strong class="command">view</strong></span></p>
</td>
<td>
@@ -820,7 +848,7 @@
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574305"></a><span><strong class="command">acl</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2574944"></a><span><strong class="command">acl</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">acl</strong></span> acl-name {
address_match_list
};
@@ -902,12 +930,14 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574494"></a><span><strong class="command">controls</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2575133"></a><span><strong class="command">controls</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">controls</strong></span> {
- [ inet ( ip_addr | * ) [ port ip_port ] allow { <em class="replaceable"><code> address_match_list </code></em> }
+ [ inet ( ip_addr | * ) [ port ip_port ]
+ allow { <em class="replaceable"><code> address_match_list </code></em> }
keys { <em class="replaceable"><code>key_list</code></em> }; ]
[ inet ...; ]
- [ unix <em class="replaceable"><code>path</code></em> perm <em class="replaceable"><code>number</code></em> owner <em class="replaceable"><code>number</code></em> group <em class="replaceable"><code>number</code></em> keys { <em class="replaceable"><code>key_list</code></em> }; ]
+ [ unix <em class="replaceable"><code>path</code></em> perm <em class="replaceable"><code>number</code></em> owner <em class="replaceable"><code>number</code></em> group <em class="replaceable"><code>number</code></em>
+ keys { <em class="replaceable"><code>key_list</code></em> }; ]
[ unix ...; ]
};
</pre>
@@ -1024,12 +1054,12 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574923"></a><span><strong class="command">include</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2575425"></a><span><strong class="command">include</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">include</strong></span> <em class="replaceable"><code>filename</code></em>;</pre>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574940"></a><span><strong class="command">include</strong></span> Statement Definition and
+<a name="id2575442"></a><span><strong class="command">include</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p>
The <span><strong class="command">include</strong></span> statement inserts the
@@ -1044,7 +1074,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574964"></a><span><strong class="command">key</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2575465"></a><span><strong class="command">key</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">key</strong></span> <em class="replaceable"><code>key_id</code></em> {
algorithm <em class="replaceable"><code>string</code></em>;
secret <em class="replaceable"><code>string</code></em>;
@@ -1053,7 +1083,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2574987"></a><span><strong class="command">key</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2575489"></a><span><strong class="command">key</strong></span> Statement Definition and Usage</h3></div></div></div>
<p>
The <span><strong class="command">key</strong></span> statement defines a shared
secret key for use with TSIG (see <a href="Bv9ARM.ch04.html#tsig" title="TSIG">the section called &#8220;TSIG&#8221;</a>)
@@ -1100,7 +1130,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575078"></a><span><strong class="command">logging</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2575648"></a><span><strong class="command">logging</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">logging</strong></span> {
[ <span><strong class="command">channel</strong></span> <em class="replaceable"><code>channel_name</code></em> {
( <span><strong class="command">file</strong></span> <em class="replaceable"><code>path_name</code></em>
@@ -1124,7 +1154,7 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2575204"></a><span><strong class="command">logging</strong></span> Statement Definition and
+<a name="id2575842"></a><span><strong class="command">logging</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p>
The <span><strong class="command">logging</strong></span> statement configures a
@@ -1158,7 +1188,7 @@
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2575256"></a>The <span><strong class="command">channel</strong></span> Phrase</h4></div></div></div>
+<a name="id2575894"></a>The <span><strong class="command">channel</strong></span> Phrase</h4></div></div></div>
<p>
All log output goes to one or more <span class="emphasis"><em>channels</em></span>;
you can make as many of them as you want.
@@ -1342,32 +1372,30 @@ notrace</strong></span>. All debugging messages in the server have a debug
used is described in <a href="Bv9ARM.ch06.html#the_category_phrase" title="The category Phrase">the section called &#8220;The <span><strong class="command">category</strong></span> Phrase&#8221;</a>.
</p>
<pre class="programlisting">channel default_syslog {
- syslog daemon; // send to syslog's daemon
- // facility
- severity info; // only send priority info
- // and higher
-};
+ // send to syslog's daemon facility
+ syslog daemon;
+ // only send priority info and higher
+ severity info;
channel default_debug {
- file "named.run"; // write to named.run in
- // the working directory
- // Note: stderr is used instead
- // of "named.run"
- // if the server is started
- // with the '-f' option.
- severity dynamic; // log at the server's
- // current debug level
+ // write to named.run in the working directory
+ // Note: stderr is used instead of "named.run" if
+ // the server is started with the '-f' option.
+ file "named.run";
+ // log at the server's current debug level
+ severity dynamic;
};
channel default_stderr {
- stderr; // writes to stderr
- severity info; // only send priority info
- // and higher
+ // writes to stderr
+ stderr;
+ // only send priority info and higher
+ severity info;
};
channel null {
- null; // toss anything sent to
- // this channel
+ // toss anything sent to this channel
+ null;
};
</pre>
<p>
@@ -1610,12 +1638,14 @@ category notify { null; };
<p>
The query log entry reports the client's IP
address and port number, and the query name,
- class and type. It also reports whether the
+ class and type. Next it reports whether the
Recursion Desired flag was set (+ if set, -
if not set), if the query was signed (S),
- EDNS was in use (E), if DO (DNSSEC Ok) was
- set (D), or if CD (Checking Disabled) was set
- (C).
+ EDNS was in use (E), if TCP was used (T), if
+ DO (DNSSEC Ok) was set (D), or if CD (Checking
+ Disabled) was set (C). After this the
+ destination address the query was sent to is
+ reported.
</p>
<p>
@@ -1723,7 +1753,7 @@ category notify { null; };
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2576820"></a>The <span><strong class="command">query-errors</strong></span> Category</h4></div></div></div>
+<a name="id2577253"></a>The <span><strong class="command">query-errors</strong></span> Category</h4></div></div></div>
<p>
The <span><strong class="command">query-errors</strong></span> category is
specifically intended for debugging purposes: To identify
@@ -1754,7 +1784,15 @@ category notify { null; };
The log message will look like as follows:
</p>
<p>
- <code class="computeroutput">fetch completed at resolver.c:2970 for www.example.com/A in 30.000183: timed out/success [domain:example.com,referral:2,restart:7,qrysent:8,timeout:5,lame:0,neterr:0,badresp:1,adberr:0,findfail:0,valfail:0]</code>
+
+ </p>
+<pre class="programlisting">
+fetch completed at resolver.c:2970 for www.example.com/A
+in 30.000183: timed out/success [domain:example.com,
+referral:2,restart:7,qrysent:8,timeout:5,lame:0,neterr:0,
+badresp:1,adberr:0,findfail:0,valfail:0]
+ </pre>
+<p>
</p>
<p>
The first part before the colon shows that a recursive
@@ -1943,13 +1981,14 @@ category notify { null; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577401"></a><span><strong class="command">lwres</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2577841"></a><span><strong class="command">lwres</strong></span> Statement Grammar</h3></div></div></div>
<p>
This is the grammar of the <span><strong class="command">lwres</strong></span>
statement in the <code class="filename">named.conf</code> file:
</p>
<pre class="programlisting"><span><strong class="command">lwres</strong></span> {
- [<span class="optional"> listen-on { <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; ... </span>] }; </span>]
+ [<span class="optional"> listen-on { <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ;
+ [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; ... </span>] }; </span>]
[<span class="optional"> view <em class="replaceable"><code>view_name</code></em>; </span>]
[<span class="optional"> search { <em class="replaceable"><code>domain_name</code></em> ; [<span class="optional"> <em class="replaceable"><code>domain_name</code></em> ; ... </span>] }; </span>]
[<span class="optional"> ndots <em class="replaceable"><code>number</code></em>; </span>]
@@ -1958,7 +1997,7 @@ category notify { null; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577475"></a><span><strong class="command">lwres</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2577982"></a><span><strong class="command">lwres</strong></span> Statement Definition and Usage</h3></div></div></div>
<p>
The <span><strong class="command">lwres</strong></span> statement configures the
name
@@ -2009,14 +2048,15 @@ category notify { null; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577539"></a><span><strong class="command">masters</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2578046"></a><span><strong class="command">masters</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting">
-<span><strong class="command">masters</strong></span> <em class="replaceable"><code>name</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] { ( <em class="replaceable"><code>masters_list</code></em> | <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] [<span class="optional">key <em class="replaceable"><code>key</code></em></span>] ) ; [<span class="optional">...</span>] };
+<span><strong class="command">masters</strong></span> <em class="replaceable"><code>name</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] { ( <em class="replaceable"><code>masters_list</code></em> |
+ <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] [<span class="optional">key <em class="replaceable"><code>key</code></em></span>] ) ; [<span class="optional">...</span>] };
</pre>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577582"></a><span><strong class="command">masters</strong></span> Statement Definition and
+<a name="id2578090"></a><span><strong class="command">masters</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p><span><strong class="command">masters</strong></span>
lists allow for a common set of masters to be easily used by
@@ -2025,23 +2065,27 @@ category notify { null; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2577597"></a><span><strong class="command">options</strong></span> Statement Grammar</h3></div></div></div>
+<a name="id2578105"></a><span><strong class="command">options</strong></span> Statement Grammar</h3></div></div></div>
<p>
This is the grammar of the <span><strong class="command">options</strong></span>
statement in the <code class="filename">named.conf</code> file:
</p>
<pre class="programlisting"><span><strong class="command">options</strong></span> {
+ [<span class="optional"> attach-cache <em class="replaceable"><code>cache_name</code></em>; </span>]
[<span class="optional"> version <em class="replaceable"><code>version_string</code></em>; </span>]
[<span class="optional"> hostname <em class="replaceable"><code>hostname_string</code></em>; </span>]
[<span class="optional"> server-id <em class="replaceable"><code>server_id_string</code></em>; </span>]
[<span class="optional"> directory <em class="replaceable"><code>path_name</code></em>; </span>]
[<span class="optional"> key-directory <em class="replaceable"><code>path_name</code></em>; </span>]
+ [<span class="optional"> managed-keys-directory <em class="replaceable"><code>path_name</code></em>; </span>]
[<span class="optional"> named-xfer <em class="replaceable"><code>path_name</code></em>; </span>]
+ [<span class="optional"> tkey-gssapi-keytab <em class="replaceable"><code>path_name</code></em>; </span>]
[<span class="optional"> tkey-gssapi-credential <em class="replaceable"><code>principal</code></em>; </span>]
[<span class="optional"> tkey-domain <em class="replaceable"><code>domainname</code></em>; </span>]
[<span class="optional"> tkey-dhkey <em class="replaceable"><code>key_name</code></em> <em class="replaceable"><code>key_tag</code></em>; </span>]
[<span class="optional"> cache-file <em class="replaceable"><code>path_name</code></em>; </span>]
[<span class="optional"> dump-file <em class="replaceable"><code>path_name</code></em>; </span>]
+ [<span class="optional"> bindkeys-file <em class="replaceable"><code>path_name</code></em>; </span>]
[<span class="optional"> memstatistics <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> memstatistics-file <em class="replaceable"><code>path_name</code></em>; </span>]
[<span class="optional"> pid-file <em class="replaceable"><code>path_name</code></em>; </span>]
@@ -2066,8 +2110,9 @@ category notify { null; };
[<span class="optional"> maintain-ixfr-base <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> ixfr-from-differences (<em class="replaceable"><code>yes_or_no</code></em> | <code class="constant">master</code> | <code class="constant">slave</code>); </span>]
[<span class="optional"> dnssec-enable <em class="replaceable"><code>yes_or_no</code></em>; </span>]
- [<span class="optional"> dnssec-validation <em class="replaceable"><code>yes_or_no</code></em>; </span>]
- [<span class="optional"> dnssec-lookaside <em class="replaceable"><code>domain</code></em> trust-anchor <em class="replaceable"><code>domain</code></em>; </span>]
+ [<span class="optional"> dnssec-validation (<em class="replaceable"><code>yes_or_no</code></em> | <code class="constant">auto</code>); </span>]
+ [<span class="optional"> dnssec-lookaside ( <em class="replaceable"><code>auto</code></em> |
+ <em class="replaceable"><code>domain</code></em> trust-anchor <em class="replaceable"><code>domain</code></em> ); </span>]
[<span class="optional"> dnssec-must-be-secure <em class="replaceable"><code>domain yes_or_no</code></em>; </span>]
[<span class="optional"> dnssec-accept-expired <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> forward ( <em class="replaceable"><code>only</code></em> | <em class="replaceable"><code>first</code></em> ); </span>]
@@ -2078,12 +2123,14 @@ category notify { null; };
... }; </span>]
[<span class="optional"> check-names ( <em class="replaceable"><code>master</code></em> | <em class="replaceable"><code>slave</code></em> | <em class="replaceable"><code>response</code></em> )
( <em class="replaceable"><code>warn</code></em> | <em class="replaceable"><code>fail</code></em> | <em class="replaceable"><code>ignore</code></em> ); </span>]
+ [<span class="optional"> check-dup-records ( <em class="replaceable"><code>warn</code></em> | <em class="replaceable"><code>fail</code></em> | <em class="replaceable"><code>ignore</code></em> ); </span>]
[<span class="optional"> check-mx ( <em class="replaceable"><code>warn</code></em> | <em class="replaceable"><code>fail</code></em> | <em class="replaceable"><code>ignore</code></em> ); </span>]
[<span class="optional"> check-wildcard <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> check-integrity <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> check-mx-cname ( <em class="replaceable"><code>warn</code></em> | <em class="replaceable"><code>fail</code></em> | <em class="replaceable"><code>ignore</code></em> ); </span>]
[<span class="optional"> check-srv-cname ( <em class="replaceable"><code>warn</code></em> | <em class="replaceable"><code>fail</code></em> | <em class="replaceable"><code>ignore</code></em> ); </span>]
[<span class="optional"> check-sibling <em class="replaceable"><code>yes_or_no</code></em>; </span>]
+ [<span class="optional"> allow-new-zones { <em class="replaceable"><code>yes_or_no</code></em> }; </span>]
[<span class="optional"> allow-notify { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
[<span class="optional"> allow-query { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
[<span class="optional"> allow-query-on { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
@@ -2095,6 +2142,8 @@ category notify { null; };
[<span class="optional"> allow-update { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
[<span class="optional"> allow-update-forwarding { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
[<span class="optional"> update-check-ksk <em class="replaceable"><code>yes_or_no</code></em>; </span>]
+ [<span class="optional"> dnssec-dnskey-kskonly <em class="replaceable"><code>yes_or_no</code></em>; </span>]
+ [<span class="optional"> dnssec-secure-to-insecure <em class="replaceable"><code>yes_or_no</code></em> ;</span>]
[<span class="optional"> try-tcp-refresh <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> allow-v6-synthesis { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
[<span class="optional"> blackhole { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
@@ -2132,13 +2181,15 @@ category notify { null; };
[<span class="optional"> transfer-source (<em class="replaceable"><code>ip4_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> alt-transfer-source (<em class="replaceable"><code>ip4_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
- [<span class="optional"> alt-transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
+ [<span class="optional"> alt-transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>)
+ [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> use-alt-transfer-source <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> notify-delay <em class="replaceable"><code>seconds</code></em> ; </span>]
[<span class="optional"> notify-source (<em class="replaceable"><code>ip4_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> notify-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> notify-to-soa <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
- [<span class="optional"> also-notify { <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; ... </span>] }; </span>]
+ [<span class="optional"> also-notify { <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ;
+ [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; ... </span>] }; </span>]
[<span class="optional"> max-ixfr-log-size <em class="replaceable"><code>number</code></em>; </span>]
[<span class="optional"> max-journal-size <em class="replaceable"><code>size_spec</code></em>; </span>]
[<span class="optional"> coresize <em class="replaceable"><code>size_spec</code></em> ; </span>]
@@ -2174,12 +2225,25 @@ category notify { null; };
[<span class="optional"> random-device <em class="replaceable"><code>path_name</code></em> ; </span>]
[<span class="optional"> max-cache-size <em class="replaceable"><code>size_spec</code></em> ; </span>]
[<span class="optional"> match-mapped-addresses <em class="replaceable"><code>yes_or_no</code></em>; </span>]
+ [<span class="optional"> filter-aaaa-on-v4 ( <em class="replaceable"><code>yes_or_no</code></em> | <em class="replaceable"><code>break-dnssec</code></em> ); </span>]
+ [<span class="optional"> filter-aaaa { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
+ [<span class="optional"> dns64 <em class="replaceable"><code>IPv6-prefix</code></em> {
+ [<span class="optional"> clients { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
+ [<span class="optional"> mapped { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
+ [<span class="optional"> exclude { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
+ [<span class="optional"> suffix IPv6-address; </span>]
+ [<span class="optional"> recursive-only <em class="replaceable"><code>yes_or_no</code></em>; </span>]
+ [<span class="optional"> break-dnssec <em class="replaceable"><code>yes_or_no</code></em>; </span>]
+ }; </span>];
+ [<span class="optional"> dns64-server <em class="replaceable"><code>name</code></em> </span>]
+ [<span class="optional"> dns64-contact <em class="replaceable"><code>name</code></em> </span>]
[<span class="optional"> preferred-glue ( <em class="replaceable"><code>A</code></em> | <em class="replaceable"><code>AAAA</code></em> | <em class="replaceable"><code>NONE</code></em> ); </span>]
[<span class="optional"> edns-udp-size <em class="replaceable"><code>number</code></em>; </span>]
[<span class="optional"> max-udp-size <em class="replaceable"><code>number</code></em>; </span>]
[<span class="optional"> root-delegation-only [<span class="optional"> exclude { <em class="replaceable"><code>namelist</code></em> } </span>] ; </span>]
[<span class="optional"> querylog <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
- [<span class="optional"> disable-algorithms <em class="replaceable"><code>domain</code></em> { <em class="replaceable"><code>algorithm</code></em>; [<span class="optional"> <em class="replaceable"><code>algorithm</code></em>; </span>] }; </span>]
+ [<span class="optional"> disable-algorithms <em class="replaceable"><code>domain</code></em> { <em class="replaceable"><code>algorithm</code></em>;
+ [<span class="optional"> <em class="replaceable"><code>algorithm</code></em>; </span>] }; </span>]
[<span class="optional"> acache-enable <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
[<span class="optional"> acache-cleaning-interval <em class="replaceable"><code>number</code></em>; </span>]
[<span class="optional"> max-acache-size <em class="replaceable"><code>size_spec</code></em> ; </span>]
@@ -2192,6 +2256,10 @@ category notify { null; };
[<span class="optional"> disable-empty-zone <em class="replaceable"><code>zone_name</code></em> ; </span>]
[<span class="optional"> zero-no-soa-ttl <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
[<span class="optional"> zero-no-soa-ttl-cache <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
+ [<span class="optional"> resolver-query-timeout <em class="replaceable"><code>number</code></em> ; </span>]
+ [<span class="optional"> deny-answer-addresses { <em class="replaceable"><code>address_match_list</code></em> } [<span class="optional"> except-from { <em class="replaceable"><code>namelist</code></em> } </span>];</span>]
+ [<span class="optional"> deny-answer-aliases { <em class="replaceable"><code>namelist</code></em> } [<span class="optional"> except-from { <em class="replaceable"><code>namelist</code></em> } </span>];</span>]
+ [<span class="optional"> response-policy { <em class="replaceable"><code>zone_name</code></em> [<span class="optional"> policy <em class="replaceable"><code>given</code></em> | <em class="replaceable"><code>no-op</code></em> | <em class="replaceable"><code>nxdomain</code></em> | <em class="replaceable"><code>nodata</code></em> | <em class="replaceable"><code>cname domain</code></em> </span>] ; } ; </span>]
};
</pre>
</div>
@@ -2209,6 +2277,91 @@ category notify { null; };
be used.
</p>
<div class="variablelist"><dl>
+<dt><span class="term"><span><strong class="command">attach-cache</strong></span></span></dt>
+<dd>
+<p>
+ Allows multiple views to share a single cache
+ database.
+ Each view has its own cache database by default, but
+ if multiple views have the same operational policy
+ for name resolution and caching, those views can
+ share a single cache to save memory and possibly
+ improve resolution efficiency by using this option.
+ </p>
+<p>
+ The <span><strong class="command">attach-cache</strong></span> option
+ may also be specified in <span><strong class="command">view</strong></span>
+ statements, in which case it overrides the
+ global <span><strong class="command">attach-cache</strong></span> option.
+ </p>
+<p>
+ The <em class="replaceable"><code>cache_name</code></em> specifies
+ the cache to be shared.
+ When the <span><strong class="command">named</strong></span> server configures
+ views which are supposed to share a cache, it
+ creates a cache with the specified name for the
+ first view of these sharing views.
+ The rest of the views will simply refer to the
+ already created cache.
+ </p>
+<p>
+ One common configuration to share a cache would be to
+ allow all views to share a single cache.
+ This can be done by specifying
+ the <span><strong class="command">attach-cache</strong></span> as a global
+ option with an arbitrary name.
+ </p>
+<p>
+ Another possible operation is to allow a subset of
+ all views to share a cache while the others to
+ retain their own caches.
+ For example, if there are three views A, B, and C,
+ and only A and B should share a cache, specify the
+ <span><strong class="command">attach-cache</strong></span> option as a view A (or
+ B)'s option, referring to the other view name:
+ </p>
+<pre class="programlisting">
+ view "A" {
+ // this view has its own cache
+ ...
+ };
+ view "B" {
+ // this view refers to A's cache
+ attach-cache "A";
+ };
+ view "C" {
+ // this view has its own cache
+ ...
+ };
+</pre>
+<p>
+ Views that share a cache must have the same policy
+ on configurable parameters that may affect caching.
+ The current implementation requires the following
+ configurable options be consistent among these
+ views:
+ <span><strong class="command">check-names</strong></span>,
+ <span><strong class="command">cleaning-interval</strong></span>,
+ <span><strong class="command">dnssec-accept-expired</strong></span>,
+ <span><strong class="command">dnssec-validation</strong></span>,
+ <span><strong class="command">max-cache-ttl</strong></span>,
+ <span><strong class="command">max-ncache-ttl</strong></span>,
+ <span><strong class="command">max-cache-size</strong></span>, and
+ <span><strong class="command">zero-no-soa-ttl</strong></span>.
+ </p>
+<p>
+ Note that there may be other parameters that may
+ cause confusion if they are inconsistent for
+ different views that share a single cache.
+ For example, if these views define different sets of
+ forwarders that can return different answers for the
+ same question, sharing the answer does not make
+ sense or could even be harmful.
+ It is administrator's responsibility to ensure
+ configuration differences in different views do
+ not cause disruption with a shared cache.
+ </p>
+</dd>
<dt><span class="term"><span><strong class="command">directory</strong></span></span></dt>
<dd><p>
The working directory of the server.
@@ -2229,10 +2382,19 @@ category notify { null; };
When performing dynamic update of secure zones, the
directory where the public and private DNSSEC key files
should be found, if different than the current working
- directory. The directory specified must be an absolute
- path. (Note that this option has no effect on the paths
- for files containing non-DNSSEC keys such as the
- <code class="filename">rndc.key</code>.
+ directory. (Note that this option has no effect on the
+ paths for files containing non-DNSSEC keys such as
+ <code class="filename">bind.keys</code>,
+ <code class="filename">rndc.key</code> or
+ <code class="filename">session.key</code>.)
+ </p></dd>
+<dt><span class="term"><span><strong class="command">managed-keys-directory</strong></span></span></dt>
+<dd><p>
+ The directory used to hold the files used to track managed keys.
+ By default it is the working directory. It there are no
+ views then the file <code class="filename">managed-keys.bind</code>
+ otherwise a SHA256 hash of the view name is used with
+ <code class="filename">.mkeys</code> extension added.
</p></dd>
<dt><span class="term"><span><strong class="command">named-xfer</strong></span></span></dt>
<dd><p>
@@ -2243,18 +2405,27 @@ category notify { null; };
<span><strong class="command">named-xfer</strong></span> program is needed;
its functionality is built into the name server.
</p></dd>
+<dt><span class="term"><span><strong class="command">tkey-gssapi-keytab</strong></span></span></dt>
+<dd><p>
+ The KRB5 keytab file to use for GSS-TSIG updates. If
+ this option is set and tkey-gssapi-credential is not
+ set, then updates will be allowed with any key
+ matching a principal in the specified keytab.
+ </p></dd>
<dt><span class="term"><span><strong class="command">tkey-gssapi-credential</strong></span></span></dt>
<dd><p>
The security credential with which the server should
authenticate keys requested by the GSS-TSIG protocol.
Currently only Kerberos 5 authentication is available
- and the credential is a Kerberos principal which
- the server can acquire through the default system
- key file, normally <code class="filename">/etc/krb5.keytab</code>.
- Normally this principal is of the form
- "<strong class="userinput"><code>DNS/</code></strong><code class="varname">server.domain</code>".
- To use GSS-TSIG, <span><strong class="command">tkey-domain</strong></span>
- must also be set.
+ and the credential is a Kerberos principal which the
+ server can acquire through the default system key
+ file, normally <code class="filename">/etc/krb5.keytab</code>.
+ The location keytab file can be overridden using the
+ tkey-gssapi-keytab option. Normally this principal is
+ of the form "<strong class="userinput"><code>DNS/</code></strong><code class="varname">server.domain</code>".
+ To use GSS-TSIG, <span><strong class="command">tkey-domain</strong></span> must
+ also be set if a specific keytab is not set with
+ tkey-gssapi-keytab.
</p></dd>
<dt><span class="term"><span><strong class="command">tkey-domain</strong></span></span></dt>
<dd><p>
@@ -2271,7 +2442,8 @@ category notify { null; };
should be the server's domain name, or an otherwise
non-existent subdomain like
"_tkey.<code class="varname">domainname</code>". If you are
- using GSS-TSIG, this variable must be defined.
+ using GSS-TSIG, this variable must be defined, unless
+ you specify a specific keytab using tkey-gssapi-keytab.
</p></dd>
<dt><span class="term"><span><strong class="command">tkey-dhkey</strong></span></span></dt>
<dd><p>
@@ -2331,6 +2503,54 @@ category notify { null; };
described
in <a href="Bv9ARM.ch06.html#statsfile" title="The Statistics File">the section called &#8220;The Statistics File&#8221;</a>.
</p></dd>
+<dt><span class="term"><span><strong class="command">bindkeys-file</strong></span></span></dt>
+<dd><p>
+ The pathname of a file to override the built-in trusted
+ keys provided by <span><strong class="command">named</strong></span>.
+ See the discussion of <span><strong class="command">dnssec-lookaside</strong></span>
+ and <span><strong class="command">dnssec-validation</strong></span> for details.
+ If not specified, the default is
+ <code class="filename">/etc/bind.keys</code>.
+ </p></dd>
+<dt><span class="term"><span><strong class="command">secroots-file</strong></span></span></dt>
+<dd><p>
+ The pathname of the file the server dumps
+ security roots to when instructed to do so with
+ <span><strong class="command">rndc secroots</strong></span>.
+ If not specified, the default is <code class="filename">named.secroots</code>.
+ </p></dd>
+<dt><span class="term"><span><strong class="command">session-keyfile</strong></span></span></dt>
+<dd><p>
+ The pathname of the file into which to write a TSIG
+ session key generated by <span><strong class="command">named</strong></span> for use by
+ <span><strong class="command">nsupdate -l</strong></span>. If not specified, the
+ default is <code class="filename">/var/run/named/session.key</code>.
+ (See <a href="Bv9ARM.ch06.html#dynamic_update_policies" title="Dynamic Update Policies">the section called &#8220;Dynamic Update Policies&#8221;</a>, and in
+ particular the discussion of the
+ <span><strong class="command">update-policy</strong></span> statement's
+ <strong class="userinput"><code>local</code></strong> option for more
+ information about this feature.)
+ </p></dd>
+<dt><span class="term"><span><strong class="command">session-keyname</strong></span></span></dt>
+<dd><p>
+ The key name to use for the TSIG session key.
+ If not specified, the default is "local-ddns".
+ </p></dd>
+<dt><span class="term"><span><strong class="command">session-keyalg</strong></span></span></dt>
+<dd><p>
+ The algorithm to use for the TSIG session key.
+ Valid values are hmac-sha1, hmac-sha224, hmac-sha256,
+ hmac-sha384, hmac-sha512 and hmac-md5. If not
+ specified, the default is hmac-sha256.
+ </p></dd>
+<dt><span class="term"><span><strong class="command">session-keyfile</strong></span></span></dt>
+<dd><p>
+ The pathname of the file into which to write a session TSIG
+ key for use by <span><strong class="command">nsupdate -l</strong></span>. (See the
+ discussion of the <span><strong class="command">update-policy</strong></span>
+ statement's <strong class="userinput"><code>local</code></strong> option for more
+ details on this feature.)
+ </p></dd>
<dt><span class="term"><span><strong class="command">port</strong></span></span></dt>
<dd><p>
The UDP/TCP port number the server uses for
@@ -2379,14 +2599,14 @@ category notify { null; };
<p>
DS queries are expected to be made to and be answered by
delegation only zones. Such queries and responses are
- treated as a exception to delegation-only processing
+ treated as an exception to delegation-only processing
and are not converted to NXDOMAIN responses provided
a CNAME is not discovered at the query name.
</p>
<p>
If a delegation only zone server also serves a child
zone it is not always possible to determine whether
- a answer comes from the delegation only zone or the
+ an answer comes from the delegation only zone or the
child zone. SOA NS and DNSKEY records are apex
only records and a matching response that contains
these records or DS is treated as coming from a
@@ -2423,42 +2643,138 @@ options {
Only the most specific will be applied.
</p></dd>
<dt><span class="term"><span><strong class="command">dnssec-lookaside</strong></span></span></dt>
-<dd><p>
- When set, <span><strong class="command">dnssec-lookaside</strong></span>
- provides the
- validator with an alternate method to validate DNSKEY records
- at the
- top of a zone. When a DNSKEY is at or below a domain
- specified by the
- deepest <span><strong class="command">dnssec-lookaside</strong></span>, and
- the normal DNSSEC validation
- has left the key untrusted, the trust-anchor will be append to
- the key
- name and a DLV record will be looked up to see if it can
- validate the
- key. If the DLV record validates a DNSKEY (similarly to the
- way a DS
+<dd>
+<p>
+ When set, <span><strong class="command">dnssec-lookaside</strong></span> provides the
+ validator with an alternate method to validate DNSKEY
+ records at the top of a zone. When a DNSKEY is at or
+ below a domain specified by the deepest
+ <span><strong class="command">dnssec-lookaside</strong></span>, and the normal DNSSEC
+ validation has left the key untrusted, the trust-anchor
+ will be appended to the key name and a DLV record will be
+ looked up to see if it can validate the key. If the DLV
+ record validates a DNSKEY (similarly to the way a DS
record does) the DNSKEY RRset is deemed to be trusted.
- </p></dd>
+ </p>
+<p>
+ If <span><strong class="command">dnssec-lookaside</strong></span> is set to
+ <strong class="userinput"><code>auto</code></strong>, then built-in default
+ values for the DLV domain and trust anchor will be
+ used, along with a built-in key for validation.
+ </p>
+<p>
+ The default DLV key is stored in the file
+ <code class="filename">bind.keys</code>;
+ <span><strong class="command">named</strong></span> will load that key at
+ startup if <span><strong class="command">dnssec-lookaside</strong></span> is set to
+ <code class="constant">auto</code>. A copy of the file is
+ installed along with <acronym class="acronym">BIND</acronym> 9, and is
+ current as of the release date. If the DLV key expires, a
+ new copy of <code class="filename">bind.keys</code> can be downloaded
+ from <a href="" target="_top">https://www.isc.org/solutions/dlv</a>.
+ </p>
+<p>
+ (To prevent problems if <code class="filename">bind.keys</code> is
+ not found, the current key is also compiled in to
+ <span><strong class="command">named</strong></span>. Relying on this is not
+ recommended, however, as it requires <span><strong class="command">named</strong></span>
+ to be recompiled with a new key when the DLV key expires.)
+ </p>
+<p>
+ NOTE: <span><strong class="command">named</strong></span> only loads certain specific
+ keys from <code class="filename">bind.keys</code>: those for the
+ DLV zone and for the DNS root zone. The file cannot be
+ used to store keys for other zones.
+ </p>
+</dd>
<dt><span class="term"><span><strong class="command">dnssec-must-be-secure</strong></span></span></dt>
<dd><p>
- Specify hierarchies which must be or may not be secure (signed and
- validated).
- If <strong class="userinput"><code>yes</code></strong>, then <span><strong class="command">named</strong></span> will only accept
- answers if they
- are secure.
- If <strong class="userinput"><code>no</code></strong>, then normal DNSSEC validation
- applies
- allowing for insecure answers to be accepted.
- The specified domain must be under a <span><strong class="command">trusted-key</strong></span> or
- <span><strong class="command">dnssec-lookaside</strong></span> must be
- active.
+ Specify hierarchies which must be or may not be secure
+ (signed and validated). If <strong class="userinput"><code>yes</code></strong>,
+ then <span><strong class="command">named</strong></span> will only accept answers if
+ they are secure. If <strong class="userinput"><code>no</code></strong>, then normal
+ DNSSEC validation applies allowing for insecure answers to
+ be accepted. The specified domain must be under a
+ <span><strong class="command">trusted-keys</strong></span> or
+ <span><strong class="command">managed-keys</strong></span> statement, or
+ <span><strong class="command">dnssec-lookaside</strong></span> must be active.
</p></dd>
+<dt><span class="term"><span><strong class="command">dns64</strong></span></span></dt>
+<dd>
+<p>
+ This directive instructs <span><strong class="command">named</strong></span> to
+ return mapped IPv4 addresses to AAAA queries when
+ there are no AAAA records. It is intended to be
+ used in conjunction with a NAT64. Each
+ <span><strong class="command">dns64</strong></span> defines one DNS64 prefix.
+ Multiple DNS64 prefixes can be defined.
+ </p>
+<p>
+ Compatible IPv6 prefixes have lengths of 32, 40, 48, 56,
+ 64 and 96 as per RFC 6052.
+ </p>
+<p>
+ Additionally a reverse IP6.ARPA zone will be created for
+ the prefix to provide a mapping from the IP6.ARPA names
+ to the corresponding IN-ADDR.ARPA names using synthesized
+ CNAMEs. <span><strong class="command">dns64-server</strong></span> and
+ <span><strong class="command">dns64-contact</strong></span> can be used to specify
+ the name of the server and contact for the zones. These
+ are settable at the view / options level. These are
+ not settable on a per-prefix basis.
+ </p>
+<p>
+ Each <span><strong class="command">dns64</strong></span> supports an optional
+ <span><strong class="command">clients</strong></span> ACL that determines which
+ clients are affected by this directive. If not defined,
+ it defaults to <strong class="userinput"><code>any;</code></strong>.
+ </p>
+<p>
+ Each <span><strong class="command">dns64</strong></span> supports an optional
+ <span><strong class="command">mapped</strong></span> ACL that selects which
+ IPv4 addresses are to be mapped in the corresponding
+ A RRset. If not defined it defaults to
+ <strong class="userinput"><code>any;</code></strong>.
+ </p>
+<p>
+ Each <span><strong class="command">dns64</strong></span> supports an optional
+ <span><strong class="command">exclude</strong></span> ACL that selects which
+ IPv6 addresses will be ignored for the purposes
+ of determining whether dns64 is to be applied.
+ Any non-matching address will prevent further
+ DNS64 processing from occurring for this client.
+ </p>
+<p>
+ A optional <span><strong class="command">suffix</strong></span> can also
+ be defined to set the bits trailing the mapped
+ IPv4 address bits. By default these bits are
+ set to <strong class="userinput"><code>::</code></strong>. The bits
+ matching the prefix and mapped IPv4 address
+ must be zero.
+ </p>
+<pre class="programlisting">
+ acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
+
+ dns64 64:FF9B::/96 {
+ clients { any; };
+ mapped { !rfc1918; any; };
+ exclude { 64:FF9B::/96; ::ffff:0000:0000/96; };
+ suffix ::;
+ };
+</pre>
+</dd>
</dl></div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boolean_options"></a>Boolean Options</h4></div></div></div>
<div class="variablelist"><dl>
+<dt><span class="term"><span><strong class="command">allow-new-zones</strong></span></span></dt>
+<dd><p>
+ If <strong class="userinput"><code>yes</code></strong>, then zones can be
+ added at runtime via <span><strong class="command">rndc addzone</strong></span>
+ or deleted via <span><strong class="command">rndc delzone</strong></span>.
+ The default is <strong class="userinput"><code>no</code></strong>.
+ </p></dd>
<dt><span class="term"><span><strong class="command">auth-nxdomain</strong></span></span></dt>
<dd><p>
If <strong class="userinput"><code>yes</code></strong>, then the <span><strong class="command">AA</strong></span> bit
@@ -2863,6 +3179,7 @@ options {
off
on a per-zone basis by specifying <span><strong class="command">zone-statistics no</strong></span>
in the <span><strong class="command">zone</strong></span> statement).
+ The default is <strong class="userinput"><code>no</code></strong>.
These statistics may be accessed
using <span><strong class="command">rndc stats</strong></span>, which will
dump them to the file listed
@@ -3006,6 +3323,57 @@ options {
internally. The use of this option is discouraged.
</p>
</dd>
+<dt><span class="term"><span><strong class="command">filter-aaaa-on-v4</strong></span></span></dt>
+<dd>
+<p>
+ This option is only available when
+ <acronym class="acronym">BIND</acronym> 9 is compiled with the
+ <strong class="userinput"><code>--enable-filter-aaaa</code></strong> option on the
+ "configure" command line. It is intended to help the
+ transition from IPv4 to IPv6 by not giving IPv6 addresses
+ to DNS clients unless they have connections to the IPv6
+ Internet. This is not recommended unless absolutely
+ necessary. The default is <strong class="userinput"><code>no</code></strong>.
+ The <span><strong class="command">filter-aaaa-on-v4</strong></span> option
+ may also be specified in <span><strong class="command">view</strong></span> statements
+ to override the global <span><strong class="command">filter-aaaa-on-v4</strong></span>
+ option.
+ </p>
+<p>
+ If <strong class="userinput"><code>yes</code></strong>,
+ the DNS client is at an IPv4 address, in <span><strong class="command">filter-aaaa</strong></span>,
+ and if the response does not include DNSSEC signatures,
+ then all AAAA records are deleted from the response.
+ This filtering applies to all responses and not only
+ authoritative responses.
+ </p>
+<p>
+ If <strong class="userinput"><code>break-dnssec</code></strong>,
+ then AAAA records are deleted even when dnssec is enabled.
+ As suggested by the name, this makes the response not verify,
+ because the DNSSEC protocol is designed detect deletions.
+ </p>
+<p>
+ This mechanism can erroneously cause other servers to
+ not give AAAA records to their clients.
+ A recursing server with both IPv6 and IPv4 network connections
+ that queries an authoritative server using this mechanism
+ via IPv4 will be denied AAAA records even if its client is
+ using IPv6.
+ </p>
+<p>
+ This mechanism is applied to authoritative as well as
+ non-authoritative records.
+ A client using IPv4 that is not allowed recursion can
+ erroneously be given AAAA records because the server is not
+ allowed to check for A records.
+ </p>
+<p>
+ Some AAAA records are given to IPv4 clients in glue records.
+ IPv4 clients that are servers can then erroneously
+ answer requests for AAAA records received via IPv4.
+ </p>
+</dd>
<dt><span class="term"><span><strong class="command">ixfr-from-differences</strong></span></span></dt>
<dd>
<p>
@@ -3060,13 +3428,23 @@ options {
Enable DNSSEC validation in <span><strong class="command">named</strong></span>.
Note <span><strong class="command">dnssec-enable</strong></span> also needs to be
set to <strong class="userinput"><code>yes</code></strong> to be effective.
- The default is <strong class="userinput"><code>yes</code></strong>.
+ If set to <strong class="userinput"><code>no</code></strong>, DNSSEC validation
+ is disabled. If set to <strong class="userinput"><code>auto</code></strong>,
+ DNSSEC validation is enabled, and a default
+ trust-anchor for the DNS root zone is used. If set to
+ <strong class="userinput"><code>yes</code></strong>, DNSSEC validation is enabled,
+ but a trust anchor must be manually configured using
+ a <span><strong class="command">trusted-keys</strong></span> or
+ <span><strong class="command">managed-keys</strong></span> statement. The default
+ is <strong class="userinput"><code>yes</code></strong>.
</p></dd>
<dt><span class="term"><span><strong class="command">dnssec-accept-expired</strong></span></span></dt>
<dd><p>
Accept expired signatures when verifying DNSSEC signatures.
The default is <strong class="userinput"><code>no</code></strong>.
- Setting this option to "yes" leaves <span><strong class="command">named</strong></span> vulnerable to replay attacks.
+ Setting this option to <strong class="userinput"><code>yes</code></strong>
+ leaves <span><strong class="command">named</strong></span> vulnerable to
+ replay attacks.
</p></dd>
<dt><span class="term"><span><strong class="command">querylog</strong></span></span></dt>
<dd><p>
@@ -3104,6 +3482,14 @@ options {
(the owner name ends in IN-ADDR.ARPA, IP6.ARPA, or IP6.INT).
</p>
</dd>
+<dt><span class="term"><span><strong class="command">check-dup-records</strong></span></span></dt>
+<dd><p>
+ Check master zones for records that are treated as different
+ by DNSSEC but are semantically equal in plain DNS. The
+ default is to <span><strong class="command">warn</strong></span>. Other possible
+ values are <span><strong class="command">fail</strong></span> and
+ <span><strong class="command">ignore</strong></span>.
+ </p></dd>
<dt><span class="term"><span><strong class="command">check-mx</strong></span></span></dt>
<dd><p>
Check whether the MX record appears to refer to a IP address.
@@ -3166,26 +3552,86 @@ options {
The default is <span><strong class="command">no</strong></span>.
</p></dd>
<dt><span class="term"><span><strong class="command">update-check-ksk</strong></span></span></dt>
-<dd><p>
- When regenerating the RRSIGs following a UPDATE
- request to a secure zone, check the KSK flag on
- the DNSKEY RR to determine if this key should be
- used to generate the RRSIG. This flag is ignored
- if there are not DNSKEY RRs both with and without
- a KSK.
- The default is <span><strong class="command">yes</strong></span>.
- </p></dd>
+<dd>
+<p>
+ When set to the default value of <code class="literal">yes</code>,
+ check the KSK bit in each key to determine how the key
+ should be used when generating RRSIGs for a secure zone.
+ </p>
+<p>
+ Ordinarily, zone-signing keys (that is, keys without the
+ KSK bit set) are used to sign the entire zone, while
+ key-signing keys (keys with the KSK bit set) are only
+ used to sign the DNSKEY RRset at the zone apex.
+ However, if this option is set to <code class="literal">no</code>,
+ then the KSK bit is ignored; KSKs are treated as if they
+ were ZSKs and are used to sign the entire zone. This is
+ similar to the <span><strong class="command">dnssec-signzone -z</strong></span>
+ command line option.
+ </p>
+<p>
+ When this option is set to <code class="literal">yes</code>, there
+ must be at least two active keys for every algorithm
+ represented in the DNSKEY RRset: at least one KSK and one
+ ZSK per algorithm. If there is any algorithm for which
+ this requirement is not met, this option will be ignored
+ for that algorithm.
+ </p>
+</dd>
+<dt><span class="term"><span><strong class="command">dnssec-dnskey-kskonly</strong></span></span></dt>
+<dd>
+<p>
+ When this option and <span><strong class="command">update-check-ksk</strong></span>
+ are both set to <code class="literal">yes</code>, only key-signing
+ keys (that is, keys with the KSK bit set) will be used
+ to sign the DNSKEY RRset at the zone apex. Zone-signing
+ keys (keys without the KSK bit set) will be used to sign
+ the remainder of the zone, but not the DNSKEY RRset.
+ This is similar to the
+ <span><strong class="command">dnssec-signzone -x</strong></span> command line option.
+ </p>
+<p>
+ The default is <span><strong class="command">no</strong></span>. If
+ <span><strong class="command">update-check-ksk</strong></span> is set to
+ <code class="literal">no</code>, this option is ignored.
+ </p>
+</dd>
<dt><span class="term"><span><strong class="command">try-tcp-refresh</strong></span></span></dt>
<dd><p>
Try to refresh the zone using TCP if UDP queries fail.
For BIND 8 compatibility, the default is
<span><strong class="command">yes</strong></span>.
</p></dd>
+<dt><span class="term"><span><strong class="command">dnssec-secure-to-insecure</strong></span></span></dt>
+<dd>
+<p>
+ Allow a dynamic zone to transition from secure to
+ insecure (i.e., signed to unsigned) by deleting all
+ of the DNSKEY records. The default is <span><strong class="command">no</strong></span>.
+ If set to <span><strong class="command">yes</strong></span>, and if the DNSKEY RRset
+ at the zone apex is deleted, all RRSIG and NSEC records
+ will be removed from the zone as well.
+ </p>
+<p>
+ If the zone uses NSEC3, then it is also necessary to
+ delete the NSEC3PARAM RRset from the zone apex; this will
+ cause the removal of all corresponding NSEC3 records.
+ (It is expected that this requirement will be eliminated
+ in a future release.)
+ </p>
+<p>
+ Note that if a zone has been configured with
+ <span><strong class="command">auto-dnssec maintain</strong></span> and the
+ private keys remain accessible in the key repository,
+ then the zone will be automatically signed again the
+ next time <span><strong class="command">named</strong></span> is started.
+ </p>
+</dd>
</dl></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2581856"></a>Forwarding</h4></div></div></div>
+<a name="id2583480"></a>Forwarding</h4></div></div></div>
<p>
The forwarding facility can be used to create a large site-wide
cache on a few servers, reducing traffic over links to external
@@ -3229,7 +3675,7 @@ options {
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2581914"></a>Dual-stack Servers</h4></div></div></div>
+<a name="id2583607"></a>Dual-stack Servers</h4></div></div></div>
<p>
Dual-stack servers are used as servers of last resort to work
around
@@ -3422,11 +3868,25 @@ options {
from these addresses will not be responded to. The default
is <strong class="userinput"><code>none</code></strong>.
</p></dd>
+<dt><span class="term"><span><strong class="command">filter-aaaa</strong></span></span></dt>
+<dd><p>
+ Specifies a list of addresses to which
+ <span><strong class="command">filter-aaaa-on-v4</strong></span>
+ is applies. The default is <strong class="userinput"><code>any</code></strong>.
+ </p></dd>
+<dt><span class="term"><span><strong class="command">resolver-query-timeout</strong></span></span></dt>
+<dd><p>
+ The amount of time the resolver will spend attempting
+ to resolve a recursive query before failing. The
+ default is <code class="literal">10</code> and the maximum is
+ <code class="literal">30</code>. Setting it to <code class="literal">0</code>
+ will result in the default being used.
+ </p></dd>
</dl></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2582420"></a>Interfaces</h4></div></div></div>
+<a name="id2584227"></a>Interfaces</h4></div></div></div>
<p>
The interfaces and ports that the server will answer queries
from may be specified using the <span><strong class="command">listen-on</strong></span> option. <span><strong class="command">listen-on</strong></span> takes
@@ -3878,7 +4338,7 @@ avoid-v6-udp-ports {};
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2583691"></a>UDP Port Lists</h4></div></div></div>
+<a name="id2585362"></a>UDP Port Lists</h4></div></div></div>
<p>
<span><strong class="command">use-v4-udp-ports</strong></span>,
<span><strong class="command">avoid-v4-udp-ports</strong></span>,
@@ -3920,7 +4380,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2583751"></a>Operating System Resource Limits</h4></div></div></div>
+<a name="id2585421"></a>Operating System Resource Limits</h4></div></div></div>
<p>
The server's usage of many system resources can be limited.
Scaled values are allowed when specifying resource limits. For
@@ -4082,7 +4542,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2584173"></a>Periodic Task Intervals</h4></div></div></div>
+<a name="id2585912"></a>Periodic Task Intervals</h4></div></div></div>
<div class="variablelist"><dl>
<dt><span class="term"><span><strong class="command">cleaning-interval</strong></span></span></dt>
<dd><p>
@@ -4252,20 +4712,26 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
their directly connected networks.
</p>
<pre class="programlisting">sortlist {
- { localhost; // IF the local host
- { localnets; // THEN first fit on the
- 192.168.1/24; // following nets
+ // IF the local host
+ // THEN first fit on the following nets
+ { localhost;
+ { localnets;
+ 192.168.1/24;
{ 192.168.2/24; 192.168.3/24; }; }; };
- { 192.168.1/24; // IF on class C 192.168.1
- { 192.168.1/24; // THEN use .1, or .2 or .3
+ // IF on class C 192.168.1 THEN use .1, or .2 or .3
+ { 192.168.1/24;
+ { 192.168.1/24;
{ 192.168.2/24; 192.168.3/24; }; }; };
- { 192.168.2/24; // IF on class C 192.168.2
- { 192.168.2/24; // THEN use .2, or .1 or .3
+ // IF on class C 192.168.2 THEN use .2, or .1 or .3
+ { 192.168.2/24;
+ { 192.168.2/24;
{ 192.168.1/24; 192.168.3/24; }; }; };
- { 192.168.3/24; // IF on class C 192.168.3
- { 192.168.3/24; // THEN use .3, or .1 or .2
+ // IF on class C 192.168.3 THEN use .3, or .1 or .2
+ { 192.168.3/24;
+ { 192.168.3/24;
{ 192.168.1/24; 192.168.2/24; }; }; };
- { { 192.168.4/24; 192.168.5/24; }; // if .4 or .5, prefer that net
+ // IF .4 or .5 THEN prefer that net
+ { { 192.168.4/24; 192.168.5/24; };
};
};</pre>
<p>
@@ -4456,7 +4922,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
Specifies the number of days into the future when
DNSSEC signatures automatically generated as a
result of dynamic updates (<a href="Bv9ARM.ch04.html#dynamic_update" title="Dynamic Update">the section called &#8220;Dynamic Update&#8221;</a>) will expire. There
- is a optional second field which specifies how
+ is an optional second field which specifies how
long before expiry that the signatures will be
regenerated. If not specified, the signatures will
be regenerated at 1/4 of base interval. The second
@@ -4537,30 +5003,46 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</p>
</dd>
<dt><span class="term"><span><strong class="command">edns-udp-size</strong></span></span></dt>
-<dd><p>
+<dd>
+<p>
Sets the advertised EDNS UDP buffer size in bytes
to control the size of packets received.
- Valid values are 512 to 4096 (values outside this range
+ Valid values are 1024 to 4096 (values outside this range
will be silently adjusted). The default value
is 4096. The usual reason for setting
<span><strong class="command">edns-udp-size</strong></span> to a non-default
value is to get UDP answers to pass through broken
firewalls that block fragmented packets and/or
block UDP packets that are greater than 512 bytes.
- </p></dd>
+ </p>
+<p>
+ <span><strong class="command">named</strong></span> will fallback to using 512 bytes
+ if it get a series of timeout at the initial value. 512
+ bytes is not being offered to encourage sites to fix their
+ firewalls. Small EDNS UDP sizes will result in the
+ excessive use of TCP.
+ </p>
+</dd>
<dt><span class="term"><span><strong class="command">max-udp-size</strong></span></span></dt>
-<dd><p>
- Sets the maximum EDNS UDP message size <span><strong class="command">named</strong></span> will
- send in bytes. Valid values are 512 to 4096 (values outside
- this range will be silently adjusted). The default
+<dd>
+<p>
+ Sets the maximum EDNS UDP message size
+ <span><strong class="command">named</strong></span> will send in bytes.
+ Valid values are 512 to 4096 (values outside this
+ range will be silently adjusted). The default
value is 4096. The usual reason for setting
- <span><strong class="command">max-udp-size</strong></span> to a non-default value is to get UDP
- answers to pass through broken firewalls that
- block fragmented packets and/or block UDP packets
- that are greater than 512 bytes.
+ <span><strong class="command">max-udp-size</strong></span> to a non-default
+ value is to get UDP answers to pass through broken
+ firewalls that block fragmented packets and/or
+ block UDP packets that are greater than 512 bytes.
This is independent of the advertised receive
buffer (<span><strong class="command">edns-udp-size</strong></span>).
- </p></dd>
+ </p>
+<p>
+ Setting this to a low value will encourage additional
+ TCP traffic to the nameserver.
+ </p>
+</dd>
<dt><span class="term"><span><strong class="command">masterfile-format</strong></span></span></dt>
<dd><p>Specifies
the file format of zone files (see
@@ -4705,7 +5187,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
<p>
Named will attempt to determine if a built-in zone already exists
or is active (covered by a forward-only forwarding declaration)
- and will not create a empty zone in that case.
+ and will not create an empty zone in that case.
</p>
<p>
The current list of empty zones is:
@@ -4873,6 +5355,260 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</p></dd>
</dl></div>
</div>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2588025"></a>Content Filtering</h4></div></div></div>
+<p>
+ <acronym class="acronym">BIND</acronym> 9 provides the ability to filter
+ out DNS responses from external DNS servers containing
+ certain types of data in the answer section.
+ Specifically, it can reject address (A or AAAA) records if
+ the corresponding IPv4 or IPv6 addresses match the given
+ <code class="varname">address_match_list</code> of the
+ <span><strong class="command">deny-answer-addresses</strong></span> option.
+ It can also reject CNAME or DNAME records if the "alias"
+ name (i.e., the CNAME alias or the substituted query name
+ due to DNAME) matches the
+ given <code class="varname">namelist</code> of the
+ <span><strong class="command">deny-answer-aliases</strong></span> option, where
+ "match" means the alias name is a subdomain of one of
+ the <code class="varname">name_list</code> elements.
+ If the optional <code class="varname">namelist</code> is specified
+ with <span><strong class="command">except-from</strong></span>, records whose query name
+ matches the list will be accepted regardless of the filter
+ setting.
+ Likewise, if the alias name is a subdomain of the
+ corresponding zone, the <span><strong class="command">deny-answer-aliases</strong></span>
+ filter will not apply;
+ for example, even if "example.com" is specified for
+ <span><strong class="command">deny-answer-aliases</strong></span>,
+ </p>
+<pre class="programlisting">www.example.com. CNAME xxx.example.com.</pre>
+<p>
+ returned by an "example.com" server will be accepted.
+ </p>
+<p>
+ In the <code class="varname">address_match_list</code> of the
+ <span><strong class="command">deny-answer-addresses</strong></span> option, only
+ <code class="varname">ip_addr</code>
+ and <code class="varname">ip_prefix</code>
+ are meaningful;
+ any <code class="varname">key_id</code> will be silently ignored.
+ </p>
+<p>
+ If a response message is rejected due to the filtering,
+ the entire message is discarded without being cached, and
+ a SERVFAIL error will be returned to the client.
+ </p>
+<p>
+ This filtering is intended to prevent "DNS rebinding attacks," in
+ which an attacker, in response to a query for a domain name the
+ attacker controls, returns an IP address within your own network or
+ an alias name within your own domain.
+ A naive web browser or script could then serve as an
+ unintended proxy, allowing the attacker
+ to get access to an internal node of your local network
+ that couldn't be externally accessed otherwise.
+ See the paper available at
+ <a href="" target="_top">
+ http://portal.acm.org/citation.cfm?id=1315245.1315298
+ </a>
+ for more details about the attacks.
+ </p>
+<p>
+ For example, if you own a domain named "example.net" and
+ your internal network uses an IPv4 prefix 192.0.2.0/24,
+ you might specify the following rules:
+ </p>
+<pre class="programlisting">deny-answer-addresses { 192.0.2.0/24; } except-from { "example.net"; };
+deny-answer-aliases { "example.net"; };
+</pre>
+<p>
+ If an external attacker lets a web browser in your local
+ network look up an IPv4 address of "attacker.example.com",
+ the attacker's DNS server would return a response like this:
+ </p>
+<pre class="programlisting">attacker.example.com. A 192.0.2.1</pre>
+<p>
+ in the answer section.
+ Since the rdata of this record (the IPv4 address) matches
+ the specified prefix 192.0.2.0/24, this response will be
+ ignored.
+ </p>
+<p>
+ On the other hand, if the browser looks up a legitimate
+ internal web server "www.example.net" and the
+ following response is returned to
+ the <acronym class="acronym">BIND</acronym> 9 server
+ </p>
+<pre class="programlisting">www.example.net. A 192.0.2.2</pre>
+<p>
+ it will be accepted since the owner name "www.example.net"
+ matches the <span><strong class="command">except-from</strong></span> element,
+ "example.net".
+ </p>
+<p>
+ Note that this is not really an attack on the DNS per se.
+ In fact, there is nothing wrong for an "external" name to
+ be mapped to your "internal" IP address or domain name
+ from the DNS point of view.
+ It might actually be provided for a legitimate purpose,
+ such as for debugging.
+ As long as the mapping is provided by the correct owner,
+ it is not possible or does not make sense to detect
+ whether the intent of the mapping is legitimate or not
+ within the DNS.
+ The "rebinding" attack must primarily be protected at the
+ application that uses the DNS.
+ For a large site, however, it may be difficult to protect
+ all possible applications at once.
+ This filtering feature is provided only to help such an
+ operational environment;
+ it is generally discouraged to turn it on unless you are
+ very sure you have no other choice and the attack is a
+ real threat for your applications.
+ </p>
+<p>
+ Care should be particularly taken if you want to use this
+ option for addresses within 127.0.0.0/8.
+ These addresses are obviously "internal", but many
+ applications conventionally rely on a DNS mapping from
+ some name to such an address.
+ Filtering out DNS records containing this address
+ spuriously can break such applications.
+ </p>
+</div>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2588148"></a>Response Policy Zone (RPZ) Rewriting</h4></div></div></div>
+<p>
+ <acronym class="acronym">BIND</acronym> 9 includes an intentionally limited
+ mechanism to modify DNS responses for recursive requests
+ similar to email anti-spam DNS blacklists.
+ All response policy zones are named in the
+ <span><strong class="command">response-policy</strong></span> option for the view or among the
+ global options if there is no response-policy option for the view.
+ </p>
+<p>
+ The rules encoded in a response policy zone (RPZ) are applied
+ only to responses to queries that ask for recursion (RD=1).
+ RPZs are normal DNS zones containing RRsets
+ that can be queried normally if allowed.
+ It is usually best to restrict those queries with something like
+ <span><strong class="command">allow-query {none; };</strong></span> or
+ <span><strong class="command">allow-query { 127.0.0.1; };</strong></span>.
+ </p>
+<p>
+ There are four kinds of RPZ rewrite rules. QNAME rules are
+ applied to query names in requests and to targets of CNAME
+ records resolved in the process of generating the response.
+ The owner name of a QNAME rule is the query name relativized
+ to the RPZ.
+ The records in a rewrite rule are usually A, AAAA, or special
+ CNAMEs, but can be any type except DNAME.
+ </p>
+<p>
+ IP rules are triggered by addresses in A and AAAA records.
+ All IP addresses in A or AAAA RRsets are tested and the rule
+ longest prefix is applied. Ties between rules with equal prefixes
+ are broken in favor of the first RPZ mentioned in the
+ response-policy option.
+ The rule matching the smallest IP address is chosen among equal
+ prefix rules from a single RPZ.
+ IP rules are expressed in RRsets with owner names that are
+ subdomains of rpz-ip and encoding an IP address block, reversed
+ as in IN-ARPA.
+ prefix.B.B.B.B with prefix between 1 and 32 and B between 1 and 255
+ encodes an IPv4 address.
+ IPv6 addresses are encoded by with prefix.W.W.W.W.W.W.W.W or
+ prefix.WORDS.zz.WORDS. The words in the standard IPv6 text
+ representation are reversed, "::" is replaced with ".zz.",
+ and ":" becomes ".".
+ </p>
+<p>
+ NSDNAME rules match names in NS RRsets for the response or a
+ parent. They are encoded as subdomains of rpz-nsdomain relativized
+ to the RPZ origin name.
+ </p>
+<p>
+ NSIP rules match IP addresses in A and AAAA RRsets for names of
+ responsible servers or the names that can be matched by NSDNAME
+ rules. The are encoded like IP rules except as subdomains of
+ rpz-nsip.
+ </p>
+<p>
+ Authority verification issues and variations in authority data in
+ the current version of <acronym class="acronym">BIND</acronym> 9 can cause
+ inconsistent results from NSIP and NSDNAME. So they are available
+ only when <acronym class="acronym">BIND</acronym> is built with the
+ <strong class="userinput"><code>--enable-rpz-nsip</code></strong> or
+ <strong class="userinput"><code>--enable-rpz-nsdname</code></strong> options
+ on the "configure" command line.
+ </p>
+<p>
+ Four policies can be expressed.
+ The <span><strong class="command">NXDOMAIN</strong></span> policy causes a NXDOMAIN response
+ and is expressed with an RRset consisting of a single CNAME
+ whose target is the root domain (.).
+ <span><strong class="command">NODATA</strong></span> generates NODATA or ANCOUNT=1 regardless
+ of query type.
+ It is expressed with a CNAME whose target is the wildcard
+ top-level domain (*.).
+ The <span><strong class="command">NO-OP</strong></span> policy does not change the response
+ and is used to "poke holes" in policies for larger CIDR blocks or in
+ zones named later in the <span><strong class="command">response-policy</strong></span> option.
+ The NO-OP policy is expressed by a CNAME with a target consisting
+ of the variable part of the owner name, such as "example.com." for
+ a QNAME rule or "128.1.0.0.127." for an IP rule.
+ The <span><strong class="command">CNAME</strong></span> policy is used to replace the RRsets
+ of response.
+ A and AAAA RRsets are most common and useful to capture
+ an evil domain in a walled garden, but any valid set of RRsets
+ is possible.
+ </p>
+<p>
+ All of the policies in an RPZ can be overridden with a
+ <span><strong class="command">policy</strong></span> clause.
+ <span><strong class="command">given</strong></span> says "do not override."
+ <span><strong class="command">no-op</strong></span> says "do nothing" regardless of the policy
+ in RPZ records.
+ <span><strong class="command">nxdomain</strong></span> causes all RPZ rules to generate
+ NXDOMAIN results.
+ <span><strong class="command">nodata</strong></span> gives nodata.
+ <span><strong class="command">cname domain</strong></span> causes all RPZ rules to act as if
+ the consisted of a "cname domain" record.
+ </p>
+<p>
+ For example, you might use this option statement
+ </p>
+<pre class="programlisting">response-policy { zone "bl"; };</pre>
+<p>
+ and this zone statement
+ </p>
+<pre class="programlisting">zone "bl" {type master; file "example/bl"; allow-query {none;}; };</pre>
+<p>
+ with this zone file
+ </p>
+<pre class="programlisting">$TTL 1H
+@ SOA LOCALHOST. named-mgr.example.com (1 1h 15m 30d 2h)
+
+; QNAME rules
+nxdomain.domain.com CNAME .
+nodata.domain.com CNAME *.
+bad.domain.com A 10.0.0.1
+ AAAA 2001:2::1
+ok.domain.com CNAME ok.domain.com.
+*.badzone.domain.com CNAME garden.example.com.
+
+; IP rules rewriting all answers for 127/8 except 127.0.0.1
+8.0.0.0.127.ip CNAME .
+32.1.0.0.127.ip CNAME 32.1.0.0.127.
+
+; NSDNAME and NSIP rules
+ns.domain.com.rpz-nsdname CNAME .
+48.zz.2.2001.rpz-nsip CNAME .
+</pre>
+</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
@@ -4891,8 +5627,10 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
[<span class="optional"> transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> notify-source (<em class="replaceable"><code>ip4_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> notify-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
- [<span class="optional"> query-source [<span class="optional"> address ( <em class="replaceable"><code>ip_addr</code></em> | <em class="replaceable"><code>*</code></em> ) </span>] [<span class="optional"> port ( <em class="replaceable"><code>ip_port</code></em> | <em class="replaceable"><code>*</code></em> ) </span>]; </span>]
- [<span class="optional"> query-source-v6 [<span class="optional"> address ( <em class="replaceable"><code>ip_addr</code></em> | <em class="replaceable"><code>*</code></em> ) </span>] [<span class="optional"> port ( <em class="replaceable"><code>ip_port</code></em> | <em class="replaceable"><code>*</code></em> ) </span>]; </span>]
+ [<span class="optional"> query-source [<span class="optional"> address ( <em class="replaceable"><code>ip_addr</code></em> | <em class="replaceable"><code>*</code></em> ) </span>]
+ [<span class="optional"> port ( <em class="replaceable"><code>ip_port</code></em> | <em class="replaceable"><code>*</code></em> ) </span>]; </span>]
+ [<span class="optional"> query-source-v6 [<span class="optional"> address ( <em class="replaceable"><code>ip_addr</code></em> | <em class="replaceable"><code>*</code></em> ) </span>]
+ [<span class="optional"> port ( <em class="replaceable"><code>ip_port</code></em> | <em class="replaceable"><code>*</code></em> ) </span>]; </span>]
[<span class="optional"> use-queryport-pool <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> queryport-pool-ports <em class="replaceable"><code>number</code></em>; </span>]
[<span class="optional"> queryport-pool-updateinterval <em class="replaceable"><code>number</code></em>; </span>]
@@ -5072,14 +5810,15 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
<div class="titlepage"><div><div><h3 class="title">
<a name="statschannels"></a><span><strong class="command">statistics-channels</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">statistics-channels</strong></span> {
- [ inet ( ip_addr | * ) [ port ip_port ] [allow { <em class="replaceable"><code> address_match_list </code></em> } ]; ]
+ [ inet ( ip_addr | * ) [ port ip_port ]
+ [ allow { <em class="replaceable"><code> address_match_list </code></em> } ]; ]
[ inet ...; ]
};
</pre>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2586907"></a><span><strong class="command">statistics-channels</strong></span> Statement Definition and
+<a name="id2589239"></a><span><strong class="command">statistics-channels</strong></span> Statement Definition and
Usage</h3></div></div></div>
<p>
The <span><strong class="command">statistics-channels</strong></span> statement
@@ -5130,7 +5869,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2587062"></a><span><strong class="command">trusted-keys</strong></span> Statement Grammar</h3></div></div></div>
+<a name="trusted-keys"></a><span><strong class="command">trusted-keys</strong></span> Statement Grammar</h3></div></div></div>
<pre class="programlisting"><span><strong class="command">trusted-keys</strong></span> {
<em class="replaceable"><code>string</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ;
[<span class="optional"> <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ; [<span class="optional">...</span>]</span>]
@@ -5139,7 +5878,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2587113"></a><span><strong class="command">trusted-keys</strong></span> Statement Definition
+<a name="id2589379"></a><span><strong class="command">trusted-keys</strong></span> Statement Definition
and Usage</h3></div></div></div>
<p>
The <span><strong class="command">trusted-keys</strong></span> statement defines
@@ -5169,6 +5908,135 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
in the key data, so the configuration may be split up into
multiple lines.
</p>
+<p>
+ <span><strong class="command">trusted-keys</strong></span> may be set at the top level
+ of <code class="filename">named.conf</code> or within a view. If it is
+ set in both places, they are additive: keys defined at the top
+ level are inherited by all views, but keys defined in a view
+ are only used within that view.
+ </p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2589494"></a><span><strong class="command">managed-keys</strong></span> Statement Grammar</h3></div></div></div>
+<pre class="programlisting"><span><strong class="command">managed-keys</strong></span> {
+ <em class="replaceable"><code>string</code></em> initial-key <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ;
+ [<span class="optional"> <em class="replaceable"><code>string</code></em> initial-key <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ; [<span class="optional">...</span>]</span>]
+};
+</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="managed-keys"></a><span><strong class="command">managed-keys</strong></span> Statement Definition
+ and Usage</h3></div></div></div>
+<p>
+ The <span><strong class="command">managed-keys</strong></span> statement, like
+ <span><strong class="command">trusted-keys</strong></span>, defines DNSSEC
+ security roots. The difference is that
+ <span><strong class="command">managed-keys</strong></span> can be kept up to date
+ automatically, without intervention from the resolver
+ operator.
+ </p>
+<p>
+ Suppose, for example, that a zone's key-signing
+ key was compromised, and the zone owner had to revoke and
+ replace the key. A resolver which had the old key in a
+ <span><strong class="command">trusted-keys</strong></span> statement would be
+ unable to validate this zone any longer; it would
+ reply with a SERVFAIL response code. This would
+ continue until the resolver operator had updated the
+ <span><strong class="command">trusted-keys</strong></span> statement with the new key.
+ </p>
+<p>
+ If, however, the zone were listed in a
+ <span><strong class="command">managed-keys</strong></span> statement instead, then the
+ zone owner could add a "stand-by" key to the zone in advance.
+ <span><strong class="command">named</strong></span> would store the stand-by key, and
+ when the original key was revoked, <span><strong class="command">named</strong></span>
+ would be able to transition smoothly to the new key. It would
+ also recognize that the old key had been revoked, and cease
+ using that key to validate answers, minimizing the damage that
+ the compromised key could do.
+ </p>
+<p>
+ A <span><strong class="command">managed-keys</strong></span> statement contains a list of
+ the keys to be managed, along with information about how the
+ keys are to be initialized for the first time. The only
+ initialization method currently supported (as of
+ <acronym class="acronym">BIND</acronym> 9.7.0) is <code class="literal">initial-key</code>.
+ This means the <span><strong class="command">managed-keys</strong></span> statement must
+ contain a copy of the initializing key. (Future releases may
+ allow keys to be initialized by other methods, eliminating this
+ requirement.)
+ </p>
+<p>
+ Consequently, a <span><strong class="command">managed-keys</strong></span> statement
+ appears similar to a <span><strong class="command">trusted-keys</strong></span>, differing
+ in the presence of the second field, containing the keyword
+ <code class="literal">initial-key</code>. The difference is, whereas the
+ keys listed in a <span><strong class="command">trusted-keys</strong></span> continue to be
+ trusted until they are removed from
+ <code class="filename">named.conf</code>, an initializing key listed
+ in a <span><strong class="command">managed-keys</strong></span> statement is only trusted
+ <span class="emphasis"><em>once</em></span>: for as long as it takes to load the
+ managed key database and start the RFC 5011 key maintenance
+ process.
+ </p>
+<p>
+ The first time <span><strong class="command">named</strong></span> runs with a managed key
+ configured in <code class="filename">named.conf</code>, it fetches the
+ DNSKEY RRset directly from the zone apex, and validates it
+ using the key specified in the <span><strong class="command">managed-keys</strong></span>
+ statement. If the DNSKEY RRset is validly signed, then it is
+ used as the basis for a new managed keys database.
+ </p>
+<p>
+ From that point on, whenever <span><strong class="command">named</strong></span> runs, it
+ sees the <span><strong class="command">managed-keys</strong></span> statement, checks to
+ make sure RFC 5011 key maintenance has already been initialized
+ for the specified domain, and if so, it simply moves on. The
+ key specified in the <span><strong class="command">managed-keys</strong></span> is not
+ used to validate answers; it has been superseded by the key or
+ keys stored in the managed keys database.
+ </p>
+<p>
+ The next time <span><strong class="command">named</strong></span> runs after a name
+ has been <span class="emphasis"><em>removed</em></span> from the
+ <span><strong class="command">managed-keys</strong></span> statement, the corresponding
+ zone will be removed from the managed keys database,
+ and RFC 5011 key maintenance will no longer be used for that
+ domain.
+ </p>
+<p>
+ <span><strong class="command">named</strong></span> only maintains a single managed keys
+ database; consequently, unlike <span><strong class="command">trusted-keys</strong></span>,
+ <span><strong class="command">managed-keys</strong></span> may only be set at the top
+ level of <code class="filename">named.conf</code>, not within a view.
+ </p>
+<p>
+ In the current implementation, the managed keys database is
+ stored as a master-format zone file called
+ <code class="filename">managed-keys.bind</code>. When the key database
+ is changed, the zone is updated. As with any other dynamic
+ zone, changes will be written into a journal file,
+ <code class="filename">managed-keys.bind.jnl</code>. They are committed
+ to the master file as soon as possible afterward; in the case
+ of the managed key database, this will usually occur within 30
+ seconds. So, whenever <span><strong class="command">named</strong></span> is using
+ automatic key maintenance, those two files can be expected to
+ exist in the working directory. (For this reason among others,
+ the working directory should be always be writable by
+ <span><strong class="command">named</strong></span>.)
+ </p>
+<p>
+ If the <span><strong class="command">dnssec-lookaside</strong></span> option is
+ set to <strong class="userinput"><code>auto</code></strong>, <span><strong class="command">named</strong></span>
+ will automatically initialize a managed key for the
+ zone <code class="literal">dlv.isc.org</code>. The key that is
+ used to initialize the key maintenance process is built
+ into <span><strong class="command">named</strong></span>, and can be overridden
+ from <span><strong class="command">bindkeys-file</strong></span>.
+ </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
@@ -5185,7 +6053,7 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2587195"></a><span><strong class="command">view</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2589851"></a><span><strong class="command">view</strong></span> Statement Definition and Usage</h3></div></div></div>
<p>
The <span><strong class="command">view</strong></span> statement is a powerful
feature
@@ -5274,11 +6142,12 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
// This should match our internal networks.
match-clients { 10.0.0.0/8; };
- // Provide recursive service to internal clients only.
+ // Provide recursive service to internal
+ // clients only.
recursion yes;
- // Provide a complete view of the example.com zone
- // including addresses of internal hosts.
+ // Provide a complete view of the example.com
+ // zone including addresses of internal hosts.
zone "example.com" {
type master;
file "example-internal.db";
@@ -5286,14 +6155,15 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
};
view "external" {
- // Match all clients not matched by the previous view.
+ // Match all clients not matched by the
+ // previous view.
match-clients { any; };
// Refuse recursive service to external clients.
recursion no;
- // Provide a restricted view of the example.com zone
- // containing only publicly accessible hosts.
+ // Provide a restricted view of the example.com
+ // zone containing only publicly accessible hosts.
zone "example.com" {
type master;
file "example-external.db";
@@ -5311,8 +6181,9 @@ view "external" {
[<span class="optional"> allow-query-on { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
[<span class="optional"> allow-transfer { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
[<span class="optional"> allow-update { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
- [<span class="optional"> update-policy { <em class="replaceable"><code>update_policy_rule</code></em> [<span class="optional">...</span>] }; </span>]
- [<span class="optional"> also-notify { <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; ... </span>] }; </span>]
+ [<span class="optional"> update-policy <em class="replaceable"><code>local</code></em> | { <em class="replaceable"><code>update_policy_rule</code></em> [<span class="optional">...</span>] }; </span>]
+ [<span class="optional"> also-notify { <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ;
+ [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; ... </span>] }; </span>]
[<span class="optional"> check-names (<code class="constant">warn</code>|<code class="constant">fail</code>|<code class="constant">ignore</code>) ; </span>]
[<span class="optional"> check-mx (<code class="constant">warn</code>|<code class="constant">fail</code>|<code class="constant">ignore</code>) ; </span>]
[<span class="optional"> check-wildcard <em class="replaceable"><code>yes_or_no</code></em>; </span>]
@@ -5348,6 +6219,7 @@ view "external" {
[<span class="optional"> min-retry-time <em class="replaceable"><code>number</code></em> ; </span>]
[<span class="optional"> max-retry-time <em class="replaceable"><code>number</code></em> ; </span>]
[<span class="optional"> key-directory <em class="replaceable"><code>path_name</code></em>; </span>]
+ [<span class="optional"> auto-dnssec <code class="constant">allow</code>|<code class="constant">maintain</code>|<code class="constant">create</code>|<code class="constant">off</code>; </span>]
[<span class="optional"> zero-no-soa-ttl <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
};
@@ -5359,8 +6231,11 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
[<span class="optional"> allow-transfer { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
[<span class="optional"> allow-update-forwarding { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
[<span class="optional"> update-check-ksk <em class="replaceable"><code>yes_or_no</code></em>; </span>]
+ [<span class="optional"> dnssec-dnskey-kskonly <em class="replaceable"><code>yes_or_no</code></em>; </span>]
+ [<span class="optional"> dnssec-secure-to-insecure <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
[<span class="optional"> try-tcp-refresh <em class="replaceable"><code>yes_or_no</code></em>; </span>]
- [<span class="optional"> also-notify { <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; ... </span>] }; </span>]
+ [<span class="optional"> also-notify { <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ;
+ [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; ... </span>] }; </span>]
[<span class="optional"> check-names (<code class="constant">warn</code>|<code class="constant">fail</code>|<code class="constant">ignore</code>) ; </span>]
[<span class="optional"> dialup <em class="replaceable"><code>dialup_option</code></em> ; </span>]
[<span class="optional"> file <em class="replaceable"><code>string</code></em> ; </span>]
@@ -5373,7 +6248,9 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
[<span class="optional"> ixfr-from-differences <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> ixfr-tmp-file <em class="replaceable"><code>string</code></em> ; </span>]
[<span class="optional"> maintain-ixfr-base <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
- [<span class="optional"> masters [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] { ( <em class="replaceable"><code>masters_list</code></em> | <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] [<span class="optional">key <em class="replaceable"><code>key</code></em></span>] ) ; [<span class="optional">...</span>] }; </span>]
+ [<span class="optional"> masters [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] { ( <em class="replaceable"><code>masters_list</code></em> | <em class="replaceable"><code>ip_addr</code></em>
+ [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>]
+ [<span class="optional">key <em class="replaceable"><code>key</code></em></span>] ) ; [<span class="optional">...</span>] }; </span>]
[<span class="optional"> max-ixfr-log-size <em class="replaceable"><code>number</code></em> ; </span>]
[<span class="optional"> max-transfer-idle-in <em class="replaceable"><code>number</code></em> ; </span>]
[<span class="optional"> max-transfer-idle-out <em class="replaceable"><code>number</code></em> ; </span>]
@@ -5386,7 +6263,8 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
[<span class="optional"> transfer-source (<em class="replaceable"><code>ip4_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> alt-transfer-source (<em class="replaceable"><code>ip4_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
- [<span class="optional"> alt-transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
+ [<span class="optional"> alt-transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>)
+ [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> use-alt-transfer-source <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> notify-source (<em class="replaceable"><code>ip4_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> notify-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
@@ -5404,7 +6282,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
type hint;
file <em class="replaceable"><code>string</code></em> ;
[<span class="optional"> delegation-only <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
- [<span class="optional"> check-names (<code class="constant">warn</code>|<code class="constant">fail</code>|<code class="constant">ignore</code>) ; // Not Implemented. </span>]
+ [<span class="optional"> check-names (<code class="constant">warn</code>|<code class="constant">fail</code>|<code class="constant">ignore</code>) ; </span>] // Not Implemented.
};
zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"><em class="replaceable"><code>class</code></em></span>] {
@@ -5418,14 +6296,18 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
[<span class="optional"> masterfile-format (<code class="constant">text</code>|<code class="constant">raw</code>) ; </span>]
[<span class="optional"> forward (<code class="constant">only</code>|<code class="constant">first</code>) ; </span>]
[<span class="optional"> forwarders { [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; ... </span>] }; </span>]
- [<span class="optional"> masters [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] { ( <em class="replaceable"><code>masters_list</code></em> | <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] [<span class="optional">key <em class="replaceable"><code>key</code></em></span>] ) ; [<span class="optional">...</span>] }; </span>]
+ [<span class="optional"> masters [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] { ( <em class="replaceable"><code>masters_list</code></em> | <em class="replaceable"><code>ip_addr</code></em>
+ [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>]
+ [<span class="optional">key <em class="replaceable"><code>key</code></em></span>] ) ; [<span class="optional">...</span>] }; </span>]
[<span class="optional"> max-transfer-idle-in <em class="replaceable"><code>number</code></em> ; </span>]
[<span class="optional"> max-transfer-time-in <em class="replaceable"><code>number</code></em> ; </span>]
[<span class="optional"> pubkey <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>string</code></em> ; </span>]
[<span class="optional"> transfer-source (<em class="replaceable"><code>ip4_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
- [<span class="optional"> transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
+ [<span class="optional"> transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>)
+ [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> alt-transfer-source (<em class="replaceable"><code>ip4_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
- [<span class="optional"> alt-transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>) [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
+ [<span class="optional"> alt-transfer-source-v6 (<em class="replaceable"><code>ip6_addr</code></em> | <code class="constant">*</code>)
+ [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; </span>]
[<span class="optional"> use-alt-transfer-source <em class="replaceable"><code>yes_or_no</code></em>; </span>]
[<span class="optional"> zone-statistics <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
[<span class="optional"> database <em class="replaceable"><code>string</code></em> ; </span>]
@@ -5437,6 +6319,14 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
};
zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"><em class="replaceable"><code>class</code></em></span>] {
+ type static-stub;
+ [<span class="optional"> allow-query { <em class="replaceable"><code>address_match_list</code></em> }; </span>]
+ [<span class="optional"> server-addresses { [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> ; ... </span>] }; </span>]
+ [<span class="optional"> server-names { [<span class="optional"> <em class="replaceable"><code>namelist</code></em> </span>] }; </span>]
+ [<span class="optional"> zone-statistics <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
+};
+
+zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"><em class="replaceable"><code>class</code></em></span>] {
type forward;
[<span class="optional"> forward (<code class="constant">only</code>|<code class="constant">first</code>) ; </span>]
[<span class="optional"> forwarders { [<span class="optional"> <em class="replaceable"><code>ip_addr</code></em> [<span class="optional">port <em class="replaceable"><code>ip_port</code></em></span>] ; ... </span>] }; </span>]
@@ -5451,10 +6341,10 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2588600"></a><span><strong class="command">zone</strong></span> Statement Definition and Usage</h3></div></div></div>
+<a name="id2591396"></a><span><strong class="command">zone</strong></span> Statement Definition and Usage</h3></div></div></div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2588608"></a>Zone Types</h4></div></div></div>
+<a name="id2591403"></a>Zone Types</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -5583,6 +6473,55 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
<tr>
<td>
<p>
+ <code class="varname">static-stub</code>
+ </p>
+ </td>
+<td>
+ <p>
+ A static-stub zone is similar to a stub zone
+ with the following exceptions:
+ the zone data is statically configured, rather
+ than transferred from a master server;
+ when recursion is necessary for a query that
+ matches a static-stub zone, the locally
+ configured data (nameserver names and glue addresses)
+ is always used even if different authoritative
+ information is cached.
+ </p>
+ <p>
+ Zone data is configured via the
+ <span><strong class="command">server-addresses</strong></span> and
+ <span><strong class="command">server-names</strong></span> zone options.
+ </p>
+ <p>
+ The zone data is maintained in the form of NS
+ and (if necessary) glue A or AAAA RRs
+ internally, which can be seen by dumping zone
+ databases by <span><strong class="command">rndc dumpdb -all</strong></span>.
+ The configured RRs are considered local configuration
+ parameters rather than public data.
+ Non recursive queries (i.e., those with the RD
+ bit off) to a static-stub zone are therefore
+ prohibited and will be responded with REFUSED.
+ </p>
+ <p>
+ Since the data is statically configured, no
+ zone maintenance action takes place for a static-stub
+ zone.
+ For example, there is no periodic refresh
+ attempt, and an incoming notify message
+ will be rejected with an rcode of NOTAUTH.
+ </p>
+ <p>
+ Each static-stub zone is configured with
+ internally generated NS and (if necessary)
+ glue A or AAAA RRs
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
<code class="varname">forward</code>
</p>
</td>
@@ -5665,7 +6604,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2589104"></a>Class</h4></div></div></div>
+<a name="id2592085"></a>Class</h4></div></div></div>
<p>
The zone's name may optionally be followed by a class. If
a class is not specified, class <code class="literal">IN</code> (for <code class="varname">Internet</code>),
@@ -5687,7 +6626,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2589137"></a>Zone Options</h4></div></div></div>
+<a name="id2592118"></a>Zone Options</h4></div></div></div>
<div class="variablelist"><dl>
<dt><span class="term"><span><strong class="command">allow-notify</strong></span></span></dt>
<dd><p>
@@ -5752,6 +6691,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
received from the
network. The default varies according to zone type. For <span><strong class="command">master</strong></span> zones the default is <span><strong class="command">fail</strong></span>. For <span><strong class="command">slave</strong></span>
zones the default is <span><strong class="command">warn</strong></span>.
+ It is not implemented for <span><strong class="command">hint</strong></span> zones.
</p></dd>
<dt><span class="term"><span><strong class="command">check-mx</strong></span></span></dt>
<dd><p>
@@ -5783,6 +6723,11 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
See the description of
<span><strong class="command">update-check-ksk</strong></span> in <a href="Bv9ARM.ch06.html#boolean_options" title="Boolean Options">the section called &#8220;Boolean Options&#8221;</a>.
</p></dd>
+<dt><span class="term"><span><strong class="command">dnssec-dnskey-kskonly</strong></span></span></dt>
+<dd><p>
+ See the description of
+ <span><strong class="command">dnssec-dnskey-kskonly</strong></span> in <a href="Bv9ARM.ch06.html#boolean_options" title="Boolean Options">the section called &#8220;Boolean Options&#8221;</a>.
+ </p></dd>
<dt><span class="term"><span><strong class="command">try-tcp-refresh</strong></span></span></dt>
<dd><p>
See the description of
@@ -5926,6 +6871,78 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
<span><strong class="command">statistics-file</strong></span> defined in
the server options.
</p></dd>
+<dt><span class="term"><span><strong class="command">server-addresses</strong></span></span></dt>
+<dd>
+<p>
+ Only meaningful for static-stub zones.
+ This is a list of IP addresses to which queries
+ should be sent in recursive resolution for the
+ zone.
+ A non empty list for this option will internally
+ configure the apex NS RR with associated glue A or
+ AAAA RRs.
+ </p>
+<p>
+ For example, if "example.com" is configured as a
+ static-stub zone with 192.0.2.1 and 2001:db8::1234
+ in a <span><strong class="command">server-addresses</strong></span> option,
+ the following RRs will be internally configured.
+ </p>
+<pre class="programlisting">example.com. NS example.com.
+example.com. A 192.0.2.1
+example.com. AAAA 2001:db8::1234</pre>
+<p>
+ These records are internally used to resolve
+ names under the static-stub zone.
+ For instance, if the server receives a query for
+ "www.example.com" with the RD bit on, the server
+ will initiate recursive resolution and send
+ queries to 192.0.2.1 and/or 2001:db8::1234.
+ </p>
+</dd>
+<dt><span class="term"><span><strong class="command">server-names</strong></span></span></dt>
+<dd>
+<p>
+ Only meaningful for static-stub zones.
+ This is a list of domain names of nameservers that
+ act as authoritative servers of the static-stub
+ zone.
+ These names will be resolved to IP addresses when
+ <span><strong class="command">named</strong></span> needs to send queries to
+ these servers.
+ To make this supplemental resolution successful,
+ these names must not be a subdomain of the origin
+ name of static-stub zone.
+ That is, when "example.net" is the origin of a
+ static-stub zone, "ns.example" and
+ "master.example.com" can be specified in the
+ <span><strong class="command">server-names</strong></span> option, but
+ "ns.example.net" cannot, and will be rejected by
+ the configuration parser.
+ </p>
+<p>
+ A non empty list for this option will internally
+ configure the apex NS RR with the specified names.
+ For example, if "example.com" is configured as a
+ static-stub zone with "ns1.example.net" and
+ "ns2.example.net"
+ in a <span><strong class="command">server-names</strong></span> option,
+ the following RRs will be internally configured.
+ </p>
+<pre class="programlisting">example.com. NS ns1.example.net.
+example.com. NS ns2.example.net.
+</pre>
+<p>
+ These records are internally used to resolve
+ names under the static-stub zone.
+ For instance, if the server receives a query for
+ "www.example.com" with the RD bit on, the server
+ initiate recursive resolution,
+ resolve "ns1.example.net" and/or
+ "ns2.example.net" to IP addresses, and then send
+ queries to (one or more of) these addresses.
+ </p>
+</dd>
<dt><span class="term"><span><strong class="command">sig-validity-interval</strong></span></span></dt>
<dd><p>
See the description of
@@ -6003,6 +7020,48 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
Usage">the section called &#8220;<span><strong class="command">options</strong></span> Statement Definition and
Usage&#8221;</a>.
</p></dd>
+<dt><span class="term"><span><strong class="command">auto-dnssec</strong></span></span></dt>
+<dd>
+<p>
+ Zones configured for dynamic DNS may also use this
+ option to allow varying levels of automatic DNSSEC key
+ management. There are four possible settings:
+ </p>
+<p>
+ <span><strong class="command">auto-dnssec allow;</strong></span> permits
+ keys to be updated and the zone fully re-signed
+ whenever the user issues the command <span><strong class="command">rndc sign
+ <em class="replaceable"><code>zonename</code></em></strong></span>.
+ </p>
+<p>
+ <span><strong class="command">auto-dnssec maintain;</strong></span> includes the
+ above, but also automatically adjusts the zone's DNSSEC
+ keys on schedule, according to the keys' timing metadata
+ (see <a href="man.dnssec-keygen.html" title="dnssec-keygen"><span class="refentrytitle"><span class="application">dnssec-keygen</span></span>(8)</a> and
+ <a href="man.dnssec-settime.html" title="dnssec-settime"><span class="refentrytitle"><span class="application">dnssec-settime</span></span>(8)</a>). The command
+ <span><strong class="command">rndc sign
+ <em class="replaceable"><code>zonename</code></em></strong></span> causes
+ <span><strong class="command">named</strong></span> to load keys from the key
+ repository and sign the zone with all keys that are
+ active.
+ <span><strong class="command">rndc loadkeys
+ <em class="replaceable"><code>zonename</code></em></strong></span> causes
+ <span><strong class="command">named</strong></span> to load keys from the key
+ repository and schedule key maintenance events to occur
+ in the future, but it does not sign the full zone
+ immediately.
+ </p>
+<p>
+ <span><strong class="command">auto-dnssec create;</strong></span> includes the
+ above, but also allows <span><strong class="command">named</strong></span>
+ to create new keys in the key repository when needed.
+ (NOTE: This option is not yet implemented; the syntax is
+ being reserved for future use.)
+ </p>
+<p>
+ The default setting is <span><strong class="command">auto-dnssec off</strong></span>.
+ </p>
+</dd>
<dt><span class="term"><span><strong class="command">multi-master</strong></span></span></dt>
<dd><p>
See the description of <span><strong class="command">multi-master</strong></span> in
@@ -6013,6 +7072,11 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
See the description of <span><strong class="command">masterfile-format</strong></span>
in <a href="Bv9ARM.ch06.html#tuning" title="Tuning">the section called &#8220;Tuning&#8221;</a>.
</p></dd>
+<dt><span class="term"><span><strong class="command">dnssec-secure-to-insecure</strong></span></span></dt>
+<dd><p>
+ See the description of
+ <span><strong class="command">dnssec-secure-to-insecure</strong></span> in <a href="Bv9ARM.ch06.html#boolean_options" title="Boolean Options">the section called &#8220;Boolean Options&#8221;</a>.
+ </p></dd>
</dl></div>
</div>
<div class="sect3" lang="en">
@@ -6031,15 +7095,14 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
record of any name in the zone.
</p>
<p>
- The <span><strong class="command">update-policy</strong></span> clause is new
- in <acronym class="acronym">BIND</acronym> 9 and allows more fine-grained
- control over what updates are allowed. A set of rules
- is specified, where each rule either grants or denies
- permissions for one or more names to be updated by
- one or more identities. If the dynamic update request
- message is signed (that is, it includes either a TSIG
- or SIG(0) record), the identity of the signer can be
- determined.
+ The <span><strong class="command">update-policy</strong></span> clause
+ allows more fine-grained control over what updates are
+ allowed. A set of rules is specified, where each rule
+ either grants or denies permissions for one or more
+ names to be updated by one or more identities. If
+ the dynamic update request message is signed (that is,
+ it includes either a TSIG or SIG(0) record), the
+ identity of the signer can be determined.
</p>
<p>
Rules are specified in the <span><strong class="command">update-policy</strong></span>
@@ -6052,20 +7115,47 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
address is not relevant.
</p>
<p>
- This is how a rule definition looks:
+ There is a pre-defined <span><strong class="command">update-policy</strong></span>
+ rule which can be switched on with the command
+ <span><strong class="command">update-policy local;</strong></span>.
+ Switching on this rule in a zone causes
+ <span><strong class="command">named</strong></span> to generate a TSIG session
+ key and place it in a file, and to allow that key
+ to update the zone. (By default, the file is
+ <code class="filename">/var/run/named/session.key</code>, the key
+ name is "local-ddns" and the key algorithm is HMAC-SHA256,
+ but these values are configurable with the
+ <span><strong class="command">session-keyfile</strong></span>,
+ <span><strong class="command">session-keyname</strong></span> and
+ <span><strong class="command">session-keyalg</strong></span> options, respectively).
+ </p>
+<p>
+ A client running on the local system, and with appropriate
+ permissions, may read that file and use the key to sign update
+ requests. The zone's update policy will be set to allow that
+ key to change any record within the zone. Assuming the
+ key name is "local-ddns", this policy is equivalent to:
+ </p>
+<pre class="programlisting">update-policy { grant local-ddns zonesub any; };
+ </pre>
+<p>
+ The command <span><strong class="command">nsupdate -l</strong></span> sends update
+ requests to localhost, and signs them using the session key.
+ </p>
+<p>
+ Other rule definitions look like this:
</p>
<pre class="programlisting">
-( <span><strong class="command">grant</strong></span> | <span><strong class="command">deny</strong></span> ) <em class="replaceable"><code>identity</code></em> <em class="replaceable"><code>nametype</code></em> <em class="replaceable"><code>name</code></em> [<span class="optional"> <em class="replaceable"><code>types</code></em> </span>]
+( <span><strong class="command">grant</strong></span> | <span><strong class="command">deny</strong></span> ) <em class="replaceable"><code>identity</code></em> <em class="replaceable"><code>nametype</code></em> [<span class="optional"> <em class="replaceable"><code>name</code></em> </span>] [<span class="optional"> <em class="replaceable"><code>types</code></em> </span>]
</pre>
<p>
Each rule grants or denies privileges. Once a message has
successfully matched a rule, the operation is immediately
- granted
- or denied and no further rules are examined. A rule is matched
- when the signer matches the identity field, the name matches the
- name field in accordance with the nametype field, and the type
- matches
- the types specified in the type field.
+ granted or denied and no further rules are examined. A rule
+ is matched when the signer matches the identity field, the
+ name matches the name field in accordance with the nametype
+ field, and the type matches the types specified in the type
+ field.
</p>
<p>
No signer is required for <em class="replaceable"><code>tcp-self</code></em>
@@ -6091,7 +7181,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
contain a fully-qualified domain name.
</p>
<p>
- The <em class="replaceable"><code>nametype</code></em> field has 12
+ The <em class="replaceable"><code>nametype</code></em> field has 13
values:
<code class="varname">name</code>, <code class="varname">subdomain</code>,
<code class="varname">wildcard</code>, <code class="varname">self</code>,
@@ -6099,7 +7189,8 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
<code class="varname">krb5-self</code>, <code class="varname">ms-self</code>,
<code class="varname">krb5-subdomain</code>,
<code class="varname">ms-subdomain</code>,
- <code class="varname">tcp-self</code> and <code class="varname">6to4-self</code>.
+ <code class="varname">tcp-self</code>, <code class="varname">6to4-self</code>,
+ <code class="varname">zonesub</code>, and <code class="varname">external</code>.
</p>
<div class="informaltable"><table border="1">
<colgroup>
@@ -6140,6 +7231,29 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
<tr>
<td>
<p>
+ <code class="varname">zonesub</code>
+ </p>
+ </td>
+<td>
+ <p>
+ This rule is similar to subdomain, except that
+ it matches when the name being updated is a
+ subdomain of the zone in which the
+ <span><strong class="command">update-policy</strong></span> statement
+ appears. This obviates the need to type the zone
+ name twice, and enables the use of a standard
+ <span><strong class="command">update-policy</strong></span> statement in
+ multiple zones without modification.
+ </p>
+ <p>
+ When this rule is used, the
+ <em class="replaceable"><code>name</code></em> field is omitted.
+ </p>
+ </td>
+</tr>
+<tr>
+<td>
+ <p>
<code class="varname">wildcard</code>
</p>
</td>
@@ -6233,7 +7347,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
<td>
<p>
Allow the 6to4 prefix to be update by any TCP
- conection from the 6to4 network or from the
+ connection from the 6to4 network or from the
corresponding IPv4 address. This is intended
to allow NS or DNAME RRsets to be added to the
reverse tree.
@@ -6245,12 +7359,55 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
</td>
</tr>
+<tr>
+<td>
+ <p>
+ <code class="varname">external</code>
+ </p>
+ </td>
+<td>
+ <p>
+ This rule allows <span><strong class="command">named</strong></span>
+ to defer the decision of whether to allow a
+ given update to an external daemon.
+ </p>
+ <p>
+ The method of communicating with the daemon is
+ specified in the <em class="replaceable"><code>identity</code></em>
+ field, the format of which is
+ "<code class="constant">local:</code><em class="replaceable"><code>path</code></em>",
+ where <em class="replaceable"><code>path</code></em> is the location
+ of a UNIX-domain socket. (Currently, "local" is the
+ only supported mechanism.)
+ </p>
+ <p>
+ Requests to the external daemon are sent over the
+ UNIX-domain socket as datagrams with the following
+ format:
+ </p>
+ <pre class="programlisting">
+ Protocol version number (4 bytes, network byte order, currently 1)
+ Request length (4 bytes, network byte order)
+ Signer (null-terminated string)
+ Name (null-terminated string)
+ TCP source address (null-terminated string)
+ Rdata type (null-terminated string)
+ Key (null-terminated string)
+ TKEY token length (4 bytes, network byte order)
+ TKEY token (remainder of packet)</pre>
+ <p>
+ The daemon replies with a four-byte value in
+ network byte order, containing either 0 or 1; 0
+ indicates that the specified update is not
+ permitted, and 1 indicates that it is.
+ </p>
+ </td>
+</tr>
</tbody>
</table></div>
<p>
In all cases, the <em class="replaceable"><code>name</code></em>
- field must
- specify a fully-qualified domain name.
+ field must specify a fully-qualified domain name.
</p>
<p>
If no types are explicitly specified, this rule matches
@@ -6266,7 +7423,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2591216"></a>Zone File</h2></div></div></div>
+<a name="id2594660"></a>Zone File</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="types_of_resource_records_and_when_to_use_them"></a>Types of Resource Records and When to Use Them</h3></div></div></div>
@@ -6279,7 +7436,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2591234"></a>Resource Records</h4></div></div></div>
+<a name="id2594678"></a>Resource Records</h4></div></div></div>
<p>
A domain name identifies a node. Each node has a set of
resource information, which may be empty. The set of resource
@@ -7016,7 +8173,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2592857"></a>Textual expression of RRs</h4></div></div></div>
+<a name="id2596301"></a>Textual expression of RRs</h4></div></div></div>
<p>
RRs are represented in binary form in the packets of the DNS
protocol, and are usually represented in highly encoded form
@@ -7219,7 +8376,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2593378"></a>Discussion of MX Records</h3></div></div></div>
+<a name="id2596822"></a>Discussion of MX Records</h3></div></div></div>
<p>
As described above, domain servers store information as a
series of resource records, each of which contains a particular
@@ -7475,7 +8632,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2593993"></a>Inverse Mapping in IPv4</h3></div></div></div>
+<a name="id2597574"></a>Inverse Mapping in IPv4</h3></div></div></div>
<p>
Reverse name resolution (that is, translation from IP address
to name) is achieved by means of the <span class="emphasis"><em>in-addr.arpa</em></span> domain
@@ -7536,7 +8693,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2594188"></a>Other Zone File Directives</h3></div></div></div>
+<a name="id2597701"></a>Other Zone File Directives</h3></div></div></div>
<p>
The Master File Format was initially defined in RFC 1035 and
has subsequently been extended. While the Master File Format
@@ -7551,7 +8708,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2594211"></a>The <span><strong class="command">@</strong></span> (at-sign)</h4></div></div></div>
+<a name="id2597723"></a>The <span><strong class="command">@</strong></span> (at-sign)</h4></div></div></div>
<p>
When used in the label (or name) field, the asperand or
at-sign (@) symbol represents the current origin.
@@ -7562,7 +8719,7 @@ zone <em class="replaceable"><code>zone_name</code></em> [<span class="optional"
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2594227"></a>The <span><strong class="command">$ORIGIN</strong></span> Directive</h4></div></div></div>
+<a name="id2597739"></a>The <span><strong class="command">$ORIGIN</strong></span> Directive</h4></div></div></div>
<p>
Syntax: <span><strong class="command">$ORIGIN</strong></span>
<em class="replaceable"><code>domain-name</code></em>
@@ -7591,7 +8748,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2594356"></a>The <span><strong class="command">$INCLUDE</strong></span> Directive</h4></div></div></div>
+<a name="id2597868"></a>The <span><strong class="command">$INCLUDE</strong></span> Directive</h4></div></div></div>
<p>
Syntax: <span><strong class="command">$INCLUDE</strong></span>
<em class="replaceable"><code>filename</code></em>
@@ -7627,7 +8784,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2594425"></a>The <span><strong class="command">$TTL</strong></span> Directive</h4></div></div></div>
+<a name="id2597938"></a>The <span><strong class="command">$TTL</strong></span> Directive</h4></div></div></div>
<p>
Syntax: <span><strong class="command">$TTL</strong></span>
<em class="replaceable"><code>default-ttl</code></em>
@@ -7646,7 +8803,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2594461"></a><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</h3></div></div></div>
+<a name="id2597974"></a><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</h3></div></div></div>
<p>
Syntax: <span><strong class="command">$GENERATE</strong></span>
<em class="replaceable"><code>range</code></em>
@@ -7666,7 +8823,7 @@ WWW.EXAMPLE.COM. CNAME MAIN-SERVER.EXAMPLE.COM.
Classless IN-ADDR.ARPA delegation.
</p>
<pre class="programlisting">$ORIGIN 0.0.192.IN-ADDR.ARPA.
-$GENERATE 1-2 0 NS SERVER$.EXAMPLE.
+$GENERATE 1-2 @ NS SERVER$.EXAMPLE.
$GENERATE 1-127 $ CNAME $.0</pre>
<p>
is equivalent to
@@ -7678,6 +8835,28 @@ $GENERATE 1-127 $ CNAME $.0</pre>
...
127.0.0.192.IN-ADDR.ARPA. CNAME 127.0.0.0.192.IN-ADDR.ARPA.
</pre>
+<p>
+ Generate a set of A and MX records. Note the MX's right hand
+ side is a quoted string. The quotes will be stripped when the
+ right hand side is processed.
+ </p>
+<pre class="programlisting">
+$ORIGIN EXAMPLE.
+$GENERATE 1-127 HOST-$ A 1.2.3.$
+$GENERATE 1-127 HOST-$ MX "0 ."</pre>
+<p>
+ is equivalent to
+ </p>
+<pre class="programlisting">HOST-1.EXAMPLE. A 1.2.3.1
+HOST-1.EXAMPLE. MX 0 .
+HOST-2.EXAMPLE. A 1.2.3.2
+HOST-2.EXAMPLE. MX 0 .
+HOST-3.EXAMPLE. A 1.2.3.3
+HOST-3.EXAMPLE. MX 0 .
+...
+HOST-127.EXAMPLE. A 1.2.3.127
+HOST-127.EXAMPLE. MX 0 .
+</pre>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -7728,8 +8907,10 @@ $GENERATE 1-127 $ CNAME $.0</pre>
Available output forms are decimal
(<span><strong class="command">d</strong></span>), octal
- (<span><strong class="command">o</strong></span>) and hexadecimal
+ (<span><strong class="command">o</strong></span>), hexadecimal
(<span><strong class="command">x</strong></span> or <span><strong class="command">X</strong></span>
+ for uppercase) and nibble
+ (<span><strong class="command">n</strong></span> or <span><strong class="command">N</strong></span>\
for uppercase). The default modifier is
<span><strong class="command">${0,0,d}</strong></span>. If the
<span><strong class="command">lhs</strong></span> is not absolute, the
@@ -7737,8 +8918,16 @@ $GENERATE 1-127 $ CNAME $.0</pre>
to the name.
</p>
<p>
- For compatibility with earlier versions, <span><strong class="command">$$</strong></span> is still
- recognized as indicating a literal $ in the output.
+ In nibble mode the value will be treated as
+ if it was a reversed hexadecimal string
+ with each hexadecimal digit as a separate
+ label. The width field includes the label
+ separator.
+ </p>
+ <p>
+ For compatibility with earlier versions,
+ <span><strong class="command">$$</strong></span> is still recognized as
+ indicating a literal $ in the output.
</p>
</td>
</tr>
@@ -7780,8 +8969,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</td>
<td>
<p>
- At present the only supported types are
- PTR, CNAME, DNAME, A, AAAA and NS.
+ Any valid type.
</p>
</td>
</tr>
@@ -7791,8 +8979,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</td>
<td>
<p>
- <span><strong class="command">rhs</strong></span> is a domain name. It is processed
- similarly to lhs.
+ <span><strong class="command">rhs</strong></span>, optionally, quoted string.
</p>
</td>
</tr>
@@ -7942,9 +9129,12 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</td>
<td>
<p>
- The number of RRsets per RR type (positive
- or negative) and nonexistent names stored in the
- cache database.
+ The number of RRsets per RR type and nonexistent
+ names stored in the cache database.
+ If the exclamation mark (!) is printed for a RR
+ type, it means that particular type of RRset is
+ known to be nonexistent (this is also known as
+ "NXRRSET").
Maintained per view.
</p>
</td>
@@ -8037,7 +9227,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2595458"></a>Name Server Statistics Counters</h4></div></div></div>
+<a name="id2598928"></a>Name Server Statistics Counters</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -8594,7 +9784,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2596931"></a>Zone Maintenance Statistics Counters</h4></div></div></div>
+<a name="id2600401"></a>Zone Maintenance Statistics Counters</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -8748,7 +9938,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2597314"></a>Resolver Statistics Counters</h4></div></div></div>
+<a name="id2600852"></a>Resolver Statistics Counters</h4></div></div></div>
<div class="informaltable"><table border="1">
<colgroup>
<col>
@@ -8900,6 +10090,13 @@ $GENERATE 1-127 $ CNAME $.0</pre>
<td>
<p>
Mismatch responses received.
+ The DNS ID, response's source address,
+ and/or the response's source port does not
+ match what was expected.
+ (The port must be 53 or as defined by
+ the <span><strong class="command">port</strong></span> option.)
+ This may be an indication of a cache
+ poisoning attempt.
</p>
</td>
</tr>
@@ -9124,7 +10321,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2598332"></a>Socket I/O Statistics Counters</h4></div></div></div>
+<a name="id2601942"></a>Socket I/O Statistics Counters</h4></div></div></div>
<p>
Socket I/O statistics counters are defined per socket
types, which are
@@ -9279,7 +10476,7 @@ $GENERATE 1-127 $ CNAME $.0</pre>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2598842"></a>Compatibility with <span class="emphasis"><em>BIND</em></span> 8 Counters</h4></div></div></div>
+<a name="id2602384"></a>Compatibility with <span class="emphasis"><em>BIND</em></span> 8 Counters</h4></div></div></div>
<p>
Most statistics counters that were available
in <span><strong class="command">BIND</strong></span> 8 are also supported in
diff --git a/doc/arm/Bv9ARM.ch07.html b/doc/arm/Bv9ARM.ch07.html
index ce23cadf3b32..371f4a94eca5 100644
--- a/doc/arm/Bv9ARM.ch07.html
+++ b/doc/arm/Bv9ARM.ch07.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch07.html,v 1.178.14.15 2010-08-20 02:05:39 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch07.html,v 1.242.8.1.2.1 2011-06-09 03:41:08 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -46,10 +46,10 @@
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#Access_Control_Lists">Access Control Lists</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2599016"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2602626"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599234">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599362">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2602707">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2602766">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#dynamic_update_security">Dynamic Update Security</a></span></dt>
</dl>
@@ -80,14 +80,17 @@
Here is an example of how to properly apply ACLs:
</p>
<pre class="programlisting">
-// Set up an ACL named "bogusnets" that will block RFC1918 space
-// and some reserved space, which is commonly used in spoofing attacks.
+// Set up an ACL named "bogusnets" that will block
+// RFC1918 space and some reserved space, which is
+// commonly used in spoofing attacks.
acl bogusnets {
- 0.0.0.0/8; 1.0.0.0/8; 2.0.0.0/8; 192.0.2.0/24; 224.0.0.0/3;
- 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;
+ 0.0.0.0/8; 1.0.0.0/8; 2.0.0.0/8; 192.0.2.0/24;
+ 224.0.0.0/3; 10.0.0.0/8; 172.16.0.0/12;
+ 192.168.0.0/16;
};
-// Set up an ACL called our-nets. Replace this with the real IP numbers.
+// Set up an ACL called our-nets. Replace this with the
+// real IP numbers.
acl our-nets { x.x.x.x/24; x.x.x.x/21; };
options {
...
@@ -119,7 +122,7 @@ zone "example.com" {
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599016"></a><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span>
+<a name="id2602626"></a><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span>
</h2></div></div></div>
<p>
On UNIX servers, it is possible to run <acronym class="acronym">BIND</acronym>
@@ -145,7 +148,7 @@ zone "example.com" {
</p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2599234"></a>The <span><strong class="command">chroot</strong></span> Environment</h3></div></div></div>
+<a name="id2602707"></a>The <span><strong class="command">chroot</strong></span> Environment</h3></div></div></div>
<p>
In order for a <span><strong class="command">chroot</strong></span> environment
to
@@ -173,7 +176,7 @@ zone "example.com" {
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2599362"></a>Using the <span><strong class="command">setuid</strong></span> Function</h3></div></div></div>
+<a name="id2602766"></a>Using the <span><strong class="command">setuid</strong></span> Function</h3></div></div></div>
<p>
Prior to running the <span><strong class="command">named</strong></span> daemon,
use
diff --git a/doc/arm/Bv9ARM.ch08.html b/doc/arm/Bv9ARM.ch08.html
index bb9ecc84c645..0681e47ce1e5 100644
--- a/doc/arm/Bv9ARM.ch08.html
+++ b/doc/arm/Bv9ARM.ch08.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch08.html,v 1.178.14.15 2010-08-20 02:05:39 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch08.html,v 1.242.8.1.2.1 2011-06-09 03:41:08 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,18 +45,18 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599442">Common Problems</a></span></dt>
-<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2599447">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599459">Incrementing and Changing the Serial Number</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599476">Where Can I Get Help?</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2602915">Common Problems</a></span></dt>
+<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2602920">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2602932">Incrementing and Changing the Serial Number</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2602949">Where Can I Get Help?</a></span></dt>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599442"></a>Common Problems</h2></div></div></div>
+<a name="id2602915"></a>Common Problems</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2599447"></a>It's not working; how can I figure out what's wrong?</h3></div></div></div>
+<a name="id2602920"></a>It's not working; how can I figure out what's wrong?</h3></div></div></div>
<p>
The best solution to solving installation and
configuration issues is to take preventative measures by setting
@@ -68,7 +68,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599459"></a>Incrementing and Changing the Serial Number</h2></div></div></div>
+<a name="id2602932"></a>Incrementing and Changing the Serial Number</h2></div></div></div>
<p>
Zone serial numbers are just numbers &#8212; they aren't
date related. A lot of people set them to a number that
@@ -95,7 +95,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599476"></a>Where Can I Get Help?</h2></div></div></div>
+<a name="id2602949"></a>Where Can I Get Help?</h2></div></div></div>
<p>
The Internet Systems Consortium
(<acronym class="acronym">ISC</acronym>) offers a wide range
diff --git a/doc/arm/Bv9ARM.ch09.html b/doc/arm/Bv9ARM.ch09.html
index c5bd994e0bee..fd532377bad5 100644
--- a/doc/arm/Bv9ARM.ch09.html
+++ b/doc/arm/Bv9ARM.ch09.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch09.html,v 1.180.16.16 2010-08-20 02:05:38 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch09.html,v 1.246.8.1.2.1 2011-06-09 03:41:08 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -45,21 +45,31 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599606">Acknowledgments</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2603147">Acknowledgments</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#historical_dns_information">A Brief History of the <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599778">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2603319">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#ipv6addresses">IPv6 addresses (AAAA)</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch09.html#bibliography">Bibliography (and Suggested Reading)</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#rfcs">Request for Comments (RFCs)</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#internet_drafts">Internet Drafts</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2603126">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2606462">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#bind9.library">BIND 9 DNS Library Support</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608789">Prerequisite</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608798">Compilation</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608004">Installation</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608035">Known Defects/Restrictions</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608112">The dns.conf File</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608138">Sample Applications</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2609111">Library References</a></span></dt>
</dl></dd>
</dl>
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599606"></a>Acknowledgments</h2></div></div></div>
+<a name="id2603147"></a>Acknowledgments</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="historical_dns_information"></a>A Brief History of the <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym>
@@ -162,7 +172,7 @@
</div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="id2599778"></a>General <acronym class="acronym">DNS</acronym> Reference Information</h2></div></div></div>
+<a name="id2603319"></a>General <acronym class="acronym">DNS</acronym> Reference Information</h2></div></div></div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="ipv6addresses"></a>IPv6 addresses (AAAA)</h3></div></div></div>
@@ -250,17 +260,17 @@
</p>
<div class="bibliography">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2599897"></a>Bibliography</h4></div></div></div>
+<a name="id2603507"></a>Bibliography</h4></div></div></div>
<div class="bibliodiv">
<h3 class="title">Standards</h3>
<div class="biblioentry">
-<a name="id2599908"></a><p>[<abbr class="abbrev">RFC974</abbr>] <span class="author"><span class="firstname">C.</span> <span class="surname">Partridge</span>. </span><span class="title"><i>Mail Routing and the Domain System</i>. </span><span class="pubdate">January 1986. </span></p>
+<a name="id2603517"></a><p>[<abbr class="abbrev">RFC974</abbr>] <span class="author"><span class="firstname">C.</span> <span class="surname">Partridge</span>. </span><span class="title"><i>Mail Routing and the Domain System</i>. </span><span class="pubdate">January 1986. </span></p>
</div>
<div class="biblioentry">
-<a name="id2599931"></a><p>[<abbr class="abbrev">RFC1034</abbr>] <span class="author"><span class="firstname">P.V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Concepts and Facilities</i>. </span><span class="pubdate">November 1987. </span></p>
+<a name="id2603541"></a><p>[<abbr class="abbrev">RFC1034</abbr>] <span class="author"><span class="firstname">P.V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Concepts and Facilities</i>. </span><span class="pubdate">November 1987. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600023"></a><p>[<abbr class="abbrev">RFC1035</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Implementation and
+<a name="id2603564"></a><p>[<abbr class="abbrev">RFC1035</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>Domain Names &#8212; Implementation and
Specification</i>. </span><span class="pubdate">November 1987. </span></p>
</div>
</div>
@@ -268,42 +278,42 @@
<h3 class="title">
<a name="proposed_standards"></a>Proposed Standards</h3>
<div class="biblioentry">
-<a name="id2600059"></a><p>[<abbr class="abbrev">RFC2181</abbr>] <span class="author"><span class="firstname">R., R. Bush</span> <span class="surname">Elz</span>. </span><span class="title"><i>Clarifications to the <acronym class="acronym">DNS</acronym>
+<a name="id2603601"></a><p>[<abbr class="abbrev">RFC2181</abbr>] <span class="author"><span class="firstname">R., R. Bush</span> <span class="surname">Elz</span>. </span><span class="title"><i>Clarifications to the <acronym class="acronym">DNS</acronym>
Specification</i>. </span><span class="pubdate">July 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600086"></a><p>[<abbr class="abbrev">RFC2308</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Andrews</span>. </span><span class="title"><i>Negative Caching of <acronym class="acronym">DNS</acronym>
+<a name="id2603627"></a><p>[<abbr class="abbrev">RFC2308</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Andrews</span>. </span><span class="title"><i>Negative Caching of <acronym class="acronym">DNS</acronym>
Queries</i>. </span><span class="pubdate">March 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600112"></a><p>[<abbr class="abbrev">RFC1995</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Ohta</span>. </span><span class="title"><i>Incremental Zone Transfer in <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">August 1996. </span></p>
+<a name="id2603653"></a><p>[<abbr class="abbrev">RFC1995</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Ohta</span>. </span><span class="title"><i>Incremental Zone Transfer in <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">August 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600136"></a><p>[<abbr class="abbrev">RFC1996</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A Mechanism for Prompt Notification of Zone Changes</i>. </span><span class="pubdate">August 1996. </span></p>
+<a name="id2603677"></a><p>[<abbr class="abbrev">RFC1996</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A Mechanism for Prompt Notification of Zone Changes</i>. </span><span class="pubdate">August 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600160"></a><p>[<abbr class="abbrev">RFC2136</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">Y.</span> <span class="surname">Rekhter</span>, and <span class="firstname">J.</span> <span class="surname">Bound</span>. </span><span class="title"><i>Dynamic Updates in the Domain Name System</i>. </span><span class="pubdate">April 1997. </span></p>
+<a name="id2603701"></a><p>[<abbr class="abbrev">RFC2136</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">Y.</span> <span class="surname">Rekhter</span>, and <span class="firstname">J.</span> <span class="surname">Bound</span>. </span><span class="title"><i>Dynamic Updates in the Domain Name System</i>. </span><span class="pubdate">April 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600215"></a><p>[<abbr class="abbrev">RFC2671</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Extension Mechanisms for DNS (EDNS0)</i>. </span><span class="pubdate">August 1997. </span></p>
+<a name="id2603756"></a><p>[<abbr class="abbrev">RFC2671</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Extension Mechanisms for DNS (EDNS0)</i>. </span><span class="pubdate">August 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600242"></a><p>[<abbr class="abbrev">RFC2672</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Non-Terminal DNS Name Redirection</i>. </span><span class="pubdate">August 1999. </span></p>
+<a name="id2603783"></a><p>[<abbr class="abbrev">RFC2672</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Non-Terminal DNS Name Redirection</i>. </span><span class="pubdate">August 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600268"></a><p>[<abbr class="abbrev">RFC2845</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>, <span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, and <span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secret Key Transaction Authentication for <acronym class="acronym">DNS</acronym> (TSIG)</i>. </span><span class="pubdate">May 2000. </span></p>
+<a name="id2603810"></a><p>[<abbr class="abbrev">RFC2845</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>, <span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, and <span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secret Key Transaction Authentication for <acronym class="acronym">DNS</acronym> (TSIG)</i>. </span><span class="pubdate">May 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600330"></a><p>[<abbr class="abbrev">RFC2930</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secret Key Establishment for DNS (TKEY RR)</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2603872"></a><p>[<abbr class="abbrev">RFC2930</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secret Key Establishment for DNS (TKEY RR)</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600360"></a><p>[<abbr class="abbrev">RFC2931</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DNS Request and Transaction Signatures (SIG(0)s)</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2603901"></a><p>[<abbr class="abbrev">RFC2931</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DNS Request and Transaction Signatures (SIG(0)s)</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600390"></a><p>[<abbr class="abbrev">RFC3007</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secure Domain Name System (DNS) Dynamic Update</i>. </span><span class="pubdate">November 2000. </span></p>
+<a name="id2603931"></a><p>[<abbr class="abbrev">RFC3007</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Secure Domain Name System (DNS) Dynamic Update</i>. </span><span class="pubdate">November 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600417"></a><p>[<abbr class="abbrev">RFC3645</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Kwan</span>, <span class="firstname">P.</span> <span class="surname">Garg</span>, <span class="firstname">J.</span> <span class="surname">Gilroy</span>, <span class="firstname">L.</span> <span class="surname">Esibov</span>, <span class="firstname">J.</span> <span class="surname">Westhead</span>, and <span class="firstname">R.</span> <span class="surname">Hall</span>. </span><span class="title"><i>Generic Security Service Algorithm for Secret
+<a name="id2603958"></a><p>[<abbr class="abbrev">RFC3645</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Kwan</span>, <span class="firstname">P.</span> <span class="surname">Garg</span>, <span class="firstname">J.</span> <span class="surname">Gilroy</span>, <span class="firstname">L.</span> <span class="surname">Esibov</span>, <span class="firstname">J.</span> <span class="surname">Westhead</span>, and <span class="firstname">R.</span> <span class="surname">Hall</span>. </span><span class="title"><i>Generic Security Service Algorithm for Secret
Key Transaction Authentication for DNS
(GSS-TSIG)</i>. </span><span class="pubdate">October 2003. </span></p>
</div>
@@ -312,19 +322,19 @@
<h3 class="title">
<acronym class="acronym">DNS</acronym> Security Proposed Standards</h3>
<div class="biblioentry">
-<a name="id2600499"></a><p>[<abbr class="abbrev">RFC3225</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Conrad</span>. </span><span class="title"><i>Indicating Resolver Support of DNSSEC</i>. </span><span class="pubdate">December 2001. </span></p>
+<a name="id2604040"></a><p>[<abbr class="abbrev">RFC3225</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Conrad</span>. </span><span class="title"><i>Indicating Resolver Support of DNSSEC</i>. </span><span class="pubdate">December 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600525"></a><p>[<abbr class="abbrev">RFC3833</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Atkins</span> and <span class="firstname">R.</span> <span class="surname">Austein</span>. </span><span class="title"><i>Threat Analysis of the Domain Name System (DNS)</i>. </span><span class="pubdate">August 2004. </span></p>
+<a name="id2604067"></a><p>[<abbr class="abbrev">RFC3833</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Atkins</span> and <span class="firstname">R.</span> <span class="surname">Austein</span>. </span><span class="title"><i>Threat Analysis of the Domain Name System (DNS)</i>. </span><span class="pubdate">August 2004. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600562"></a><p>[<abbr class="abbrev">RFC4033</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>DNS Security Introduction and Requirements</i>. </span><span class="pubdate">March 2005. </span></p>
+<a name="id2604103"></a><p>[<abbr class="abbrev">RFC4033</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>DNS Security Introduction and Requirements</i>. </span><span class="pubdate">March 2005. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600627"></a><p>[<abbr class="abbrev">RFC4034</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Resource Records for the DNS Security Extensions</i>. </span><span class="pubdate">March 2005. </span></p>
+<a name="id2604168"></a><p>[<abbr class="abbrev">RFC4034</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Resource Records for the DNS Security Extensions</i>. </span><span class="pubdate">March 2005. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600692"></a><p>[<abbr class="abbrev">RFC4035</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Protocol Modifications for the DNS
+<a name="id2604233"></a><p>[<abbr class="abbrev">RFC4035</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Arends</span>, <span class="firstname">R.</span> <span class="surname">Austein</span>, <span class="firstname">M.</span> <span class="surname">Larson</span>, <span class="firstname">D.</span> <span class="surname">Massey</span>, and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Protocol Modifications for the DNS
Security Extensions</i>. </span><span class="pubdate">March 2005. </span></p>
</div>
</div>
@@ -332,146 +342,146 @@
<h3 class="title">Other Important RFCs About <acronym class="acronym">DNS</acronym>
Implementation</h3>
<div class="biblioentry">
-<a name="id2600765"></a><p>[<abbr class="abbrev">RFC1535</abbr>] <span class="author"><span class="firstname">E.</span> <span class="surname">Gavron</span>. </span><span class="title"><i>A Security Problem and Proposed Correction With Widely
+<a name="id2604375"></a><p>[<abbr class="abbrev">RFC1535</abbr>] <span class="author"><span class="firstname">E.</span> <span class="surname">Gavron</span>. </span><span class="title"><i>A Security Problem and Proposed Correction With Widely
Deployed <acronym class="acronym">DNS</acronym> Software.</i>. </span><span class="pubdate">October 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600791"></a><p>[<abbr class="abbrev">RFC1536</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Kumar</span>, <span class="firstname">J.</span> <span class="surname">Postel</span>, <span class="firstname">C.</span> <span class="surname">Neuman</span>, <span class="firstname">P.</span> <span class="surname">Danzig</span>, and <span class="firstname">S.</span> <span class="surname">Miller</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Implementation
+<a name="id2604401"></a><p>[<abbr class="abbrev">RFC1536</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Kumar</span>, <span class="firstname">J.</span> <span class="surname">Postel</span>, <span class="firstname">C.</span> <span class="surname">Neuman</span>, <span class="firstname">P.</span> <span class="surname">Danzig</span>, and <span class="firstname">S.</span> <span class="surname">Miller</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Implementation
Errors and Suggested Fixes</i>. </span><span class="pubdate">October 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600859"></a><p>[<abbr class="abbrev">RFC1982</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Elz</span> and <span class="firstname">R.</span> <span class="surname">Bush</span>. </span><span class="title"><i>Serial Number Arithmetic</i>. </span><span class="pubdate">August 1996. </span></p>
+<a name="id2604469"></a><p>[<abbr class="abbrev">RFC1982</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Elz</span> and <span class="firstname">R.</span> <span class="surname">Bush</span>. </span><span class="title"><i>Serial Number Arithmetic</i>. </span><span class="pubdate">August 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600894"></a><p>[<abbr class="abbrev">RFC4074</abbr>] <span class="authorgroup"><span class="firstname">Y.</span> <span class="surname">Morishita</span> and <span class="firstname">T.</span> <span class="surname">Jinmei</span>. </span><span class="title"><i>Common Misbehaviour Against <acronym class="acronym">DNS</acronym>
+<a name="id2604504"></a><p>[<abbr class="abbrev">RFC4074</abbr>] <span class="authorgroup"><span class="firstname">Y.</span> <span class="surname">Morishita</span> and <span class="firstname">T.</span> <span class="surname">Jinmei</span>. </span><span class="title"><i>Common Misbehaviour Against <acronym class="acronym">DNS</acronym>
Queries for IPv6 Addresses</i>. </span><span class="pubdate">May 2005. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">Resource Record Types</h3>
<div class="biblioentry">
-<a name="id2600940"></a><p>[<abbr class="abbrev">RFC1183</abbr>] <span class="authorgroup"><span class="firstname">C.F.</span> <span class="surname">Everhart</span>, <span class="firstname">L. A.</span> <span class="surname">Mamakos</span>, <span class="firstname">R.</span> <span class="surname">Ullmann</span>, and <span class="firstname">P.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>New <acronym class="acronym">DNS</acronym> RR Definitions</i>. </span><span class="pubdate">October 1990. </span></p>
+<a name="id2604550"></a><p>[<abbr class="abbrev">RFC1183</abbr>] <span class="authorgroup"><span class="firstname">C.F.</span> <span class="surname">Everhart</span>, <span class="firstname">L. A.</span> <span class="surname">Mamakos</span>, <span class="firstname">R.</span> <span class="surname">Ullmann</span>, and <span class="firstname">P.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i>New <acronym class="acronym">DNS</acronym> RR Definitions</i>. </span><span class="pubdate">October 1990. </span></p>
</div>
<div class="biblioentry">
-<a name="id2600998"></a><p>[<abbr class="abbrev">RFC1706</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">R.</span> <span class="surname">Colella</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> NSAP Resource Records</i>. </span><span class="pubdate">October 1994. </span></p>
+<a name="id2604608"></a><p>[<abbr class="abbrev">RFC1706</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">R.</span> <span class="surname">Colella</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> NSAP Resource Records</i>. </span><span class="pubdate">October 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601035"></a><p>[<abbr class="abbrev">RFC2168</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Daniel</span> and <span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="title"><i>Resolution of Uniform Resource Identifiers using
+<a name="id2604645"></a><p>[<abbr class="abbrev">RFC2168</abbr>] <span class="authorgroup"><span class="firstname">R.</span> <span class="surname">Daniel</span> and <span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="title"><i>Resolution of Uniform Resource Identifiers using
the Domain Name System</i>. </span><span class="pubdate">June 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601070"></a><p>[<abbr class="abbrev">RFC1876</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Davis</span>, <span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">T.</span>, and <span class="firstname">I.</span> <span class="surname">Dickinson</span>. </span><span class="title"><i>A Means for Expressing Location Information in the
+<a name="id2604680"></a><p>[<abbr class="abbrev">RFC1876</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Davis</span>, <span class="firstname">P.</span> <span class="surname">Vixie</span>, <span class="firstname">T.</span>, and <span class="firstname">I.</span> <span class="surname">Dickinson</span>. </span><span class="title"><i>A Means for Expressing Location Information in the
Domain
Name System</i>. </span><span class="pubdate">January 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601125"></a><p>[<abbr class="abbrev">RFC2052</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A <acronym class="acronym">DNS</acronym> RR for Specifying the
+<a name="id2604734"></a><p>[<abbr class="abbrev">RFC2052</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>A <acronym class="acronym">DNS</acronym> RR for Specifying the
Location of
Services.</i>. </span><span class="pubdate">October 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601163"></a><p>[<abbr class="abbrev">RFC2163</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Allocchio</span>. </span><span class="title"><i>Using the Internet <acronym class="acronym">DNS</acronym> to
+<a name="id2604773"></a><p>[<abbr class="abbrev">RFC2163</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Allocchio</span>. </span><span class="title"><i>Using the Internet <acronym class="acronym">DNS</acronym> to
Distribute MIXER
Conformant Global Address Mapping</i>. </span><span class="pubdate">January 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601189"></a><p>[<abbr class="abbrev">RFC2230</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Atkinson</span>. </span><span class="title"><i>Key Exchange Delegation Record for the <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">October 1997. </span></p>
+<a name="id2604798"></a><p>[<abbr class="abbrev">RFC2230</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Atkinson</span>. </span><span class="title"><i>Key Exchange Delegation Record for the <acronym class="acronym">DNS</acronym></i>. </span><span class="pubdate">October 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601214"></a><p>[<abbr class="abbrev">RFC2536</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DSA KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2604824"></a><p>[<abbr class="abbrev">RFC2536</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>DSA KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601241"></a><p>[<abbr class="abbrev">RFC2537</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/MD5 KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2604851"></a><p>[<abbr class="abbrev">RFC2537</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/MD5 KEYs and SIGs in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601268"></a><p>[<abbr class="abbrev">RFC2538</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Storing Certificates in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2604877"></a><p>[<abbr class="abbrev">RFC2538</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Storing Certificates in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601307"></a><p>[<abbr class="abbrev">RFC2539</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Storage of Diffie-Hellman Keys in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2604917"></a><p>[<abbr class="abbrev">RFC2539</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Storage of Diffie-Hellman Keys in the Domain Name System (DNS)</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601337"></a><p>[<abbr class="abbrev">RFC2540</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Detached Domain Name System (DNS) Information</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2604947"></a><p>[<abbr class="abbrev">RFC2540</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Detached Domain Name System (DNS) Information</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601367"></a><p>[<abbr class="abbrev">RFC2782</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span>. </span><span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="author"><span class="firstname">L.</span> <span class="surname">Esibov</span>. </span><span class="title"><i>A DNS RR for specifying the location of services (DNS SRV)</i>. </span><span class="pubdate">February 2000. </span></p>
+<a name="id2604977"></a><p>[<abbr class="abbrev">RFC2782</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gulbrandsen</span>. </span><span class="author"><span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="author"><span class="firstname">L.</span> <span class="surname">Esibov</span>. </span><span class="title"><i>A DNS RR for specifying the location of services (DNS SRV)</i>. </span><span class="pubdate">February 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601410"></a><p>[<abbr class="abbrev">RFC2915</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="author"><span class="firstname">R.</span> <span class="surname">Daniel</span>. </span><span class="title"><i>The Naming Authority Pointer (NAPTR) DNS Resource Record</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2605019"></a><p>[<abbr class="abbrev">RFC2915</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Mealling</span>. </span><span class="author"><span class="firstname">R.</span> <span class="surname">Daniel</span>. </span><span class="title"><i>The Naming Authority Pointer (NAPTR) DNS Resource Record</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601443"></a><p>[<abbr class="abbrev">RFC3110</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</i>. </span><span class="pubdate">May 2001. </span></p>
+<a name="id2605052"></a><p>[<abbr class="abbrev">RFC3110</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>RSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)</i>. </span><span class="pubdate">May 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601469"></a><p>[<abbr class="abbrev">RFC3123</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Koch</span>. </span><span class="title"><i>A DNS RR Type for Lists of Address Prefixes (APL RR)</i>. </span><span class="pubdate">June 2001. </span></p>
+<a name="id2605079"></a><p>[<abbr class="abbrev">RFC3123</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Koch</span>. </span><span class="title"><i>A DNS RR Type for Lists of Address Prefixes (APL RR)</i>. </span><span class="pubdate">June 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601493"></a><p>[<abbr class="abbrev">RFC3596</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">C.</span> <span class="surname">Huitema</span>, <span class="firstname">V.</span> <span class="surname">Ksinant</span>, and <span class="firstname">M.</span> <span class="surname">Souissi</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Extensions to support IP
+<a name="id2605102"></a><p>[<abbr class="abbrev">RFC3596</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Thomson</span>, <span class="firstname">C.</span> <span class="surname">Huitema</span>, <span class="firstname">V.</span> <span class="surname">Ksinant</span>, and <span class="firstname">M.</span> <span class="surname">Souissi</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Extensions to support IP
version 6</i>. </span><span class="pubdate">October 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601619"></a><p>[<abbr class="abbrev">RFC3597</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gustafsson</span>. </span><span class="title"><i>Handling of Unknown DNS Resource Record (RR) Types</i>. </span><span class="pubdate">September 2003. </span></p>
+<a name="id2605160"></a><p>[<abbr class="abbrev">RFC3597</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Gustafsson</span>. </span><span class="title"><i>Handling of Unknown DNS Resource Record (RR) Types</i>. </span><span class="pubdate">September 2003. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">
<acronym class="acronym">DNS</acronym> and the Internet</h3>
<div class="biblioentry">
-<a name="id2601651"></a><p>[<abbr class="abbrev">RFC1101</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Network Names
+<a name="id2605192"></a><p>[<abbr class="abbrev">RFC1101</abbr>] <span class="author"><span class="firstname">P. V.</span> <span class="surname">Mockapetris</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Network Names
and Other Types</i>. </span><span class="pubdate">April 1989. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601676"></a><p>[<abbr class="abbrev">RFC1123</abbr>] <span class="author"><span class="surname">Braden</span>. </span><span class="title"><i>Requirements for Internet Hosts - Application and
+<a name="id2605218"></a><p>[<abbr class="abbrev">RFC1123</abbr>] <span class="author"><span class="surname">Braden</span>. </span><span class="title"><i>Requirements for Internet Hosts - Application and
Support</i>. </span><span class="pubdate">October 1989. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601699"></a><p>[<abbr class="abbrev">RFC1591</abbr>] <span class="author"><span class="firstname">J.</span> <span class="surname">Postel</span>. </span><span class="title"><i>Domain Name System Structure and Delegation</i>. </span><span class="pubdate">March 1994. </span></p>
+<a name="id2605240"></a><p>[<abbr class="abbrev">RFC1591</abbr>] <span class="author"><span class="firstname">J.</span> <span class="surname">Postel</span>. </span><span class="title"><i>Domain Name System Structure and Delegation</i>. </span><span class="pubdate">March 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601790"></a><p>[<abbr class="abbrev">RFC2317</abbr>] <span class="authorgroup"><span class="firstname">H.</span> <span class="surname">Eidnes</span>, <span class="firstname">G.</span> <span class="surname">de Groot</span>, and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Classless IN-ADDR.ARPA Delegation</i>. </span><span class="pubdate">March 1998. </span></p>
+<a name="id2605264"></a><p>[<abbr class="abbrev">RFC2317</abbr>] <span class="authorgroup"><span class="firstname">H.</span> <span class="surname">Eidnes</span>, <span class="firstname">G.</span> <span class="surname">de Groot</span>, and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Classless IN-ADDR.ARPA Delegation</i>. </span><span class="pubdate">March 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601836"></a><p>[<abbr class="abbrev">RFC2826</abbr>] <span class="authorgroup"><span class="surname">Internet Architecture Board</span>. </span><span class="title"><i>IAB Technical Comment on the Unique DNS Root</i>. </span><span class="pubdate">May 2000. </span></p>
+<a name="id2605309"></a><p>[<abbr class="abbrev">RFC2826</abbr>] <span class="authorgroup"><span class="surname">Internet Architecture Board</span>. </span><span class="title"><i>IAB Technical Comment on the Unique DNS Root</i>. </span><span class="pubdate">May 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601860"></a><p>[<abbr class="abbrev">RFC2929</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, <span class="firstname">E.</span> <span class="surname">Brunner-Williams</span>, and <span class="firstname">B.</span> <span class="surname">Manning</span>. </span><span class="title"><i>Domain Name System (DNS) IANA Considerations</i>. </span><span class="pubdate">September 2000. </span></p>
+<a name="id2605333"></a><p>[<abbr class="abbrev">RFC2929</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>, <span class="firstname">E.</span> <span class="surname">Brunner-Williams</span>, and <span class="firstname">B.</span> <span class="surname">Manning</span>. </span><span class="title"><i>Domain Name System (DNS) IANA Considerations</i>. </span><span class="pubdate">September 2000. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">
<acronym class="acronym">DNS</acronym> Operations</h3>
<div class="biblioentry">
-<a name="id2601917"></a><p>[<abbr class="abbrev">RFC1033</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Lottor</span>. </span><span class="title"><i>Domain administrators operations guide.</i>. </span><span class="pubdate">November 1987. </span></p>
+<a name="id2605390"></a><p>[<abbr class="abbrev">RFC1033</abbr>] <span class="author"><span class="firstname">M.</span> <span class="surname">Lottor</span>. </span><span class="title"><i>Domain administrators operations guide.</i>. </span><span class="pubdate">November 1987. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601941"></a><p>[<abbr class="abbrev">RFC1537</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Beertema</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Data File
+<a name="id2605414"></a><p>[<abbr class="abbrev">RFC1537</abbr>] <span class="author"><span class="firstname">P.</span> <span class="surname">Beertema</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Data File
Configuration Errors</i>. </span><span class="pubdate">October 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601968"></a><p>[<abbr class="abbrev">RFC1912</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Barr</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Operational and
+<a name="id2605441"></a><p>[<abbr class="abbrev">RFC1912</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Barr</span>. </span><span class="title"><i>Common <acronym class="acronym">DNS</acronym> Operational and
Configuration Errors</i>. </span><span class="pubdate">February 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2601994"></a><p>[<abbr class="abbrev">RFC2010</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Operational Criteria for Root Name Servers.</i>. </span><span class="pubdate">October 1996. </span></p>
+<a name="id2605467"></a><p>[<abbr class="abbrev">RFC2010</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Manning</span> and <span class="firstname">P.</span> <span class="surname">Vixie</span>. </span><span class="title"><i>Operational Criteria for Root Name Servers.</i>. </span><span class="pubdate">October 1996. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602030"></a><p>[<abbr class="abbrev">RFC2219</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Hamilton</span> and <span class="firstname">R.</span> <span class="surname">Wright</span>. </span><span class="title"><i>Use of <acronym class="acronym">DNS</acronym> Aliases for
+<a name="id2605504"></a><p>[<abbr class="abbrev">RFC2219</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Hamilton</span> and <span class="firstname">R.</span> <span class="surname">Wright</span>. </span><span class="title"><i>Use of <acronym class="acronym">DNS</acronym> Aliases for
Network Services.</i>. </span><span class="pubdate">October 1997. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">Internationalized Domain Names</h3>
<div class="biblioentry">
-<a name="id2602076"></a><p>[<abbr class="abbrev">RFC2825</abbr>] <span class="authorgroup"><span class="surname">IAB</span> and <span class="firstname">R.</span> <span class="surname">Daigle</span>. </span><span class="title"><i>A Tangled Web: Issues of I18N, Domain Names,
+<a name="id2605549"></a><p>[<abbr class="abbrev">RFC2825</abbr>] <span class="authorgroup"><span class="surname">IAB</span> and <span class="firstname">R.</span> <span class="surname">Daigle</span>. </span><span class="title"><i>A Tangled Web: Issues of I18N, Domain Names,
and the Other Internet protocols</i>. </span><span class="pubdate">May 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602108"></a><p>[<abbr class="abbrev">RFC3490</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Faltstrom</span>, <span class="firstname">P.</span> <span class="surname">Hoffman</span>, and <span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Internationalizing Domain Names in Applications (IDNA)</i>. </span><span class="pubdate">March 2003. </span></p>
+<a name="id2605581"></a><p>[<abbr class="abbrev">RFC3490</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Faltstrom</span>, <span class="firstname">P.</span> <span class="surname">Hoffman</span>, and <span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Internationalizing Domain Names in Applications (IDNA)</i>. </span><span class="pubdate">March 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602154"></a><p>[<abbr class="abbrev">RFC3491</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Hoffman</span> and <span class="firstname">M.</span> <span class="surname">Blanchet</span>. </span><span class="title"><i>Nameprep: A Stringprep Profile for Internationalized Domain Names</i>. </span><span class="pubdate">March 2003. </span></p>
+<a name="id2605627"></a><p>[<abbr class="abbrev">RFC3491</abbr>] <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Hoffman</span> and <span class="firstname">M.</span> <span class="surname">Blanchet</span>. </span><span class="title"><i>Nameprep: A Stringprep Profile for Internationalized Domain Names</i>. </span><span class="pubdate">March 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602189"></a><p>[<abbr class="abbrev">RFC3492</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Punycode: A Bootstring encoding of Unicode
+<a name="id2605662"></a><p>[<abbr class="abbrev">RFC3492</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Costello</span>. </span><span class="title"><i>Punycode: A Bootstring encoding of Unicode
for Internationalized Domain Names in
Applications (IDNA)</i>. </span><span class="pubdate">March 2003. </span></p>
</div>
@@ -487,47 +497,47 @@
</p>
</div>
<div class="biblioentry">
-<a name="id2602234"></a><p>[<abbr class="abbrev">RFC1464</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Rosenbaum</span>. </span><span class="title"><i>Using the Domain Name System To Store Arbitrary String
+<a name="id2605707"></a><p>[<abbr class="abbrev">RFC1464</abbr>] <span class="author"><span class="firstname">R.</span> <span class="surname">Rosenbaum</span>. </span><span class="title"><i>Using the Domain Name System To Store Arbitrary String
Attributes</i>. </span><span class="pubdate">May 1993. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602257"></a><p>[<abbr class="abbrev">RFC1713</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Romao</span>. </span><span class="title"><i>Tools for <acronym class="acronym">DNS</acronym> Debugging</i>. </span><span class="pubdate">November 1994. </span></p>
+<a name="id2605730"></a><p>[<abbr class="abbrev">RFC1713</abbr>] <span class="author"><span class="firstname">A.</span> <span class="surname">Romao</span>. </span><span class="title"><i>Tools for <acronym class="acronym">DNS</acronym> Debugging</i>. </span><span class="pubdate">November 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602282"></a><p>[<abbr class="abbrev">RFC1794</abbr>] <span class="author"><span class="firstname">T.</span> <span class="surname">Brisco</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Support for Load
+<a name="id2605755"></a><p>[<abbr class="abbrev">RFC1794</abbr>] <span class="author"><span class="firstname">T.</span> <span class="surname">Brisco</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Support for Load
Balancing</i>. </span><span class="pubdate">April 1995. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602308"></a><p>[<abbr class="abbrev">RFC2240</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Legal Basis for Domain Name Allocation</i>. </span><span class="pubdate">November 1997. </span></p>
+<a name="id2605781"></a><p>[<abbr class="abbrev">RFC2240</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Legal Basis for Domain Name Allocation</i>. </span><span class="pubdate">November 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602331"></a><p>[<abbr class="abbrev">RFC2345</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>, <span class="firstname">T.</span> <span class="surname">Wolf</span>, and <span class="firstname">G.</span> <span class="surname">Oglesby</span>. </span><span class="title"><i>Domain Names and Company Name Retrieval</i>. </span><span class="pubdate">May 1998. </span></p>
+<a name="id2605804"></a><p>[<abbr class="abbrev">RFC2345</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>, <span class="firstname">T.</span> <span class="surname">Wolf</span>, and <span class="firstname">G.</span> <span class="surname">Oglesby</span>. </span><span class="title"><i>Domain Names and Company Name Retrieval</i>. </span><span class="pubdate">May 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602377"></a><p>[<abbr class="abbrev">RFC2352</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Convention For Using Legal Names as Domain Names</i>. </span><span class="pubdate">May 1998. </span></p>
+<a name="id2605850"></a><p>[<abbr class="abbrev">RFC2352</abbr>] <span class="author"><span class="firstname">O.</span> <span class="surname">Vaughan</span>. </span><span class="title"><i>A Convention For Using Legal Names as Domain Names</i>. </span><span class="pubdate">May 1998. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602401"></a><p>[<abbr class="abbrev">RFC3071</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>. </span><span class="title"><i>Reflections on the DNS, RFC 1591, and Categories of Domains</i>. </span><span class="pubdate">February 2001. </span></p>
+<a name="id2605874"></a><p>[<abbr class="abbrev">RFC3071</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Klensin</span>. </span><span class="title"><i>Reflections on the DNS, RFC 1591, and Categories of Domains</i>. </span><span class="pubdate">February 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602427"></a><p>[<abbr class="abbrev">RFC3258</abbr>] <span class="authorgroup"><span class="firstname">T.</span> <span class="surname">Hardie</span>. </span><span class="title"><i>Distributing Authoritative Name Servers via
+<a name="id2605900"></a><p>[<abbr class="abbrev">RFC3258</abbr>] <span class="authorgroup"><span class="firstname">T.</span> <span class="surname">Hardie</span>. </span><span class="title"><i>Distributing Authoritative Name Servers via
Shared Unicast Addresses</i>. </span><span class="pubdate">April 2002. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602453"></a><p>[<abbr class="abbrev">RFC3901</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Durand</span> and <span class="firstname">J.</span> <span class="surname">Ihren</span>. </span><span class="title"><i>DNS IPv6 Transport Operational Guidelines</i>. </span><span class="pubdate">September 2004. </span></p>
+<a name="id2605926"></a><p>[<abbr class="abbrev">RFC3901</abbr>] <span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Durand</span> and <span class="firstname">J.</span> <span class="surname">Ihren</span>. </span><span class="title"><i>DNS IPv6 Transport Operational Guidelines</i>. </span><span class="pubdate">September 2004. </span></p>
</div>
</div>
<div class="bibliodiv">
<h3 class="title">Obsolete and Unimplemented Experimental RFC</h3>
<div class="biblioentry">
-<a name="id2602497"></a><p>[<abbr class="abbrev">RFC1712</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Farrell</span>, <span class="firstname">M.</span> <span class="surname">Schulze</span>, <span class="firstname">S.</span> <span class="surname">Pleitner</span>, and <span class="firstname">D.</span> <span class="surname">Baldoni</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Geographical
+<a name="id2605970"></a><p>[<abbr class="abbrev">RFC1712</abbr>] <span class="authorgroup"><span class="firstname">C.</span> <span class="surname">Farrell</span>, <span class="firstname">M.</span> <span class="surname">Schulze</span>, <span class="firstname">S.</span> <span class="surname">Pleitner</span>, and <span class="firstname">D.</span> <span class="surname">Baldoni</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> Encoding of Geographical
Location</i>. </span><span class="pubdate">November 1994. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602554"></a><p>[<abbr class="abbrev">RFC2673</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Binary Labels in the Domain Name System</i>. </span><span class="pubdate">August 1999. </span></p>
+<a name="id2606027"></a><p>[<abbr class="abbrev">RFC2673</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span>. </span><span class="title"><i>Binary Labels in the Domain Name System</i>. </span><span class="pubdate">August 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602581"></a><p>[<abbr class="abbrev">RFC2874</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span> and <span class="firstname">C.</span> <span class="surname">Huitema</span>. </span><span class="title"><i>DNS Extensions to Support IPv6 Address Aggregation
+<a name="id2606054"></a><p>[<abbr class="abbrev">RFC2874</abbr>] <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Crawford</span> and <span class="firstname">C.</span> <span class="surname">Huitema</span>. </span><span class="title"><i>DNS Extensions to Support IPv6 Address Aggregation
and Renumbering</i>. </span><span class="pubdate">July 2000. </span></p>
</div>
</div>
@@ -541,39 +551,39 @@
</p>
</div>
<div class="biblioentry">
-<a name="id2602629"></a><p>[<abbr class="abbrev">RFC2065</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">C.</span> <span class="surname">Kaufman</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">January 1997. </span></p>
+<a name="id2606102"></a><p>[<abbr class="abbrev">RFC2065</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span> and <span class="firstname">C.</span> <span class="surname">Kaufman</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">January 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602737"></a><p>[<abbr class="abbrev">RFC2137</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secure Domain Name System Dynamic Update</i>. </span><span class="pubdate">April 1997. </span></p>
+<a name="id2606141"></a><p>[<abbr class="abbrev">RFC2137</abbr>] <span class="author"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Secure Domain Name System Dynamic Update</i>. </span><span class="pubdate">April 1997. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602763"></a><p>[<abbr class="abbrev">RFC2535</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">March 1999. </span></p>
+<a name="id2606168"></a><p>[<abbr class="abbrev">RFC2535</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Eastlake</span>, <span class="lineage">3rd</span>. </span><span class="title"><i>Domain Name System Security Extensions</i>. </span><span class="pubdate">March 1999. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602793"></a><p>[<abbr class="abbrev">RFC3008</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Domain Name System Security (DNSSEC)
+<a name="id2606198"></a><p>[<abbr class="abbrev">RFC3008</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span>. </span><span class="title"><i>Domain Name System Security (DNSSEC)
Signing Authority</i>. </span><span class="pubdate">November 2000. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602819"></a><p>[<abbr class="abbrev">RFC3090</abbr>] <span class="authorgroup"><span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>DNS Security Extension Clarification on Zone Status</i>. </span><span class="pubdate">March 2001. </span></p>
+<a name="id2606224"></a><p>[<abbr class="abbrev">RFC3090</abbr>] <span class="authorgroup"><span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>DNS Security Extension Clarification on Zone Status</i>. </span><span class="pubdate">March 2001. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602845"></a><p>[<abbr class="abbrev">RFC3445</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Massey</span> and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Limiting the Scope of the KEY Resource Record (RR)</i>. </span><span class="pubdate">December 2002. </span></p>
+<a name="id2606250"></a><p>[<abbr class="abbrev">RFC3445</abbr>] <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Massey</span> and <span class="firstname">S.</span> <span class="surname">Rose</span>. </span><span class="title"><i>Limiting the Scope of the KEY Resource Record (RR)</i>. </span><span class="pubdate">December 2002. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602950"></a><p>[<abbr class="abbrev">RFC3655</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Redefinition of DNS Authenticated Data (AD) bit</i>. </span><span class="pubdate">November 2003. </span></p>
+<a name="id2606286"></a><p>[<abbr class="abbrev">RFC3655</abbr>] <span class="authorgroup"><span class="firstname">B.</span> <span class="surname">Wellington</span> and <span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Redefinition of DNS Authenticated Data (AD) bit</i>. </span><span class="pubdate">November 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2602986"></a><p>[<abbr class="abbrev">RFC3658</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Delegation Signer (DS) Resource Record (RR)</i>. </span><span class="pubdate">December 2003. </span></p>
+<a name="id2606323"></a><p>[<abbr class="abbrev">RFC3658</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Gudmundsson</span>. </span><span class="title"><i>Delegation Signer (DS) Resource Record (RR)</i>. </span><span class="pubdate">December 2003. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603013"></a><p>[<abbr class="abbrev">RFC3755</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Weiler</span>. </span><span class="title"><i>Legacy Resolver Compatibility for Delegation Signer (DS)</i>. </span><span class="pubdate">May 2004. </span></p>
+<a name="id2606349"></a><p>[<abbr class="abbrev">RFC3755</abbr>] <span class="authorgroup"><span class="firstname">S.</span> <span class="surname">Weiler</span>. </span><span class="title"><i>Legacy Resolver Compatibility for Delegation Signer (DS)</i>. </span><span class="pubdate">May 2004. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603040"></a><p>[<abbr class="abbrev">RFC3757</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Kolkman</span>, <span class="firstname">J.</span> <span class="surname">Schlyter</span>, and <span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>Domain Name System KEY (DNSKEY) Resource Record
+<a name="id2606376"></a><p>[<abbr class="abbrev">RFC3757</abbr>] <span class="authorgroup"><span class="firstname">O.</span> <span class="surname">Kolkman</span>, <span class="firstname">J.</span> <span class="surname">Schlyter</span>, and <span class="firstname">E.</span> <span class="surname">Lewis</span>. </span><span class="title"><i>Domain Name System KEY (DNSKEY) Resource Record
(RR) Secure Entry Point (SEP) Flag</i>. </span><span class="pubdate">April 2004. </span></p>
</div>
<div class="biblioentry">
-<a name="id2603084"></a><p>[<abbr class="abbrev">RFC3845</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Schlyter</span>. </span><span class="title"><i>DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format</i>. </span><span class="pubdate">August 2004. </span></p>
+<a name="id2606421"></a><p>[<abbr class="abbrev">RFC3845</abbr>] <span class="authorgroup"><span class="firstname">J.</span> <span class="surname">Schlyter</span>. </span><span class="title"><i>DNS Security (DNSSEC) NextSECure (NSEC) RDATA Format</i>. </span><span class="pubdate">August 2004. </span></p>
</div>
</div>
</div>
@@ -594,16 +604,481 @@
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
-<a name="id2603126"></a>Other Documents About <acronym class="acronym">BIND</acronym>
+<a name="id2606462"></a>Other Documents About <acronym class="acronym">BIND</acronym>
</h3></div></div></div>
<p></p>
<div class="bibliography">
<div class="titlepage"><div><div><h4 class="title">
-<a name="id2603136"></a>Bibliography</h4></div></div></div>
+<a name="id2606472"></a>Bibliography</h4></div></div></div>
<div class="biblioentry">
-<a name="id2603138"></a><p><span class="authorgroup"><span class="firstname">Paul</span> <span class="surname">Albitz</span> and <span class="firstname">Cricket</span> <span class="surname">Liu</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></i>. </span><span class="copyright">Copyright © 1998 Sebastopol, CA: O'Reilly and Associates. </span></p>
+<a name="id2606474"></a><p><span class="authorgroup"><span class="firstname">Paul</span> <span class="surname">Albitz</span> and <span class="firstname">Cricket</span> <span class="surname">Liu</span>. </span><span class="title"><i><acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></i>. </span><span class="copyright">Copyright © 1998 Sebastopol, CA: O'Reilly and Associates. </span></p>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="bind9.library"></a>BIND 9 DNS Library Support</h2></div></div></div>
+<p>This version of BIND 9 "exports" its internal libraries so
+ that they can be used by third-party applications more easily (we
+ call them "export" libraries in this document). In addition to
+ all major DNS-related APIs BIND 9 is currently using, the export
+ libraries provide the following features:</p>
+<div class="itemizedlist"><ul type="disc">
+<li><p>The newly created "DNS client" module. This is a higher
+ level API that provides an interface to name resolution,
+ single DNS transaction with a particular server, and dynamic
+ update. Regarding name resolution, it supports advanced
+ features such as DNSSEC validation and caching. This module
+ supports both synchronous and asynchronous mode.</p></li>
+<li><p>The new "IRS" (Information Retrieval System) library.
+ It provides an interface to parse the traditional resolv.conf
+ file and more advanced, DNS-specific configuration file for
+ the rest of this package (see the description for the
+ dns.conf file below).</p></li>
+<li><p>As part of the IRS library, newly implemented standard
+ address-name mapping functions, getaddrinfo() and
+ getnameinfo(), are provided. They use the DNSSEC-aware
+ validating resolver backend, and could use other advanced
+ features of the BIND 9 libraries such as caching. The
+ getaddrinfo() function resolves both A and AAAA RRs
+ concurrently (when the address family is unspecified).</p></li>
+<li><p>An experimental framework to support other event
+ libraries than BIND 9's internal event task system.</p></li>
+</ul></div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2608789"></a>Prerequisite</h3></div></div></div>
+<p>GNU make is required to build the export libraries (other
+ part of BIND 9 can still be built with other types of make). In
+ the reminder of this document, "make" means GNU make. Note that
+ in some platforms you may need to invoke a different command name
+ than "make" (e.g. "gmake") to indicate it's GNU make.</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2608798"></a>Compilation</h3></div></div></div>
+<pre class="screen">
+$ <strong class="userinput"><code>./configure --enable-exportlib <em class="replaceable"><code>[other flags]</code></em></code></strong>
+$ <strong class="userinput"><code>make</code></strong>
+</pre>
+<p>
+ This will create (in addition to usual BIND 9 programs) and a
+ separate set of libraries under the lib/export directory. For
+ example, <code class="filename">lib/export/dns/libdns.a</code> is the archive file of the
+ export version of the BIND 9 DNS library. Sample application
+ programs using the libraries will also be built under the
+ lib/export/samples directory (see below).</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2608004"></a>Installation</h3></div></div></div>
+<pre class="screen">
+$ <strong class="userinput"><code>cd lib/export</code></strong>
+$ <strong class="userinput"><code>make install</code></strong>
+</pre>
+<p>
+ This will install library object files under the directory
+ specified by the --with-export-libdir configure option (default:
+ EPREFIX/lib/bind9), and header files under the directory
+ specified by the --with-export-includedir configure option
+ (default: PREFIX/include/bind9).
+ Root privilege is normally required.
+ "<span><strong class="command">make install</strong></span>" at the top directory will do the
+ same.
+ </p>
+<p>
+ To see how to build your own
+ application after the installation, see
+ <code class="filename">lib/export/samples/Makefile-postinstall.in</code>.</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2608035"></a>Known Defects/Restrictions</h3></div></div></div>
+<div class="itemizedlist"><ul type="disc">
+<li><p>Currently, win32 is not supported for the export
+ library. (Normal BIND 9 application can be built as
+ before).</p></li>
+<li>
+<p>The "fixed" RRset order is not (currently) supported in
+ the export library. If you want to use "fixed" RRset order
+ for, e.g. <span><strong class="command">named</strong></span> while still building the
+ export library even without the fixed order support, build
+ them separately:
+ </p>
+<pre class="screen">
+$ <strong class="userinput"><code>./configure --enable-fixed-rrset <em class="replaceable"><code>[other flags, but not --enable-exportlib]</code></em></code></strong>
+$ <strong class="userinput"><code>make</code></strong>
+$ <strong class="userinput"><code>./configure --enable-exportlib <em class="replaceable"><code>[other flags, but not --enable-fixed-rrset]</code></em></code></strong>
+$ <strong class="userinput"><code>cd lib/export</code></strong>
+$ <strong class="userinput"><code>make</code></strong>
+</pre>
+<p>
+ </p>
+</li>
+<li><p>The client module and the IRS library currently do not
+ support DNSSEC validation using DLV (the underlying modules
+ can handle it, but there is no tunable interface to enable
+ the feature).</p></li>
+<li><p>RFC 5011 is not supported in the validating stub
+ resolver of the export library. In fact, it is not clear
+ whether it should: trust anchors would be a system-wide
+ configuration which would be managed by an administrator,
+ while the stub resolver will be used by ordinary applications
+ run by a normal user.</p></li>
+<li><p>Not all common <code class="filename">/etc/resolv.conf</code>
+ options are supported
+ in the IRS library. The only available options in this
+ version are "debug" and "ndots".</p></li>
+</ul></div>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2608112"></a>The dns.conf File</h3></div></div></div>
+<p>The IRS library supports an "advanced" configuration file
+ related to the DNS library for configuration parameters that
+ would be beyond the capability of the
+ <code class="filename">resolv.conf</code> file.
+ Specifically, it is intended to provide DNSSEC related
+ configuration parameters. By default the path to this
+ configuration file is <code class="filename">/etc/dns.conf</code>.
+ This module is very
+ experimental and the configuration syntax or library interfaces
+ may change in future versions. Currently, only the
+ <span><strong class="command">trusted-keys</strong></span>
+ statement is supported, whose syntax is the same as the same name
+ of statement for <code class="filename">named.conf</code>. (See
+ <a href="Bv9ARM.ch06.html#trusted-keys" title="trusted-keys Statement Grammar">the section called &#8220;<span><strong class="command">trusted-keys</strong></span> Statement Grammar&#8221;</a> for details.)</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2608138"></a>Sample Applications</h3></div></div></div>
+<p>Some sample application programs using this API are
+ provided for reference. The following is a brief description of
+ these applications.
+ </p>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2608147"></a>sample: a simple stub resolver utility</h4></div></div></div>
+<p>
+ It sends a query of a given name (of a given optional RR type) to a
+ specified recursive server, and prints the result as a list of
+ RRs. It can also act as a validating stub resolver if a trust
+ anchor is given via a set of command line options.</p>
+<p>
+ Usage: sample [options] server_address hostname
+ </p>
+<p>
+ Options and Arguments:
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">
+ -t RRtype
+ </span></dt>
+<dd><p>
+ specify the RR type of the query. The default is the A RR.
+ </p></dd>
+<dt><span class="term">
+ [-a algorithm] [-e] -k keyname -K keystring
+ </span></dt>
+<dd>
+<p>
+ specify a command-line DNS key to validate the answer. For
+ example, to specify the following DNSKEY of example.com:
+</p>
+<div class="literallayout"><p><br>
+                example.com. 3600 IN DNSKEY 257 3 5 xxx<br>
+</p></div>
+<p>
+ specify the options as follows:
+</p>
+<pre class="screen">
+<strong class="userinput"><code>
+ -e -k example.com -K "xxx"
+</code></strong>
+</pre>
+<p>
+ -e means that this key is a zone's "key signing key" (as known
+ as "secure Entry point").
+ When -a is omitted rsasha1 will be used by default.
+ </p>
+</dd>
+<dt><span class="term">
+ -s domain:alt_server_address
+ </span></dt>
+<dd><p>
+ specify a separate recursive server address for the specific
+ "domain". Example: -s example.com:2001:db8::1234
+ </p></dd>
+<dt><span class="term">server_address</span></dt>
+<dd><p>
+ an IP(v4/v6) address of the recursive server to which queries
+ are sent.
+ </p></dd>
+<dt><span class="term">hostname</span></dt>
+<dd><p>
+ the domain name for the query
+ </p></dd>
+</dl></div>
+</div>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2608237"></a>sample-async: a simple stub resolver, working asynchronously</h4></div></div></div>
+<p>
+ Similar to "sample", but accepts a list
+ of (query) domain names as a separate file and resolves the names
+ asynchronously.</p>
+<p>
+ Usage: sample-async [-s server_address] [-t RR_type] input_file</p>
+<p>
+ Options and Arguments:
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">
+ -s server_address
+ </span></dt>
+<dd>
+ an IPv4 address of the recursive server to which queries are sent.
+ (IPv6 addresses are not supported in this implementation)
+ </dd>
+<dt><span class="term">
+ -t RR_type
+ </span></dt>
+<dd>
+ specify the RR type of the queries. The default is the A
+ RR.
+ </dd>
+<dt><span class="term">
+ input_file
+ </span></dt>
+<dd>
+ a list of domain names to be resolved. each line
+ consists of a single domain name. Example:
+ <div class="literallayout"><p><br>
+  www.example.com<br>
+  mx.examle.net<br>
+  ns.xxx.example<br>
+</p></div>
+</dd>
+</dl></div>
+</div>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2608291"></a>sample-request: a simple DNS transaction client</h4></div></div></div>
+<p>
+ It sends a query to a specified server, and
+ prints the response with minimal processing. It doesn't act as a
+ "stub resolver": it stops the processing once it gets any
+ response from the server, whether it's a referral or an alias
+ (CNAME or DNAME) that would require further queries to get the
+ ultimate answer. In other words, this utility acts as a very
+ simplified <span><strong class="command">dig</strong></span>.
+ </p>
+<p>
+ Usage: sample-request [-t RRtype] server_address hostname
+ </p>
+<p>
+ Options and Arguments:
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">
+ -t RRtype
+ </span></dt>
+<dd><p>
+ specify the RR type of
+ the queries. The default is the A RR.
+ </p></dd>
+<dt><span class="term">
+ server_address
+ </span></dt>
+<dd><p>
+ an IP(v4/v6)
+ address of the recursive server to which the query is sent.
+ </p></dd>
+<dt><span class="term">
+ hostname
+ </span></dt>
+<dd><p>
+ the domain name for the query
+ </p></dd>
+</dl></div>
+</div>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2608355"></a>sample-gai: getaddrinfo() and getnameinfo() test code</h4></div></div></div>
+<p>
+ This is a test program
+ to check getaddrinfo() and getnameinfo() behavior. It takes a
+ host name as an argument, calls getaddrinfo() with the given host
+ name, and calls getnameinfo() with the resulting IP addresses
+ returned by getaddrinfo(). If the dns.conf file exists and
+ defines a trust anchor, the underlying resolver will act as a
+ validating resolver, and getaddrinfo()/getnameinfo() will fail
+ with an EAI_INSECUREDATA error when DNSSEC validation fails.
+ </p>
+<p>
+ Usage: sample-gai hostname
+ </p>
+</div>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2608370"></a>sample-update: a simple dynamic update client program</h4></div></div></div>
+<p>
+ It accepts a single update command as a
+ command-line argument, sends an update request message to the
+ authoritative server, and shows the response from the server. In
+ other words, this is a simplified <span><strong class="command">nsupdate</strong></span>.
+ </p>
+<p>
+ Usage: sample-update [options] (add|delete) "update data"
+ </p>
+<p>
+ Options and Arguments:
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">
+ -a auth_server
+ </span></dt>
+<dd><p>
+ An IP address of the authoritative server that has authority
+ for the zone containing the update name. This should normally
+ be the primary authoritative server that accepts dynamic
+ updates. It can also be a secondary server that is configured
+ to forward update requests to the primary server.
+ </p></dd>
+<dt><span class="term">
+ -k keyfile
+ </span></dt>
+<dd><p>
+ A TSIG key file to secure the update transaction. The keyfile
+ format is the same as that for the nsupdate utility.
+ </p></dd>
+<dt><span class="term">
+ -p prerequisite
+ </span></dt>
+<dd><p>
+ A prerequisite for the update (only one prerequisite can be
+ specified). The prerequisite format is the same as that is
+ accepted by the nsupdate utility.
+ </p></dd>
+<dt><span class="term">
+ -r recursive_server
+ </span></dt>
+<dd><p>
+ An IP address of a recursive server that this utility will
+ use. A recursive server may be necessary to identify the
+ authoritative server address to which the update request is
+ sent.
+ </p></dd>
+<dt><span class="term">
+ -z zonename
+ </span></dt>
+<dd><p>
+ The domain name of the zone that contains
+ </p></dd>
+<dt><span class="term">
+ (add|delete)
+ </span></dt>
+<dd><p>
+ Specify the type of update operation. Either "add" or "delete"
+ must be specified.
+ </p></dd>
+<dt><span class="term">
+ "update data"
+ </span></dt>
+<dd><p>
+ Specify the data to be updated. A typical example of the data
+ would look like "name TTL RRtype RDATA".
+ </p></dd>
+</dl></div>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Note</h3>In practice, either -a or -r must be specified. Others can
+ be optional; the underlying library routine tries to identify the
+ appropriate server and the zone name for the update.</div>
+<p>
+ Examples: assuming the primary authoritative server of the
+ dynamic.example.com zone has an IPv6 address 2001:db8::1234,
+ </p>
+<pre class="screen">
+$ <strong class="userinput"><code>sample-update -a sample-update -k Kxxx.+nnn+mmmm.key add "foo.dynamic.example.com 30 IN A 192.168.2.1"</code></strong></pre>
+<p>
+ adds an A RR for foo.dynamic.example.com using the given key.
+ </p>
+<pre class="screen">
+$ <strong class="userinput"><code>sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com 30 IN A"</code></strong></pre>
+<p>
+ removes all A RRs for foo.dynamic.example.com using the given key.
+ </p>
+<pre class="screen">
+$ <strong class="userinput"><code>sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com"</code></strong></pre>
+<p>
+ removes all RRs for foo.dynamic.example.com using the given key.
+ </p>
+</div>
+<div class="sect3" lang="en">
+<div class="titlepage"><div><div><h4 class="title">
+<a name="id2609047"></a>nsprobe: domain/name server checker in terms of RFC 4074</h4></div></div></div>
+<p>
+ It checks a set
+ of domains to see the name servers of the domains behave
+ correctly in terms of RFC 4074. This is included in the set of
+ sample programs to show how the export library can be used in a
+ DNS-related application.
+ </p>
+<p>
+ Usage: nsprobe [-d] [-v [-v...]] [-c cache_address] [input_file]
+ </p>
+<p>
+ Options
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">
+ -d
+ </span></dt>
+<dd><p>
+ run in the "debug" mode. with this option nsprobe will dump
+ every RRs it receives.
+ </p></dd>
+<dt><span class="term">
+ -v
+ </span></dt>
+<dd><p>
+ increase verbosity of other normal log messages. This can be
+ specified multiple times
+ </p></dd>
+<dt><span class="term">
+ -c cache_address
+ </span></dt>
+<dd><p>
+ specify an IP address of a recursive (caching) name server.
+ nsprobe uses this server to get the NS RRset of each domain and
+ the A and/or AAAA RRsets for the name servers. The default
+ value is 127.0.0.1.
+ </p></dd>
+<dt><span class="term">
+ input_file
+ </span></dt>
+<dd><p>
+ a file name containing a list of domain (zone) names to be
+ probed. when omitted the standard input will be used. Each
+ line of the input file specifies a single domain name such as
+ "example.com". In general this domain name must be the apex
+ name of some DNS zone (unlike normal "host names" such as
+ "www.example.com"). nsprobe first identifies the NS RRsets for
+ the given domain name, and sends A and AAAA queries to these
+ servers for some "widely used" names under the zone;
+ specifically, adding "www" and "ftp" to the zone name.
+ </p></dd>
+</dl></div>
</div>
</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="id2609111"></a>Library References</h3></div></div></div>
+<p>As of this writing, there is no formal "manual" of the
+ libraries, except this document, header files (some of them
+ provide pretty detailed explanations), and sample application
+ programs.</p>
</div>
</div>
</div>
diff --git a/doc/arm/Bv9ARM.ch10.html b/doc/arm/Bv9ARM.ch10.html
index 692948501bba..7ff08e1a9f00 100644
--- a/doc/arm/Bv9ARM.ch10.html
+++ b/doc/arm/Bv9ARM.ch10.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.ch10.html,v 1.11.14.3 2010-01-24 01:55:26 tbox Exp $ -->
+<!-- $Id: Bv9ARM.ch10.html,v 1.20 2011-01-05 01:14:09 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -64,6 +64,12 @@
<span class="refentrytitle"><a href="man.dnssec-keygen.html"><span class="application">dnssec-keygen</span></a></span><span class="refpurpose"> &#8212; DNSSEC key generation tool</span>
</dt>
<dt>
+<span class="refentrytitle"><a href="man.dnssec-revoke.html"><span class="application">dnssec-revoke</span></a></span><span class="refpurpose"> &#8212; Set the REVOKED bit on a DNSSEC key</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="man.dnssec-settime.html"><span class="application">dnssec-settime</span></a></span><span class="refpurpose"> &#8212; Set the key timing metadata for a DNSSEC key</span>
+</dt>
+<dt>
<span class="refentrytitle"><a href="man.dnssec-signzone.html"><span class="application">dnssec-signzone</span></a></span><span class="refpurpose"> &#8212; DNSSEC zone signing tool</span>
</dt>
<dt>
@@ -76,6 +82,9 @@
<span class="refentrytitle"><a href="man.named.html"><span class="application">named</span></a></span><span class="refpurpose"> &#8212; Internet domain name server</span>
</dt>
<dt>
+<span class="refentrytitle"><a href="man.named-journalprint.html"><span class="application">named-journalprint</span></a></span><span class="refpurpose"> &#8212; print zone journal in human-readable form</span>
+</dt>
+<dt>
<span class="refentrytitle"><a href="man.nsupdate.html"><span class="application">nsupdate</span></a></span><span class="refpurpose"> &#8212; Dynamic DNS update utility</span>
</dt>
<dt>
@@ -87,6 +96,21 @@
<dt>
<span class="refentrytitle"><a href="man.rndc-confgen.html"><span class="application">rndc-confgen</span></a></span><span class="refpurpose"> &#8212; rndc key generation tool</span>
</dt>
+<dt>
+<span class="refentrytitle"><a href="man.ddns-confgen.html"><span class="application">ddns-confgen</span></a></span><span class="refpurpose"> &#8212; ddns key generation tool</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="man.arpaname.html"><span class="application">arpaname</span></a></span><span class="refpurpose"> &#8212; translate IP addresses to the corresponding ARPA names</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="man.genrandom.html"><span class="application">genrandom</span></a></span><span class="refpurpose"> &#8212; generate a file containing random data</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="man.isc-hmac-fixup.html"><span class="application">isc-hmac-fixup</span></a></span><span class="refpurpose"> &#8212; fixes HMAC keys generated by older versions of BIND</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="man.nsec3hash.html"><span class="application">nsec3hash</span></a></span><span class="refpurpose"> &#8212; generate NSEC3 hash</span>
+</dt>
</dl>
</div>
</div>
diff --git a/doc/arm/Bv9ARM.html b/doc/arm/Bv9ARM.html
index 8c21270f11a6..7341705aaad1 100644
--- a/doc/arm/Bv9ARM.html
+++ b/doc/arm/Bv9ARM.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: Bv9ARM.html,v 1.193.14.16 2010-08-20 02:05:39 tbox Exp $ -->
+<!-- $Id: Bv9ARM.html,v 1.263.8.1.2.1 2011-06-09 03:41:09 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -41,7 +41,7 @@
<div>
<div><h1 class="title">
<a name="id2563174"></a>BIND 9 Administrator Reference Manual</h1></div>
-<div><p class="copyright">Copyright © 2004-2010 Internet Systems Consortium, Inc. ("ISC")</p></div>
+<div><p class="copyright">Copyright © 2004-2011 Internet Systems Consortium, Inc. ("ISC")</p></div>
<div><p class="copyright">Copyright © 2000-2003 Internet Software Consortium.</p></div>
</div>
<hr>
@@ -51,39 +51,39 @@
<dl>
<dt><span class="chapter"><a href="Bv9ARM.ch01.html">1. Introduction</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2563412">Scope of Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564391">Organization of This Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564531">Conventions Used in This Document</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564712">The Domain Name System (<acronym class="acronym">DNS</acronym>)</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564371">Scope of Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564394">Organization of This Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564534">Conventions Used in This Document</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch01.html#id2564715">The Domain Name System (<acronym class="acronym">DNS</acronym>)</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564733">DNS Fundamentals</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564768">Domains and Domain Names</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567173">Zones</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567250">Authoritative Name Servers</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567422">Caching Name Servers</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567553">Name Servers in Multiple Roles</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564737">DNS Fundamentals</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2564771">Domains and Domain Names</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567176">Zones</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567253">Authoritative Name Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567426">Caching Name Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch01.html#id2567556">Name Servers in Multiple Roles</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch02.html">2. <acronym class="acronym">BIND</acronym> Resource Requirements</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567587">Hardware requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567613">CPU Requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567626">Memory Requirements</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567721">Name Server Intensive Environment Issues</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567732">Supported Operating Systems</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567590">Hardware requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567617">CPU Requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567629">Memory Requirements</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567724">Name Server Intensive Environment Issues</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch02.html#id2567735">Supported Operating Systems</a></span></dt>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch03.html">3. Name Server Configuration</a></span></dt>
<dd><dl>
<dt><span class="sect1"><a href="Bv9ARM.ch03.html#sample_configuration">Sample Configurations</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567764">A Caching-only Name Server</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567780">An Authoritative-only Name Server</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567767">A Caching-only Name Server</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2567988">An Authoritative-only Name Server</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568007">Load Balancing</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568361">Name Server Operations</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568010">Load Balancing</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch03.html#id2568364">Name Server Operations</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2568366">Tools for Use With the Name Server Daemon</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2570006">Signals</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2568370">Tools for Use With the Name Server Daemon</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch03.html#id2570385">Signals</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch04.html">4. Advanced DNS Features</a></span></dt>
@@ -92,34 +92,64 @@
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#dynamic_update">Dynamic Update</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#journal">The journal file</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#incremental_zone_transfers">Incremental Zone Transfers (IXFR)</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2570492">Split DNS</a></span></dt>
-<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2570510">Example split DNS setup</a></span></dt></dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2570823">Split DNS</a></span></dt>
+<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2570841">Example split DNS setup</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#tsig">TSIG</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571082">Generate Shared Keys for Each Pair of Hosts</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571156">Copying the Shared Secret to Both Machines</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571166">Informing the Servers of the Key's Existence</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571203">Instructing the Server to Use the Key</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571260">TSIG Key Based Access Control</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571445">Errors</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571342">Generate Shared Keys for Each Pair of Hosts</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571553">Copying the Shared Secret to Both Machines</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571563">Informing the Servers of the Key's Existence</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571600">Instructing the Server to Use the Key</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571657">TSIG Key Based Access Control</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571706">Errors</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571459">TKEY</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571576">SIG(0)</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2571720">TKEY</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2563987">SIG(0)</a></span></dt>
<dt><span class="sect1"><a href="Bv9ARM.ch04.html#DNSSEC">DNSSEC</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571644">Generating Keys</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571792">Signing the Zone</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2571873">Configuring Servers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2564055">Generating Keys</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572189">Signing the Zone</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572270">Configuring Servers</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572110">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#dnssec.dynamic.zones">DNSSEC, Dynamic Zones, and Automatic Signing</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572172">Address Lookups Using AAAA Records</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572194">Address to Name Lookups Using Nibble Format</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607351">Converting from insecure to secure</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563493">Dynamic DNS update method</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563529">Fully automatic zone signing</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563611">Private-type records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563649">DNSKEY rollovers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563661">Dynamic DNS update method</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563763">Automatic key rollovers</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563789">NSEC3PARAM rollovers via UPDATE</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563799">Converting from NSEC to NSEC3</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563809">Converting from NSEC3 to NSEC</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563821">Converting from secure to insecure</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563859">Periodic re-signing</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2563868">NSEC3 and OPTOUT</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#rfc5011.support">Dynamic Trust Anchor Management</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607271">Validating Resolver</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607293">Authoritative Server</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#pkcs11">PKCS #11 (Cryptoki) support</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2609524">Prerequisites</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607678">Building BIND 9 with PKCS#11</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607842">PKCS #11 Tools</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2607873">Using the HSM</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2609709">Specifying the engine on the command line</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2609755">Running named with automatic zone re-signing</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch04.html#id2572490">IPv6 Support in <acronym class="acronym">BIND</acronym> 9</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572757">Address Lookups Using AAAA Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch04.html#id2572846">Address to Name Lookups Using Nibble Format</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch05.html">5. The <acronym class="acronym">BIND</acronym> 9 Lightweight Resolver</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2572227">The Lightweight Resolver Library</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch05.html#id2572880">The Lightweight Resolver Library</a></span></dt>
<dt><span class="sect1"><a href="Bv9ARM.ch05.html#lwresd">Running a Resolver Daemon</a></span></dt>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch06.html">6. <acronym class="acronym">BIND</acronym> 9 Configuration Reference</a></span></dt>
@@ -127,55 +157,58 @@
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#configuration_file_elements">Configuration File Elements</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#address_match_lists">Address Match Lists</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2573606">Comment Syntax</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574290">Comment Syntax</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#Configuration_File_Grammar">Configuration File Grammar</a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574305"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574944"><span><strong class="command">acl</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#acl"><span><strong class="command">acl</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574494"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575133"><span><strong class="command">controls</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#controls_statement_definition_and_usage"><span><strong class="command">controls</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574923"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574940"><span><strong class="command">include</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575425"><span><strong class="command">include</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575442"><span><strong class="command">include</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574964"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2574987"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575078"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575204"><span><strong class="command">logging</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575465"><span><strong class="command">key</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575489"><span><strong class="command">key</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575648"><span><strong class="command">logging</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2575842"><span><strong class="command">logging</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577401"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577475"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577539"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577582"><span><strong class="command">masters</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577841"><span><strong class="command">lwres</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577982"><span><strong class="command">lwres</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2578046"><span><strong class="command">masters</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2578090"><span><strong class="command">masters</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2577597"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2578105"><span><strong class="command">options</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#options"><span><strong class="command">options</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_grammar"><span><strong class="command">server</strong></span> Statement Grammar</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#server_statement_definition_and_usage"><span><strong class="command">server</strong></span> Statement Definition and
Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#statschannels"><span><strong class="command">statistics-channels</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2586907"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589239"><span><strong class="command">statistics-channels</strong></span> Statement Definition and
Usage</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587062"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587113"><span><strong class="command">trusted-keys</strong></span> Statement Definition
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#trusted-keys"><span><strong class="command">trusted-keys</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589379"><span><strong class="command">trusted-keys</strong></span> Statement Definition
+ and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589494"><span><strong class="command">managed-keys</strong></span> Statement Grammar</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#managed-keys"><span><strong class="command">managed-keys</strong></span> Statement Definition
and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#view_statement_grammar"><span><strong class="command">view</strong></span> Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2587195"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2589851"><span><strong class="command">view</strong></span> Statement Definition and Usage</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zone_statement_grammar"><span><strong class="command">zone</strong></span>
Statement Grammar</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2588600"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2591396"><span><strong class="command">zone</strong></span> Statement Definition and Usage</a></span></dt>
</dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2591216">Zone File</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch06.html#id2594660">Zone File</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#types_of_resource_records_and_when_to_use_them">Types of Resource Records and When to Use Them</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593378">Discussion of MX Records</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2596822">Discussion of MX Records</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#Setting_TTLs">Setting TTLs</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2593993">Inverse Mapping in IPv4</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594188">Other Zone File Directives</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2594461"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2597574">Inverse Mapping in IPv4</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2597701">Other Zone File Directives</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch06.html#id2597974"><acronym class="acronym">BIND</acronym> Master File Extension: the <span><strong class="command">$GENERATE</strong></span> Directive</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch06.html#zonefile_format">Additional File Formats</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch06.html#statistics">BIND9 Statistics</a></span></dt>
@@ -184,31 +217,41 @@
<dt><span class="chapter"><a href="Bv9ARM.ch07.html">7. <acronym class="acronym">BIND</acronym> 9 Security Considerations</a></span></dt>
<dd><dl>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#Access_Control_Lists">Access Control Lists</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2599016"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch07.html#id2602626"><span><strong class="command">Chroot</strong></span> and <span><strong class="command">Setuid</strong></span></a></span></dt>
<dd><dl>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599234">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2599362">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2602707">The <span><strong class="command">chroot</strong></span> Environment</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch07.html#id2602766">Using the <span><strong class="command">setuid</strong></span> Function</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch07.html#dynamic_update_security">Dynamic Update Security</a></span></dt>
</dl></dd>
<dt><span class="chapter"><a href="Bv9ARM.ch08.html">8. Troubleshooting</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599442">Common Problems</a></span></dt>
-<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2599447">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599459">Incrementing and Changing the Serial Number</a></span></dt>
-<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2599476">Where Can I Get Help?</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2602915">Common Problems</a></span></dt>
+<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch08.html#id2602920">It's not working; how can I figure out what's wrong?</a></span></dt></dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2602932">Incrementing and Changing the Serial Number</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch08.html#id2602949">Where Can I Get Help?</a></span></dt>
</dl></dd>
<dt><span class="appendix"><a href="Bv9ARM.ch09.html">A. Appendices</a></span></dt>
<dd><dl>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599606">Acknowledgments</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2603147">Acknowledgments</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#historical_dns_information">A Brief History of the <acronym class="acronym">DNS</acronym> and <acronym class="acronym">BIND</acronym></a></span></dt></dl></dd>
-<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2599778">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#id2603319">General <acronym class="acronym">DNS</acronym> Reference Information</a></span></dt>
<dd><dl><dt><span class="sect2"><a href="Bv9ARM.ch09.html#ipv6addresses">IPv6 addresses (AAAA)</a></span></dt></dl></dd>
<dt><span class="sect1"><a href="Bv9ARM.ch09.html#bibliography">Bibliography (and Suggested Reading)</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#rfcs">Request for Comments (RFCs)</a></span></dt>
<dt><span class="sect2"><a href="Bv9ARM.ch09.html#internet_drafts">Internet Drafts</a></span></dt>
-<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2603126">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2606462">Other Documents About <acronym class="acronym">BIND</acronym></a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="Bv9ARM.ch09.html#bind9.library">BIND 9 DNS Library Support</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608789">Prerequisite</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608798">Compilation</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608004">Installation</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608035">Known Defects/Restrictions</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608112">The dns.conf File</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2608138">Sample Applications</a></span></dt>
+<dt><span class="sect2"><a href="Bv9ARM.ch09.html#id2609111">Library References</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="reference"><a href="Bv9ARM.ch10.html">I. Manual pages</a></span></dt>
@@ -229,6 +272,12 @@
<span class="refentrytitle"><a href="man.dnssec-keygen.html"><span class="application">dnssec-keygen</span></a></span><span class="refpurpose"> &#8212; DNSSEC key generation tool</span>
</dt>
<dt>
+<span class="refentrytitle"><a href="man.dnssec-revoke.html"><span class="application">dnssec-revoke</span></a></span><span class="refpurpose"> &#8212; Set the REVOKED bit on a DNSSEC key</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="man.dnssec-settime.html"><span class="application">dnssec-settime</span></a></span><span class="refpurpose"> &#8212; Set the key timing metadata for a DNSSEC key</span>
+</dt>
+<dt>
<span class="refentrytitle"><a href="man.dnssec-signzone.html"><span class="application">dnssec-signzone</span></a></span><span class="refpurpose"> &#8212; DNSSEC zone signing tool</span>
</dt>
<dt>
@@ -241,6 +290,9 @@
<span class="refentrytitle"><a href="man.named.html"><span class="application">named</span></a></span><span class="refpurpose"> &#8212; Internet domain name server</span>
</dt>
<dt>
+<span class="refentrytitle"><a href="man.named-journalprint.html"><span class="application">named-journalprint</span></a></span><span class="refpurpose"> &#8212; print zone journal in human-readable form</span>
+</dt>
+<dt>
<span class="refentrytitle"><a href="man.nsupdate.html"><span class="application">nsupdate</span></a></span><span class="refpurpose"> &#8212; Dynamic DNS update utility</span>
</dt>
<dt>
@@ -252,6 +304,21 @@
<dt>
<span class="refentrytitle"><a href="man.rndc-confgen.html"><span class="application">rndc-confgen</span></a></span><span class="refpurpose"> &#8212; rndc key generation tool</span>
</dt>
+<dt>
+<span class="refentrytitle"><a href="man.ddns-confgen.html"><span class="application">ddns-confgen</span></a></span><span class="refpurpose"> &#8212; ddns key generation tool</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="man.arpaname.html"><span class="application">arpaname</span></a></span><span class="refpurpose"> &#8212; translate IP addresses to the corresponding ARPA names</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="man.genrandom.html"><span class="application">genrandom</span></a></span><span class="refpurpose"> &#8212; generate a file containing random data</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="man.isc-hmac-fixup.html"><span class="application">isc-hmac-fixup</span></a></span><span class="refpurpose"> &#8212; fixes HMAC keys generated by older versions of BIND</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="man.nsec3hash.html"><span class="application">nsec3hash</span></a></span><span class="refpurpose"> &#8212; generate NSEC3 hash</span>
+</dt>
</dl></dd>
</dl>
</div>
diff --git a/doc/arm/Bv9ARM.pdf b/doc/arm/Bv9ARM.pdf
index 9fc034941e81..a8a88dc38c7c 100644
--- a/doc/arm/Bv9ARM.pdf
+++ b/doc/arm/Bv9ARM.pdf
@@ -321,738 +321,1062 @@ endobj
<< /S /GoTo /D (section.4.9) >>
endobj
220 0 obj
-(4.9 IPv6 Support in BIND 9)
+(4.9 DNSSEC, Dynamic Zones, and Automatic Signing)
endobj
221 0 obj
<< /S /GoTo /D (subsection.4.9.1) >>
endobj
224 0 obj
-(4.9.1 Address Lookups Using AAAA Records)
+(4.9.1 Converting from insecure to secure)
endobj
225 0 obj
<< /S /GoTo /D (subsection.4.9.2) >>
endobj
228 0 obj
-(4.9.2 Address to Name Lookups Using Nibble Format)
+(4.9.2 Dynamic DNS update method)
endobj
229 0 obj
-<< /S /GoTo /D (chapter.5) >>
+<< /S /GoTo /D (subsection.4.9.3) >>
endobj
232 0 obj
-(5 The BIND 9 Lightweight Resolver)
+(4.9.3 Fully automatic zone signing)
endobj
233 0 obj
-<< /S /GoTo /D (section.5.1) >>
+<< /S /GoTo /D (subsection.4.9.4) >>
endobj
236 0 obj
-(5.1 The Lightweight Resolver Library)
+(4.9.4 Private-type records)
endobj
237 0 obj
-<< /S /GoTo /D (section.5.2) >>
+<< /S /GoTo /D (subsection.4.9.5) >>
endobj
240 0 obj
-(5.2 Running a Resolver Daemon)
+(4.9.5 DNSKEY rollovers)
endobj
241 0 obj
-<< /S /GoTo /D (chapter.6) >>
+<< /S /GoTo /D (subsection.4.9.6) >>
endobj
244 0 obj
-(6 BIND 9 Configuration Reference)
+(4.9.6 Dynamic DNS update method)
endobj
245 0 obj
-<< /S /GoTo /D (section.6.1) >>
+<< /S /GoTo /D (subsection.4.9.7) >>
endobj
248 0 obj
-(6.1 Configuration File Elements)
+(4.9.7 Automatic key rollovers)
endobj
249 0 obj
-<< /S /GoTo /D (subsection.6.1.1) >>
+<< /S /GoTo /D (subsection.4.9.8) >>
endobj
252 0 obj
-(6.1.1 Address Match Lists)
+(4.9.8 NSEC3PARAM rollovers via UPDATE)
endobj
253 0 obj
-<< /S /GoTo /D (subsubsection.6.1.1.1) >>
+<< /S /GoTo /D (subsection.4.9.9) >>
endobj
256 0 obj
-(6.1.1.1 Syntax)
+(4.9.9 Converting from NSEC to NSEC3)
endobj
257 0 obj
-<< /S /GoTo /D (subsubsection.6.1.1.2) >>
+<< /S /GoTo /D (subsection.4.9.10) >>
endobj
260 0 obj
-(6.1.1.2 Definition and Usage)
+(4.9.10 Converting from NSEC3 to NSEC)
endobj
261 0 obj
-<< /S /GoTo /D (subsection.6.1.2) >>
+<< /S /GoTo /D (subsection.4.9.11) >>
endobj
264 0 obj
-(6.1.2 Comment Syntax)
+(4.9.11 Converting from secure to insecure)
endobj
265 0 obj
-<< /S /GoTo /D (subsubsection.6.1.2.1) >>
+<< /S /GoTo /D (subsection.4.9.12) >>
endobj
268 0 obj
-(6.1.2.1 Syntax)
+(4.9.12 Periodic re-signing)
endobj
269 0 obj
-<< /S /GoTo /D (subsubsection.6.1.2.2) >>
+<< /S /GoTo /D (subsection.4.9.13) >>
endobj
272 0 obj
-(6.1.2.2 Definition and Usage)
+(4.9.13 NSEC3 and OPTOUT)
endobj
273 0 obj
-<< /S /GoTo /D (section.6.2) >>
+<< /S /GoTo /D (section.4.10) >>
endobj
276 0 obj
-(6.2 Configuration File Grammar)
+(4.10 Dynamic Trust Anchor Management)
endobj
277 0 obj
-<< /S /GoTo /D (subsection.6.2.1) >>
+<< /S /GoTo /D (subsection.4.10.1) >>
endobj
280 0 obj
-(6.2.1 acl Statement Grammar)
+(4.10.1 Validating Resolver)
endobj
281 0 obj
-<< /S /GoTo /D (subsection.6.2.2) >>
+<< /S /GoTo /D (subsection.4.10.2) >>
endobj
284 0 obj
-(6.2.2 acl Statement Definition and Usage)
+(4.10.2 Authoritative Server)
endobj
285 0 obj
-<< /S /GoTo /D (subsection.6.2.3) >>
+<< /S /GoTo /D (section.4.11) >>
endobj
288 0 obj
-(6.2.3 controls Statement Grammar)
+(4.11 PKCS \04311 \(Cryptoki\) support)
endobj
289 0 obj
-<< /S /GoTo /D (subsection.6.2.4) >>
+<< /S /GoTo /D (subsection.4.11.1) >>
endobj
292 0 obj
-(6.2.4 controls Statement Definition and Usage)
+(4.11.1 Prerequisites)
endobj
293 0 obj
-<< /S /GoTo /D (subsection.6.2.5) >>
+<< /S /GoTo /D (subsubsection.4.11.1.1) >>
endobj
296 0 obj
-(6.2.5 include Statement Grammar)
+(4.11.1.1 Building OpenSSL for the AEP Keyper on Linux)
endobj
297 0 obj
-<< /S /GoTo /D (subsection.6.2.6) >>
+<< /S /GoTo /D (subsubsection.4.11.1.2) >>
endobj
300 0 obj
-(6.2.6 include Statement Definition and Usage)
+(4.11.1.2 Building OpenSSL for the SCA 6000 on Solaris)
endobj
301 0 obj
-<< /S /GoTo /D (subsection.6.2.7) >>
+<< /S /GoTo /D (subsection.4.11.2) >>
endobj
304 0 obj
-(6.2.7 key Statement Grammar)
+(4.11.2 Building BIND 9 with PKCS\04311)
endobj
305 0 obj
-<< /S /GoTo /D (subsection.6.2.8) >>
+<< /S /GoTo /D (subsubsection.4.11.2.1) >>
endobj
308 0 obj
-(6.2.8 key Statement Definition and Usage)
+(4.11.2.1 Configuring BIND 9 for Linux)
endobj
309 0 obj
-<< /S /GoTo /D (subsection.6.2.9) >>
+<< /S /GoTo /D (subsubsection.4.11.2.2) >>
endobj
312 0 obj
-(6.2.9 logging Statement Grammar)
+(4.11.2.2 Configuring BIND 9 for Solaris)
endobj
313 0 obj
-<< /S /GoTo /D (subsection.6.2.10) >>
+<< /S /GoTo /D (subsection.4.11.3) >>
endobj
316 0 obj
-(6.2.10 logging Statement Definition and Usage)
+(4.11.3 PKCS \04311 Tools)
endobj
317 0 obj
-<< /S /GoTo /D (subsubsection.6.2.10.1) >>
+<< /S /GoTo /D (subsection.4.11.4) >>
endobj
320 0 obj
-(6.2.10.1 The channel Phrase)
+(4.11.4 Using the HSM)
endobj
321 0 obj
-<< /S /GoTo /D (subsubsection.6.2.10.2) >>
+<< /S /GoTo /D (subsection.4.11.5) >>
endobj
324 0 obj
-(6.2.10.2 The category Phrase)
+(4.11.5 Specifying the engine on the command line)
endobj
325 0 obj
-<< /S /GoTo /D (subsubsection.6.2.10.3) >>
+<< /S /GoTo /D (subsection.4.11.6) >>
endobj
328 0 obj
-(6.2.10.3 The query-errors Category)
+(4.11.6 Running named with automatic zone re-signing)
endobj
329 0 obj
-<< /S /GoTo /D (subsection.6.2.11) >>
+<< /S /GoTo /D (section.4.12) >>
endobj
332 0 obj
-(6.2.11 lwres Statement Grammar)
+(4.12 IPv6 Support in BIND 9)
endobj
333 0 obj
-<< /S /GoTo /D (subsection.6.2.12) >>
+<< /S /GoTo /D (subsection.4.12.1) >>
endobj
336 0 obj
-(6.2.12 lwres Statement Definition and Usage)
+(4.12.1 Address Lookups Using AAAA Records)
endobj
337 0 obj
-<< /S /GoTo /D (subsection.6.2.13) >>
+<< /S /GoTo /D (subsection.4.12.2) >>
endobj
340 0 obj
-(6.2.13 masters Statement Grammar)
+(4.12.2 Address to Name Lookups Using Nibble Format)
endobj
341 0 obj
-<< /S /GoTo /D (subsection.6.2.14) >>
+<< /S /GoTo /D (chapter.5) >>
endobj
344 0 obj
-(6.2.14 masters Statement Definition and Usage)
+(5 The BIND 9 Lightweight Resolver)
endobj
345 0 obj
-<< /S /GoTo /D (subsection.6.2.15) >>
+<< /S /GoTo /D (section.5.1) >>
endobj
348 0 obj
-(6.2.15 options Statement Grammar)
+(5.1 The Lightweight Resolver Library)
endobj
349 0 obj
-<< /S /GoTo /D (subsection.6.2.16) >>
+<< /S /GoTo /D (section.5.2) >>
endobj
352 0 obj
-(6.2.16 options Statement Definition and Usage)
+(5.2 Running a Resolver Daemon)
endobj
353 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.1) >>
+<< /S /GoTo /D (chapter.6) >>
endobj
356 0 obj
-(6.2.16.1 Boolean Options)
+(6 BIND 9 Configuration Reference)
endobj
357 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.2) >>
+<< /S /GoTo /D (section.6.1) >>
endobj
360 0 obj
-(6.2.16.2 Forwarding)
+(6.1 Configuration File Elements)
endobj
361 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.3) >>
+<< /S /GoTo /D (subsection.6.1.1) >>
endobj
364 0 obj
-(6.2.16.3 Dual-stack Servers)
+(6.1.1 Address Match Lists)
endobj
365 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.4) >>
+<< /S /GoTo /D (subsubsection.6.1.1.1) >>
endobj
368 0 obj
-(6.2.16.4 Access Control)
+(6.1.1.1 Syntax)
endobj
369 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.5) >>
+<< /S /GoTo /D (subsubsection.6.1.1.2) >>
endobj
372 0 obj
-(6.2.16.5 Interfaces)
+(6.1.1.2 Definition and Usage)
endobj
373 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.6) >>
+<< /S /GoTo /D (subsection.6.1.2) >>
endobj
376 0 obj
-(6.2.16.6 Query Address)
+(6.1.2 Comment Syntax)
endobj
377 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.7) >>
+<< /S /GoTo /D (subsubsection.6.1.2.1) >>
endobj
380 0 obj
-(6.2.16.7 Zone Transfers)
+(6.1.2.1 Syntax)
endobj
381 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.8) >>
+<< /S /GoTo /D (subsubsection.6.1.2.2) >>
endobj
384 0 obj
-(6.2.16.8 UDP Port Lists)
+(6.1.2.2 Definition and Usage)
endobj
385 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.9) >>
+<< /S /GoTo /D (section.6.2) >>
endobj
388 0 obj
-(6.2.16.9 Operating System Resource Limits)
+(6.2 Configuration File Grammar)
endobj
389 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.10) >>
+<< /S /GoTo /D (subsection.6.2.1) >>
endobj
392 0 obj
-(6.2.16.10 Server Resource Limits)
+(6.2.1 acl Statement Grammar)
endobj
393 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.11) >>
+<< /S /GoTo /D (subsection.6.2.2) >>
endobj
396 0 obj
-(6.2.16.11 Periodic Task Intervals)
+(6.2.2 acl Statement Definition and Usage)
endobj
397 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.12) >>
+<< /S /GoTo /D (subsection.6.2.3) >>
endobj
400 0 obj
-(6.2.16.12 Topology)
+(6.2.3 controls Statement Grammar)
endobj
401 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.13) >>
+<< /S /GoTo /D (subsection.6.2.4) >>
endobj
404 0 obj
-(6.2.16.13 The sortlist Statement)
+(6.2.4 controls Statement Definition and Usage)
endobj
405 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.14) >>
+<< /S /GoTo /D (subsection.6.2.5) >>
endobj
408 0 obj
-(6.2.16.14 RRset Ordering)
+(6.2.5 include Statement Grammar)
endobj
409 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.15) >>
+<< /S /GoTo /D (subsection.6.2.6) >>
endobj
412 0 obj
-(6.2.16.15 Tuning)
+(6.2.6 include Statement Definition and Usage)
endobj
413 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.16) >>
+<< /S /GoTo /D (subsection.6.2.7) >>
endobj
416 0 obj
-(6.2.16.16 Built-in server information zones)
+(6.2.7 key Statement Grammar)
endobj
417 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.17) >>
+<< /S /GoTo /D (subsection.6.2.8) >>
endobj
420 0 obj
-(6.2.16.17 Built-in Empty Zones)
+(6.2.8 key Statement Definition and Usage)
endobj
421 0 obj
-<< /S /GoTo /D (subsubsection.6.2.16.18) >>
+<< /S /GoTo /D (subsection.6.2.9) >>
endobj
424 0 obj
-(6.2.16.18 Additional Section Caching)
+(6.2.9 logging Statement Grammar)
endobj
425 0 obj
-<< /S /GoTo /D (subsection.6.2.17) >>
+<< /S /GoTo /D (subsection.6.2.10) >>
endobj
428 0 obj
-(6.2.17 server Statement Grammar)
+(6.2.10 logging Statement Definition and Usage)
endobj
429 0 obj
-<< /S /GoTo /D (subsection.6.2.18) >>
+<< /S /GoTo /D (subsubsection.6.2.10.1) >>
endobj
432 0 obj
-(6.2.18 server Statement Definition and Usage)
+(6.2.10.1 The channel Phrase)
endobj
433 0 obj
-<< /S /GoTo /D (subsection.6.2.19) >>
+<< /S /GoTo /D (subsubsection.6.2.10.2) >>
endobj
436 0 obj
-(6.2.19 statistics-channels Statement Grammar)
+(6.2.10.2 The category Phrase)
endobj
437 0 obj
-<< /S /GoTo /D (subsection.6.2.20) >>
+<< /S /GoTo /D (subsubsection.6.2.10.3) >>
endobj
440 0 obj
-(6.2.20 statistics-channels Statement Definition and Usage)
+(6.2.10.3 The query-errors Category)
endobj
441 0 obj
-<< /S /GoTo /D (subsection.6.2.21) >>
+<< /S /GoTo /D (subsection.6.2.11) >>
endobj
444 0 obj
-(6.2.21 trusted-keys Statement Grammar)
+(6.2.11 lwres Statement Grammar)
endobj
445 0 obj
-<< /S /GoTo /D (subsection.6.2.22) >>
+<< /S /GoTo /D (subsection.6.2.12) >>
endobj
448 0 obj
-(6.2.22 trusted-keys Statement Definition and Usage)
+(6.2.12 lwres Statement Definition and Usage)
endobj
449 0 obj
-<< /S /GoTo /D (subsection.6.2.23) >>
+<< /S /GoTo /D (subsection.6.2.13) >>
endobj
452 0 obj
-(6.2.23 view Statement Grammar)
+(6.2.13 masters Statement Grammar)
endobj
453 0 obj
-<< /S /GoTo /D (subsection.6.2.24) >>
+<< /S /GoTo /D (subsection.6.2.14) >>
endobj
456 0 obj
-(6.2.24 view Statement Definition and Usage)
+(6.2.14 masters Statement Definition and Usage)
endobj
457 0 obj
-<< /S /GoTo /D (subsection.6.2.25) >>
+<< /S /GoTo /D (subsection.6.2.15) >>
endobj
460 0 obj
-(6.2.25 zone Statement Grammar)
+(6.2.15 options Statement Grammar)
endobj
461 0 obj
-<< /S /GoTo /D (subsection.6.2.26) >>
+<< /S /GoTo /D (subsection.6.2.16) >>
endobj
464 0 obj
-(6.2.26 zone Statement Definition and Usage)
+(6.2.16 options Statement Definition and Usage)
endobj
465 0 obj
-<< /S /GoTo /D (subsubsection.6.2.26.1) >>
+<< /S /GoTo /D (subsubsection.6.2.16.1) >>
endobj
468 0 obj
-(6.2.26.1 Zone Types)
+(6.2.16.1 Boolean Options)
endobj
469 0 obj
-<< /S /GoTo /D (subsubsection.6.2.26.2) >>
+<< /S /GoTo /D (subsubsection.6.2.16.2) >>
endobj
472 0 obj
-(6.2.26.2 Class)
+(6.2.16.2 Forwarding)
endobj
473 0 obj
-<< /S /GoTo /D (subsubsection.6.2.26.3) >>
+<< /S /GoTo /D (subsubsection.6.2.16.3) >>
endobj
476 0 obj
-(6.2.26.3 Zone Options)
+(6.2.16.3 Dual-stack Servers)
endobj
477 0 obj
-<< /S /GoTo /D (subsubsection.6.2.26.4) >>
+<< /S /GoTo /D (subsubsection.6.2.16.4) >>
endobj
480 0 obj
-(6.2.26.4 Dynamic Update Policies)
+(6.2.16.4 Access Control)
endobj
481 0 obj
-<< /S /GoTo /D (section.6.3) >>
+<< /S /GoTo /D (subsubsection.6.2.16.5) >>
endobj
484 0 obj
-(6.3 Zone File)
+(6.2.16.5 Interfaces)
endobj
485 0 obj
-<< /S /GoTo /D (subsection.6.3.1) >>
+<< /S /GoTo /D (subsubsection.6.2.16.6) >>
endobj
488 0 obj
-(6.3.1 Types of Resource Records and When to Use Them)
+(6.2.16.6 Query Address)
endobj
489 0 obj
-<< /S /GoTo /D (subsubsection.6.3.1.1) >>
+<< /S /GoTo /D (subsubsection.6.2.16.7) >>
endobj
492 0 obj
-(6.3.1.1 Resource Records)
+(6.2.16.7 Zone Transfers)
endobj
493 0 obj
-<< /S /GoTo /D (subsubsection.6.3.1.2) >>
+<< /S /GoTo /D (subsubsection.6.2.16.8) >>
endobj
496 0 obj
-(6.3.1.2 Textual expression of RRs)
+(6.2.16.8 UDP Port Lists)
endobj
497 0 obj
-<< /S /GoTo /D (subsection.6.3.2) >>
+<< /S /GoTo /D (subsubsection.6.2.16.9) >>
endobj
500 0 obj
-(6.3.2 Discussion of MX Records)
+(6.2.16.9 Operating System Resource Limits)
endobj
501 0 obj
-<< /S /GoTo /D (subsection.6.3.3) >>
+<< /S /GoTo /D (subsubsection.6.2.16.10) >>
endobj
504 0 obj
-(6.3.3 Setting TTLs)
+(6.2.16.10 Server Resource Limits)
endobj
505 0 obj
-<< /S /GoTo /D (subsection.6.3.4) >>
+<< /S /GoTo /D (subsubsection.6.2.16.11) >>
endobj
508 0 obj
-(6.3.4 Inverse Mapping in IPv4)
+(6.2.16.11 Periodic Task Intervals)
endobj
509 0 obj
-<< /S /GoTo /D (subsection.6.3.5) >>
+<< /S /GoTo /D (subsubsection.6.2.16.12) >>
endobj
512 0 obj
-(6.3.5 Other Zone File Directives)
+(6.2.16.12 Topology)
endobj
513 0 obj
-<< /S /GoTo /D (subsubsection.6.3.5.1) >>
+<< /S /GoTo /D (subsubsection.6.2.16.13) >>
endobj
516 0 obj
-(6.3.5.1 The @ \(at-sign\))
+(6.2.16.13 The sortlist Statement)
endobj
517 0 obj
-<< /S /GoTo /D (subsubsection.6.3.5.2) >>
+<< /S /GoTo /D (subsubsection.6.2.16.14) >>
endobj
520 0 obj
-(6.3.5.2 The \044ORIGIN Directive)
+(6.2.16.14 RRset Ordering)
endobj
521 0 obj
-<< /S /GoTo /D (subsubsection.6.3.5.3) >>
+<< /S /GoTo /D (subsubsection.6.2.16.15) >>
endobj
524 0 obj
-(6.3.5.3 The \044INCLUDE Directive)
+(6.2.16.15 Tuning)
endobj
525 0 obj
-<< /S /GoTo /D (subsubsection.6.3.5.4) >>
+<< /S /GoTo /D (subsubsection.6.2.16.16) >>
endobj
528 0 obj
-(6.3.5.4 The \044TTL Directive)
+(6.2.16.16 Built-in server information zones)
endobj
529 0 obj
-<< /S /GoTo /D (subsection.6.3.6) >>
+<< /S /GoTo /D (subsubsection.6.2.16.17) >>
endobj
532 0 obj
-(6.3.6 BIND Master File Extension: the \044GENERATE Directive)
+(6.2.16.17 Built-in Empty Zones)
endobj
533 0 obj
-<< /S /GoTo /D (subsection.6.3.7) >>
+<< /S /GoTo /D (subsubsection.6.2.16.18) >>
endobj
536 0 obj
-(6.3.7 Additional File Formats)
+(6.2.16.18 Additional Section Caching)
endobj
537 0 obj
-<< /S /GoTo /D (section.6.4) >>
+<< /S /GoTo /D (subsubsection.6.2.16.19) >>
endobj
540 0 obj
-(6.4 BIND9 Statistics)
+(6.2.16.19 Content Filtering)
endobj
541 0 obj
-<< /S /GoTo /D (subsubsection.6.4.0.1) >>
+<< /S /GoTo /D (subsubsection.6.2.16.20) >>
endobj
544 0 obj
-(6.4.0.1 The Statistics File)
+(6.2.16.20 Response Policy Zone \(RPZ\) Rewriting)
endobj
545 0 obj
-<< /S /GoTo /D (subsection.6.4.1) >>
+<< /S /GoTo /D (subsection.6.2.17) >>
endobj
548 0 obj
-(6.4.1 Statistics Counters)
+(6.2.17 server Statement Grammar)
endobj
549 0 obj
-<< /S /GoTo /D (subsubsection.6.4.1.1) >>
+<< /S /GoTo /D (subsection.6.2.18) >>
endobj
552 0 obj
-(6.4.1.1 Name Server Statistics Counters)
+(6.2.18 server Statement Definition and Usage)
endobj
553 0 obj
-<< /S /GoTo /D (subsubsection.6.4.1.2) >>
+<< /S /GoTo /D (subsection.6.2.19) >>
endobj
556 0 obj
-(6.4.1.2 Zone Maintenance Statistics Counters)
+(6.2.19 statistics-channels Statement Grammar)
endobj
557 0 obj
-<< /S /GoTo /D (subsubsection.6.4.1.3) >>
+<< /S /GoTo /D (subsection.6.2.20) >>
endobj
560 0 obj
-(6.4.1.3 Resolver Statistics Counters)
+(6.2.20 statistics-channels Statement Definition and Usage)
endobj
561 0 obj
-<< /S /GoTo /D (subsubsection.6.4.1.4) >>
+<< /S /GoTo /D (subsection.6.2.21) >>
endobj
564 0 obj
-(6.4.1.4 Socket I/O Statistics Counters)
+(6.2.21 trusted-keys Statement Grammar)
endobj
565 0 obj
-<< /S /GoTo /D (subsubsection.6.4.1.5) >>
+<< /S /GoTo /D (subsection.6.2.22) >>
endobj
568 0 obj
-(6.4.1.5 Compatibility with BIND 8 Counters)
+(6.2.22 trusted-keys Statement Definition and Usage)
endobj
569 0 obj
-<< /S /GoTo /D (chapter.7) >>
+<< /S /GoTo /D (subsection.6.2.23) >>
endobj
572 0 obj
-(7 BIND 9 Security Considerations)
+(6.2.23 managed-keys Statement Grammar)
endobj
573 0 obj
-<< /S /GoTo /D (section.7.1) >>
+<< /S /GoTo /D (subsection.6.2.24) >>
endobj
576 0 obj
-(7.1 Access Control Lists)
+(6.2.24 managed-keys Statement Definition and Usage)
endobj
577 0 obj
-<< /S /GoTo /D (section.7.2) >>
+<< /S /GoTo /D (subsection.6.2.25) >>
endobj
580 0 obj
-(7.2 Chroot and Setuid)
+(6.2.25 view Statement Grammar)
endobj
581 0 obj
-<< /S /GoTo /D (subsection.7.2.1) >>
+<< /S /GoTo /D (subsection.6.2.26) >>
endobj
584 0 obj
-(7.2.1 The chroot Environment)
+(6.2.26 view Statement Definition and Usage)
endobj
585 0 obj
-<< /S /GoTo /D (subsection.7.2.2) >>
+<< /S /GoTo /D (subsection.6.2.27) >>
endobj
588 0 obj
-(7.2.2 Using the setuid Function)
+(6.2.27 zone Statement Grammar)
endobj
589 0 obj
-<< /S /GoTo /D (section.7.3) >>
+<< /S /GoTo /D (subsection.6.2.28) >>
endobj
592 0 obj
-(7.3 Dynamic Update Security)
+(6.2.28 zone Statement Definition and Usage)
endobj
593 0 obj
-<< /S /GoTo /D (chapter.8) >>
+<< /S /GoTo /D (subsubsection.6.2.28.1) >>
endobj
596 0 obj
-(8 Troubleshooting)
+(6.2.28.1 Zone Types)
endobj
597 0 obj
-<< /S /GoTo /D (section.8.1) >>
+<< /S /GoTo /D (subsubsection.6.2.28.2) >>
endobj
600 0 obj
-(8.1 Common Problems)
+(6.2.28.2 Class)
endobj
601 0 obj
-<< /S /GoTo /D (subsection.8.1.1) >>
+<< /S /GoTo /D (subsubsection.6.2.28.3) >>
endobj
604 0 obj
-(8.1.1 It's not working; how can I figure out what's wrong?)
+(6.2.28.3 Zone Options)
endobj
605 0 obj
-<< /S /GoTo /D (section.8.2) >>
+<< /S /GoTo /D (subsubsection.6.2.28.4) >>
endobj
608 0 obj
-(8.2 Incrementing and Changing the Serial Number)
+(6.2.28.4 Dynamic Update Policies)
endobj
609 0 obj
-<< /S /GoTo /D (section.8.3) >>
+<< /S /GoTo /D (section.6.3) >>
endobj
612 0 obj
-(8.3 Where Can I Get Help?)
+(6.3 Zone File)
endobj
613 0 obj
-<< /S /GoTo /D (appendix.A) >>
+<< /S /GoTo /D (subsection.6.3.1) >>
endobj
616 0 obj
-(A Appendices)
+(6.3.1 Types of Resource Records and When to Use Them)
endobj
617 0 obj
-<< /S /GoTo /D (section.A.1) >>
+<< /S /GoTo /D (subsubsection.6.3.1.1) >>
endobj
620 0 obj
-(A.1 Acknowledgments)
+(6.3.1.1 Resource Records)
endobj
621 0 obj
-<< /S /GoTo /D (subsection.A.1.1) >>
+<< /S /GoTo /D (subsubsection.6.3.1.2) >>
endobj
624 0 obj
-(A.1.1 A Brief History of the DNS and BIND)
+(6.3.1.2 Textual expression of RRs)
endobj
625 0 obj
-<< /S /GoTo /D (section.A.2) >>
+<< /S /GoTo /D (subsection.6.3.2) >>
endobj
628 0 obj
-(A.2 General DNS Reference Information)
+(6.3.2 Discussion of MX Records)
endobj
629 0 obj
-<< /S /GoTo /D (subsection.A.2.1) >>
+<< /S /GoTo /D (subsection.6.3.3) >>
endobj
632 0 obj
-(A.2.1 IPv6 addresses \(AAAA\))
+(6.3.3 Setting TTLs)
endobj
633 0 obj
-<< /S /GoTo /D (section.A.3) >>
+<< /S /GoTo /D (subsection.6.3.4) >>
endobj
636 0 obj
-(A.3 Bibliography \(and Suggested Reading\))
+(6.3.4 Inverse Mapping in IPv4)
endobj
637 0 obj
-<< /S /GoTo /D (subsection.A.3.1) >>
+<< /S /GoTo /D (subsection.6.3.5) >>
endobj
640 0 obj
-(A.3.1 Request for Comments \(RFCs\))
+(6.3.5 Other Zone File Directives)
endobj
641 0 obj
-<< /S /GoTo /D (subsection.A.3.2) >>
+<< /S /GoTo /D (subsubsection.6.3.5.1) >>
endobj
644 0 obj
-(A.3.2 Internet Drafts)
+(6.3.5.1 The @ \(at-sign\))
endobj
645 0 obj
-<< /S /GoTo /D (subsection.A.3.3) >>
+<< /S /GoTo /D (subsubsection.6.3.5.2) >>
endobj
648 0 obj
-(A.3.3 Other Documents About BIND)
+(6.3.5.2 The \044ORIGIN Directive)
endobj
649 0 obj
-<< /S /GoTo /D (appendix.B) >>
+<< /S /GoTo /D (subsubsection.6.3.5.3) >>
endobj
652 0 obj
-(B Manual pages)
+(6.3.5.3 The \044INCLUDE Directive)
endobj
653 0 obj
-<< /S /GoTo /D (section.B.1) >>
+<< /S /GoTo /D (subsubsection.6.3.5.4) >>
endobj
656 0 obj
-(B.1 dig)
+(6.3.5.4 The \044TTL Directive)
endobj
657 0 obj
-<< /S /GoTo /D (section.B.2) >>
+<< /S /GoTo /D (subsection.6.3.6) >>
endobj
660 0 obj
-(B.2 host)
+(6.3.6 BIND Master File Extension: the \044GENERATE Directive)
endobj
661 0 obj
-<< /S /GoTo /D (section.B.3) >>
+<< /S /GoTo /D (subsection.6.3.7) >>
endobj
664 0 obj
-(B.3 dnssec-dsfromkey)
+(6.3.7 Additional File Formats)
endobj
665 0 obj
-<< /S /GoTo /D (section.B.4) >>
+<< /S /GoTo /D (section.6.4) >>
endobj
668 0 obj
-(B.4 dnssec-keyfromlabel)
+(6.4 BIND9 Statistics)
endobj
669 0 obj
-<< /S /GoTo /D (section.B.5) >>
+<< /S /GoTo /D (subsubsection.6.4.0.1) >>
endobj
672 0 obj
-(B.5 dnssec-keygen)
+(6.4.0.1 The Statistics File)
endobj
673 0 obj
-<< /S /GoTo /D (section.B.6) >>
+<< /S /GoTo /D (subsection.6.4.1) >>
endobj
676 0 obj
-(B.6 dnssec-signzone)
+(6.4.1 Statistics Counters)
endobj
677 0 obj
-<< /S /GoTo /D (section.B.7) >>
+<< /S /GoTo /D (subsubsection.6.4.1.1) >>
endobj
680 0 obj
-(B.7 named-checkconf)
+(6.4.1.1 Name Server Statistics Counters)
endobj
681 0 obj
-<< /S /GoTo /D (section.B.8) >>
+<< /S /GoTo /D (subsubsection.6.4.1.2) >>
endobj
684 0 obj
-(B.8 named-checkzone)
+(6.4.1.2 Zone Maintenance Statistics Counters)
endobj
685 0 obj
-<< /S /GoTo /D (section.B.9) >>
+<< /S /GoTo /D (subsubsection.6.4.1.3) >>
endobj
688 0 obj
-(B.9 named)
+(6.4.1.3 Resolver Statistics Counters)
endobj
689 0 obj
-<< /S /GoTo /D (section.B.10) >>
+<< /S /GoTo /D (subsubsection.6.4.1.4) >>
endobj
692 0 obj
-(B.10 nsupdate)
+(6.4.1.4 Socket I/O Statistics Counters)
endobj
693 0 obj
-<< /S /GoTo /D (section.B.11) >>
+<< /S /GoTo /D (subsubsection.6.4.1.5) >>
endobj
696 0 obj
-(B.11 rndc)
+(6.4.1.5 Compatibility with BIND 8 Counters)
endobj
697 0 obj
-<< /S /GoTo /D (section.B.12) >>
+<< /S /GoTo /D (chapter.7) >>
endobj
700 0 obj
-(B.12 rndc.conf)
+(7 BIND 9 Security Considerations)
endobj
701 0 obj
-<< /S /GoTo /D (section.B.13) >>
+<< /S /GoTo /D (section.7.1) >>
endobj
704 0 obj
-(B.13 rndc-confgen)
+(7.1 Access Control Lists)
endobj
705 0 obj
-<< /S /GoTo /D [706 0 R /FitH ] >>
+<< /S /GoTo /D (section.7.2) >>
+endobj
+708 0 obj
+(7.2 Chroot and Setuid)
+endobj
+709 0 obj
+<< /S /GoTo /D (subsection.7.2.1) >>
+endobj
+712 0 obj
+(7.2.1 The chroot Environment)
+endobj
+713 0 obj
+<< /S /GoTo /D (subsection.7.2.2) >>
+endobj
+716 0 obj
+(7.2.2 Using the setuid Function)
+endobj
+717 0 obj
+<< /S /GoTo /D (section.7.3) >>
+endobj
+720 0 obj
+(7.3 Dynamic Update Security)
+endobj
+721 0 obj
+<< /S /GoTo /D (chapter.8) >>
+endobj
+724 0 obj
+(8 Troubleshooting)
+endobj
+725 0 obj
+<< /S /GoTo /D (section.8.1) >>
+endobj
+728 0 obj
+(8.1 Common Problems)
+endobj
+729 0 obj
+<< /S /GoTo /D (subsection.8.1.1) >>
+endobj
+732 0 obj
+(8.1.1 It's not working; how can I figure out what's wrong?)
+endobj
+733 0 obj
+<< /S /GoTo /D (section.8.2) >>
+endobj
+736 0 obj
+(8.2 Incrementing and Changing the Serial Number)
+endobj
+737 0 obj
+<< /S /GoTo /D (section.8.3) >>
+endobj
+740 0 obj
+(8.3 Where Can I Get Help?)
+endobj
+741 0 obj
+<< /S /GoTo /D (appendix.A) >>
+endobj
+744 0 obj
+(A Appendices)
+endobj
+745 0 obj
+<< /S /GoTo /D (section.A.1) >>
+endobj
+748 0 obj
+(A.1 Acknowledgments)
+endobj
+749 0 obj
+<< /S /GoTo /D (subsection.A.1.1) >>
+endobj
+752 0 obj
+(A.1.1 A Brief History of the DNS and BIND)
+endobj
+753 0 obj
+<< /S /GoTo /D (section.A.2) >>
+endobj
+756 0 obj
+(A.2 General DNS Reference Information)
+endobj
+757 0 obj
+<< /S /GoTo /D (subsection.A.2.1) >>
+endobj
+760 0 obj
+(A.2.1 IPv6 addresses \(AAAA\))
+endobj
+761 0 obj
+<< /S /GoTo /D (section.A.3) >>
+endobj
+764 0 obj
+(A.3 Bibliography \(and Suggested Reading\))
+endobj
+765 0 obj
+<< /S /GoTo /D (subsection.A.3.1) >>
+endobj
+768 0 obj
+(A.3.1 Request for Comments \(RFCs\))
+endobj
+769 0 obj
+<< /S /GoTo /D (subsection.A.3.2) >>
+endobj
+772 0 obj
+(A.3.2 Internet Drafts)
+endobj
+773 0 obj
+<< /S /GoTo /D (subsection.A.3.3) >>
+endobj
+776 0 obj
+(A.3.3 Other Documents About BIND)
+endobj
+777 0 obj
+<< /S /GoTo /D (section.A.4) >>
+endobj
+780 0 obj
+(A.4 BIND 9 DNS Library Support)
+endobj
+781 0 obj
+<< /S /GoTo /D (subsection.A.4.1) >>
+endobj
+784 0 obj
+(A.4.1 Prerequisite)
+endobj
+785 0 obj
+<< /S /GoTo /D (subsection.A.4.2) >>
+endobj
+788 0 obj
+(A.4.2 Compilation)
+endobj
+789 0 obj
+<< /S /GoTo /D (subsection.A.4.3) >>
+endobj
+792 0 obj
+(A.4.3 Installation)
+endobj
+793 0 obj
+<< /S /GoTo /D (subsection.A.4.4) >>
+endobj
+796 0 obj
+(A.4.4 Known Defects/Restrictions)
+endobj
+797 0 obj
+<< /S /GoTo /D (subsection.A.4.5) >>
endobj
-709 0 obj <<
+800 0 obj
+(A.4.5 The dns.conf File)
+endobj
+801 0 obj
+<< /S /GoTo /D (subsection.A.4.6) >>
+endobj
+804 0 obj
+(A.4.6 Sample Applications)
+endobj
+805 0 obj
+<< /S /GoTo /D (subsubsection.A.4.6.1) >>
+endobj
+808 0 obj
+(A.4.6.1 sample: a simple stub resolver utility)
+endobj
+809 0 obj
+<< /S /GoTo /D (subsubsection.A.4.6.2) >>
+endobj
+812 0 obj
+(A.4.6.2 sample-async: a simple stub resolver, working asynchronously)
+endobj
+813 0 obj
+<< /S /GoTo /D (subsubsection.A.4.6.3) >>
+endobj
+816 0 obj
+(A.4.6.3 sample-request: a simple DNS transaction client)
+endobj
+817 0 obj
+<< /S /GoTo /D (subsubsection.A.4.6.4) >>
+endobj
+820 0 obj
+(A.4.6.4 sample-gai: getaddrinfo\(\) and getnameinfo\(\) test code)
+endobj
+821 0 obj
+<< /S /GoTo /D (subsubsection.A.4.6.5) >>
+endobj
+824 0 obj
+(A.4.6.5 sample-update: a simple dynamic update client program)
+endobj
+825 0 obj
+<< /S /GoTo /D (subsubsection.A.4.6.6) >>
+endobj
+828 0 obj
+(A.4.6.6 nsprobe: domain/name server checker in terms of RFC 4074)
+endobj
+829 0 obj
+<< /S /GoTo /D (subsection.A.4.7) >>
+endobj
+832 0 obj
+(A.4.7 Library References)
+endobj
+833 0 obj
+<< /S /GoTo /D (appendix.B) >>
+endobj
+836 0 obj
+(B Manual pages)
+endobj
+837 0 obj
+<< /S /GoTo /D (section.B.1) >>
+endobj
+840 0 obj
+(B.1 dig)
+endobj
+841 0 obj
+<< /S /GoTo /D (section.B.2) >>
+endobj
+844 0 obj
+(B.2 host)
+endobj
+845 0 obj
+<< /S /GoTo /D (section.B.3) >>
+endobj
+848 0 obj
+(B.3 dnssec-dsfromkey)
+endobj
+849 0 obj
+<< /S /GoTo /D (section.B.4) >>
+endobj
+852 0 obj
+(B.4 dnssec-keyfromlabel)
+endobj
+853 0 obj
+<< /S /GoTo /D (section.B.5) >>
+endobj
+856 0 obj
+(B.5 dnssec-keygen)
+endobj
+857 0 obj
+<< /S /GoTo /D (section.B.6) >>
+endobj
+860 0 obj
+(B.6 dnssec-revoke)
+endobj
+861 0 obj
+<< /S /GoTo /D (section.B.7) >>
+endobj
+864 0 obj
+(B.7 dnssec-settime)
+endobj
+865 0 obj
+<< /S /GoTo /D (section.B.8) >>
+endobj
+868 0 obj
+(B.8 dnssec-signzone)
+endobj
+869 0 obj
+<< /S /GoTo /D (section.B.9) >>
+endobj
+872 0 obj
+(B.9 named-checkconf)
+endobj
+873 0 obj
+<< /S /GoTo /D (section.B.10) >>
+endobj
+876 0 obj
+(B.10 named-checkzone)
+endobj
+877 0 obj
+<< /S /GoTo /D (section.B.11) >>
+endobj
+880 0 obj
+(B.11 named)
+endobj
+881 0 obj
+<< /S /GoTo /D (section.B.12) >>
+endobj
+884 0 obj
+(B.12 named-journalprint)
+endobj
+885 0 obj
+<< /S /GoTo /D (section.B.13) >>
+endobj
+888 0 obj
+(B.13 nsupdate)
+endobj
+889 0 obj
+<< /S /GoTo /D (section.B.14) >>
+endobj
+892 0 obj
+(B.14 rndc)
+endobj
+893 0 obj
+<< /S /GoTo /D (section.B.15) >>
+endobj
+896 0 obj
+(B.15 rndc.conf)
+endobj
+897 0 obj
+<< /S /GoTo /D (section.B.16) >>
+endobj
+900 0 obj
+(B.16 rndc-confgen)
+endobj
+901 0 obj
+<< /S /GoTo /D (section.B.17) >>
+endobj
+904 0 obj
+(B.17 ddns-confgen)
+endobj
+905 0 obj
+<< /S /GoTo /D (section.B.18) >>
+endobj
+908 0 obj
+(B.18 arpaname)
+endobj
+909 0 obj
+<< /S /GoTo /D (section.B.19) >>
+endobj
+912 0 obj
+(B.19 genrandom)
+endobj
+913 0 obj
+<< /S /GoTo /D (section.B.20) >>
+endobj
+916 0 obj
+(B.20 isc-hmac-fixup)
+endobj
+917 0 obj
+<< /S /GoTo /D (section.B.21) >>
+endobj
+920 0 obj
+(B.21 nsec3hash)
+endobj
+921 0 obj
+<< /S /GoTo /D [922 0 R /FitH ] >>
+endobj
+925 0 obj <<
/Length 240
/Filter /FlateDecode
>>
@@ -1060,32 +1384,32 @@ stream
xÚ•OKA Åïó)rl›N2Éü9ZªRA¡27ñ°´[)¸[ºÖïïlWË‚^$0ïý˜y[Š *Z—BTK
ÛÖXx+Þ½¡oFÔ¡Šsåð‡[ LÁ+T\@1M±_8±Eo=C¥BÈÌ~À—Ù,C yÄŠƒÂ•Ë»—Ùrý´š——ì,ãf׺Ãǹ¯ÏÇ~”ž›}Ó7ݶ™¿æ a$/¾äKc¼\óXwŸõûà›Û| §â1'p®äðqH'`Ô ð3‹zšüßÚ±y±n VG³1°™ž07l(%tî[þM^Xúendstream
endobj
-706 0 obj <<
+922 0 obj <<
/Type /Page
-/Contents 709 0 R
-/Resources 708 0 R
+/Contents 925 0 R
+/Resources 924 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 715 0 R
+/Parent 931 0 R
>> endobj
-707 0 obj <<
+923 0 obj <<
/Type /XObject
/Subtype /Form
/FormType 1
/PTEX.FileName (./isc-logo.pdf)
/PTEX.PageNumber 1
-/PTEX.InfoDict 716 0 R
+/PTEX.InfoDict 932 0 R
/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000]
/BBox [0.00000000 0.00000000 612.00000000 792.00000000]
/PieceInfo <<
-/Illustrator 717 0 R
+/Illustrator 933 0 R
>>
/Resources <<
/ColorSpace <<
-/CS0 718 0 R
+/CS0 934 0 R
>>/Properties <<
-/MC0 719 0 R
+/MC0 935 0 R
>>/ExtGState <<
-/GS0 720 0 R
+/GS0 936 0 R
>>>>
/Length 843
/Filter /FlateDecode
@@ -1101,7 +1425,7 @@ BqÕ•l9uš
!=§ ¨Œø†vGc £I#/'~<1‚ÀÔRPy±´ýl1½Ͷw1 чd }¡þa
Ë9b :žÎÞF" ‹>64”~0IGD˜Ë Ø°$ÙtMâ¯%Z½Gð¾¥Úñ§aÑÌ‘ I¼ ý—/øýzü+À
endobj
-716 0 obj
+932 0 obj
<<
/CreationDate (D:20100303120319-08'00')
/Creator (Adobe Illustrator CS3)
@@ -1110,24 +1434,24 @@ endobj
/Title (ISC_logo_only_RGB)
>>
endobj
-717 0 obj
+933 0 obj
<<
-/Private 721 0 R
+/Private 937 0 R
/LastModified (D:20100412113400-07'00')
>>
endobj
-718 0 obj
-[/ICCBased 722 0 R]
+934 0 obj
+[/ICCBased 938 0 R]
endobj
-719 0 obj
+935 0 obj
<<
-/Intent 723 0 R
-/Usage 724 0 R
+/Intent 939 0 R
+/Usage 940 0 R
/Name (Layer 1)
/Type /OCG
>>
endobj
-720 0 obj
+936 0 obj
<<
/OPM 1
/BM /Normal
@@ -1141,22 +1465,22 @@ endobj
/SA true
>>
endobj
-721 0 obj
+937 0 obj
<<
/RoundtripVersion 13
/ContainerVersion 11
/CreatorVersion 13
-/AIMetaData 725 0 R
-/AIPrivateData1 726 0 R
-/AIPrivateData2 727 0 R
-/AIPrivateData3 728 0 R
-/AIPrivateData4 729 0 R
-/AIPrivateData5 730 0 R
+/AIMetaData 941 0 R
+/AIPrivateData1 942 0 R
+/AIPrivateData2 943 0 R
+/AIPrivateData3 944 0 R
+/AIPrivateData4 945 0 R
+/AIPrivateData5 946 0 R
/NumBlock 5
/RoundtripStreamType 1
>>
endobj
-722 0 obj
+938 0 obj
<<
/Length 281
/Filter /FlateDecode
@@ -1167,10 +1491,10 @@ H‰b``2ptqre``ÈÍ+)
rwRˆˆŒR`?ÏÀÆÀÌ
ò‹KRS€j!îAˆBPˆi
endobj
-723 0 obj
+939 0 obj
[/View/Design]
endobj
-724 0 obj
+940 0 obj
<<
/CreatorInfo <<
/Subtype /Artwork
@@ -1178,21 +1502,21 @@ endobj
>>
>>
endobj
-725 0 obj
+941 0 obj
<<
/Length 981
>>
stream
%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 13.0 %%AI8_CreatorVersion: 13.0.2 %%For: (Brian Reid) () %%Title: (ISC_logo_only_RGB.ai) %%CreationDate: 4/12/10 11:34 AM %%BoundingBox: 247 367 366 413 %%HiResBoundingBox: 247.0869 367.5654 365.0859 412.583 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 9.0 %AI12_BuildNumber: 434 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0.658824 0.8 (ISC logo blue) %%+ 0.372549 0.376471 0.384314 (PANTONE 425 U) %%+ 0 0 0 ([Registration]) %AI3_TemplateBox: 306.5 395.5 306.5 395.5 %AI3_TileBox: 18 33.1201 594 786.96 %AI3_DocumentPreview: None %AI5_ArtSize: 612 792 %AI5_RulerUnits: 3 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 0 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -381 793 0.92 1268 743 26 0 0 117 75 0 0 1 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:0 0 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream
endobj
-726 0 obj
+942 0 obj
<<
/Length 11082
>>
stream
%%BoundingBox: 247 367 366 413 %%HiResBoundingBox: 247.0869 367.5654 365.0859 412.583 %AI7_Thumbnail: 128 52 8 %%BeginData: 10932 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD1F52285252A8FD04FFFD05A8FFFFFFA87DFD4F52285252522852 %525228525252285252522852525228525252285252522852277DA8FFFFA8 %7D7D525227FD04527DA8FFFFA85252275252522852525228525252285252 %522852525228525252285252522852525228525252285252522852525228 %52525228525252285252522852525228525252285252522852525228FD21 %52A8FFFF7D7D525227FD0752275252A8FFFF7DFD215227FD2A522E522752 %2E5227522E5227522E5227522E5227522E5227522E5227527DFFFFA85252 %27522E5227522E5227522E5227522752A8FF7D5227522E5227522E522752 %2E5227522E5227522E5227522E5227522E522752277D7D7D275227522E52 %27522E5227522E5227522E5227522E5227522E5227522E5227522E522752 %2E5227FD1A52277DA8FFA87D2EFD11522E527DFFA853FD1D52A8FFFFFF7D %28FD285228525252285252522852525228525252285252522852277DFFFF %7D522752525228525252285252522852525228525252275252FFA8522752 %285252522852525228525252285252522852525228525252277DFFA852A8 %FF5227525252285252522852525228525252285252522852525228525252 %285252522852525228FD1852277DFFFFFD1B52FFA8FD1A527DFFA8275252 %FF7DFD265227522E5227522E5227522E5227522E5227522E522752277DFF %FF525227522E5227522E5227522E5227522E5227522E5227522E52275252 %FFA852275227522E5227522E5227522E5227522E5227522E522752A8A827 %522E527DA9275227522E5227522E5227522E5227522E5227522E52275227 %5227522E5227522E5227522EFD17527DFFA8FD1E527DFFA8FD17527DFFFD %0452287DFFFD155228FD075228FD08522852525228525252285252522852 %5252285252522852527D2752525228525252285252522852525228525252 %2852525228525252285252527DFF7D522852525228525252285252522852 %525228FD0452FF7D5228FD0452FF52522852525228525252285252522752 %2752527DA1A8A8FFCACFA8CAA17D5252275228FD3C52A8FFFD145228A8FF %53FD0652FFA82EFD0C527D7DCAFD04FFAFAF85AF85AFAFFFFFFFA87DFD05 %522E5227522E5227522E5227522E5227522E5227522E5227522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522752A8 %FF275227522E5227522E5227522E5227522E522752FFA827522E5227522E %FF7D522E5227522E522752275252A8FFFFAFAF603CFD041413FD04143C60 %AFFFFF535227FD3A52277DFFA827FD11527DFFFD0852A8FFFD0952A8CFFF %FFAF3C3D1414141A141A141A141A141A14141461AFFFA8FD045228525252 %285252522852525228525252285252522852525228525252285252522852 %5252285252522852525228525252285252522852525227A8FF5227525252 %2852525228525252285252522EFFA85227525252285228A87D5252522852 %27527DFFFFAF603CFD07141A1414141A1414141AFD041460FFA8FD3D52FF %A8FD10527DFF7DFD0F527DFFFFA9611414141A141A141A141A141A141A14 %1A141A141A141A14143CFFA827522E5227522E5227522E5227522E522752 %2E5227522E5227522E5227522E5227522E5227522E5227522E5227522E52 %27522E5227522E5227522E527DFF525227522E5227522E5227522E522752 %A8FF27522E5227522E5227522852275252A8FFFF3C1413FD191436FFFD3C %5259FFA828FD0E52FF7DFD0D527DFFFF8B1414141A141A141A141A141A14 %1A141A141A141A141A141A141A141A141460285252522852525228525252 %285252522852525228525252275227522752275227525252285252522852 %52522852525228525252285252522852525227A8FF7D2752525228525252 %2852525227A8FF52275252522852525228522752A8FFA93CFD05141A1414 %141A1414141A1414141A1414141A1414141A1414141A1414FD1552285252 %7D527D597D527DFD065227FD1852FFA8FD0D52FFFFFD0A52277DFFFF601A %141A141A141A141A141A141A141A141A141A141A141A141A141A141A141A %141A142E5227522E5227522E5227522E5227522752527D7DA8A8FD09FFA8 %FFA8A87D532852275227522E5227522E5227522E5227522E5227522E527D %FF525227522E5227522E52275252FF7D522E5227522E522752277DFFFF36 %FD2314FD0E527D7DFD07FFA8A87DA87DA87DFD04A8FD05FFA87DFD15527D %FFA827FD0A52A8FF7DFD0952A8FFAF1414141A141A141A141A141A141A14 %1A141A141A141A141A141A141A141A141A141A141A145252285252522852 %525227527DA8FFFFFFA87D7D52522752275227522752275227522752527D %A8FFFFFFA87E52522752525228525252285252522852525227A8FF522752 %5252285252522752FFA8275252522852525227A8FF85FD05141A1414141A %1414141A1414141A1414141A1414141A1414141A1414141A1414141AFD07 %52275253A8FFFFFFA8FD045227FD0F522EFD04527D7DFFFFFFA87DFD1052 %7DFF7DFD0A52FF7DFD0852A8FF8B1414141A141A141A141A141A141A141A %141A141A141A141A141A141A141A141A141A141A141A1427522E52275227 %7DA8FFFFA85252275227522E5227522E5227522E5227522E5227522E5227 %522E52275227527DFFFFFF7D52275227522E5227522E5227522752A8A827 %5227522E52275227A8FF5227522752525227A8FF6113FD2714FD0652A8FF %FF7D7D28FD22527DA8FFFF7DFD0C5227A8FF7DFD0852A8FFFD06522EA8FF %61141A141A141A141A141A141A141A141A141A141A141A141A141A141A14 %1A141A141A141A141A141A14285227527DFFFF7D52522752285252522852 %525228525252285252522852525228525252285252522852525228522752 %52FFFFA8525228522852525228FD0452FF7D5228525252285252FF7D5252 %52285227A8FF611414141A1414141A1414141A1414141A1414141A141414 %1A1414141A1414141A1414141A1414141A141452277DFFFFA87D28FD2952 %287DFFFF7EFD0B52A8FFFD065227A8FF7D2752525227A8FF8B141A141A14 %1A141A141A141A141A141A141A141A141A141A141A141A141A141A141A14 %1A141A141A141A1428A8FFFF525227522E5227522E5227522E5227522E52 %27522E5227522E5227522E5227522E5227522E5227522E5227522E522752 %7DFFA87D275227522E522752277EFF52275227522852A8FF52522752277D %FF8BFD121413FD0F1413FD0914FFFFA8FD3352FFFFA8FD0952FF7DFD0652 %FFA8FD04527DFFAF141A141A141A141A141A141A141A141A141A14613C3C %141A141A141A141A141A141A143D3C3C141A141A141A14FF7D2752525228 %525252285252522852525228525252285252522852525228525252285252 %522852525228525252285252522852525227A8FFA8FD045228525252A8A8 %27522852277DFF7D27522752A8FFFD051461A9AF848B1414141A141436AF %AFFFFFFFAFAF36FD04141A14141461A9FFAFFFAFAF601A1414141A7D2EFD %3552277DFFFFFD0752A8FFFD05527DFFFD04527DFF3C14141A141484FFFF %FFAF1A141A141A85FD09FF841A141A141A14AFFD08FF841A141A1427522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522E5227 %522E5227522E5227522E5227522E5227522E5227522E52277DA8FF52522E %5227527DFF52522E5227FFA852275252FF60FD061485FFFFFFAFFD041460 %FD0BFF36FD0414AFFD0AFF60141414FD3A5253FFFF7DFD04527DFFA85252 %527DFFA8285252FFAF1A141A141A141A84FFFFFFAF3D141A14FD05FF603D %60FD04FFAF141A1461FD04FFA96136AFFD04FF141A142852525228525252 %285252522852525228525252285252522852525228525252285252522852 %52522852525228525252285252522852525228522752A8FF5252285252FF %A8FD0452FF7D5227A8FF3C141AFD051485FFFFFFAF14141460FD04FF3614 %141460FFFFFFA91A141484FFFFFFA91A141414FD04FF611414FD3D52A8FF %FD0452A8FF525228A8FF7D277DFF8B141A141A141A141A85FFFFFFAF1A14 %1A60FD04FF3C141A1461FD04FF141A14FD04FF8B141A141AAFFFFFFF601A %142E5227522E5227522E5227522E5227522E5227522E5227522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522E5227 %522752A8FF5252277DFF7D2752A8FF2752A8FFFD08141385FFFFFFAF1414 %1361FD04FF36FD04148584856014133CFD04FF60FD0414FD04FF851314FD %3D52287DFFFF525252FF7D5252FFA8527DFF3C1A141A141A141A141A85FF %FFFFAF1A141A60FD04FFAF141A141A141A141A141A3CFD04FF61141A141A %3C616061361A145252285252522852525228525252285252522852525228 %525252285252522852525228525252285252522852525228525252275252 %522752525228525252277DFF7E2752FFA82753FF7E27FFA914141A141414 %1A1414148BFFFFFFAF1414143CAFFD04FFAFFD091461FD04FF3614141AFD %07141AFD2B522852285227FD075227FD075227A8FF7D27FFA8527DFF7D7D %FF3D141A141A141A141A141484FFFFFFA91A141A1485FD06FF603C141A14 %1A14143CFD04FF61141A141A141A141A141A1427522E5227522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E522752275227 %FD04527D7DA8A8FFA8FFA8FFA8A87D7D52522752275227FFA8527DFF277D %FF52A8AF13FD0A1485FFFFFFAFFD0414138BFD06FFA860FD05143CFD04FF %36FD0B14FD2852A8A8FD07FFA8FFA8FFA8FD06FFA87D5227527DFF7D7DFF %7DA8FF7DFF3C1A141A141A141A141A141A84FFFFFFAF3D141A141A148BFD %07FF8B141A141A3CFD04FF61141A141A141A141A141A1428525252285252 %522852525228525252285252522852525228525252285252522752275252 %A8A8FFFFFFA8A87D7DFD065227FD04527D7DA8FFFFA87D2752A8FF52FF7D %A8A8CAA914141A1414141A1414141A1485FFFFFFAFFD071460A8FD06FF8B %1414143CFD04FF36FD04141A1414141A1414FD2252A8FD04FF7D7D525228 %5227FD0B52275252527DFFFFFF5253FFA8A8A8FFA8FF61141A141A141A14 %1A141A141A85FFFFFFAF1A141A141A141A141A60FD06FF85141A3CFD04FF %61141A141A141A141A141A142E5227522E5227522E5227522E5227522E52 %27522E5227522E5227522752277DA8FFFFA859522752275227522E522752 %2E5227522E5227522E5227522752277DA8FF7DA8FFFFA8FFFFAFFD0C1413 %85FFFFFFAFFD061413FD0414AFFD04FFA9141360FD04FF36FD051413FD05 %14FD1D527DFFFFFF7D7DFD1E52A8FFA8FD05FF601A141A141A141A141A14 %1A141A85FFFFFFAF1A141A143D363D141A141A14FD05FF3C1A3CFD04FF61 %141A141A60AF85AF601A1452522852525228525252285252522852525228 %52525228525252277DFFFFA87D2E52275252522852525228525252285252 %52285252522852525228525252285228527DFD06FF3C141A1414141A1414 %141A1414148BFFFFFFAF141414AFFFFFAF8BFD04143CFD04FF3C143CFD04 %FF60FD04148BFFFFFFAF1414FD1752285259FFFFA9525227FD2352A8FD04 %FFAF141A141A141A141A141A141A141484FFFFFFA91A141484FFFFFFA91A %141A1461FD04FF3C1414FD04FF8B141A141AA9FFFFFF85141427522E5227 %522E5227522E5227522E5227522E52275227527DFFA87D27522E5227522E %5227522E5227522E5227522E5227522E5227522E5227522E5227522E5227 %522752A8FFFFFF60FD0E1485FFFFFFAF14141485FD04FFFD041436FD04FF %3C141484FFFFFFA8FD0414FD04FF611414FD16527DFFFF7D5228FD275227 %A8FFFFFF3D141A141A141A141A141A141A141A84FFFFFFAF3D141460FD04 %FFAF363C3CFD05FF141A1461FD04FF853C148BFD04FF3C1A142752275227 %52275227522752275227522752275227A8FFA82852275227522752275227 %522752275227522752275227522752275227522752275227522752275227 %52275252FFFFAFFD0F1485FFFFFFAFFD0414A8FD05FFAFFD05FF36FD0414 %AFFD0AFF841414147D527D527D527D527D527D527D527D527D527D52A8FF %FF527D527D527D527D527D527D527D527D527D527D527D527D527D527D52 %7D527D527D527D527D527D527D527D527DA8FF853C363D3C3C363D3C3C36 %3D3C3C363D85FFFFFFAF3D363D3685FD0AFFAF3C363D3C3C60FD0AFF6136 %3D3CFD16FFA8FD49FFAFFD11FFAFFD09FFAFFFFFFF %%EndData endstream
endobj
-727 0 obj
+943 0 obj
<<
/Length 65536
>>
@@ -1466,7 +1790,7 @@ sÓ ·ÓíÑ·OÒ„ŸuMÊ’ÏyÒÁQÊ—*V€)-z=¦Hèªmƈœ~ÅñÓ×z…Sý[t¸c&4 ŽªªAj^råº;ņÜ(cçç
Dx^QÜ×}Ì
˜ØyY‰Ÿ‹© ¨zŽ…N¬V¥%™­‚¨™@“£=HU˜ü¢³l0¼Tq_PIÐ/u,dÆö¶fý"íŒØ¾MMæu [endstream
endobj
-728 0 obj
+944 0 obj
<<
/Length 65536
>>
@@ -1708,7 +2032,7 @@ qlÞ¯­ò×âô`>
¶“¬ûVG=# [ül&wJ΂fkíY”&{öñß1øÀ ÛÄ%'DSì
 F?؆Fß®U E2,„Ò -[‰Ðð~Eô׈bˆ¨<Þë‹uAhÜš:®—Ú[ɬëxÏ*}ñ
endobj
-729 0 obj
+945 0 obj
<<
/Length 65536
>>
@@ -1931,7 +2255,7 @@ uALŽk‹Š=ŽÉÀÇš?éì•ëðå0ƒ¨Ua¦7S“«ÙŽ®&éÀ­Ó˜çÈî¹m(‚4„Ћz35Ãùd2pnSø׸®÷—fSµNP™š
]×g1ͼ‘ôAÚF¥5³ò(ª®Í
endobj
-730 0 obj
+946 0 obj
<<
/Length 53114
>>
@@ -2128,1390 +2452,1811 @@ Y‘φ㧻Ç'ÇÕpV— ´Š›·§/ óü8
œ;ø# ñ<Ý°'€å‰íö Ð"W€­
Ö^IYïc­
endobj
-710 0 obj <<
-/D [706 0 R /XYZ 85.0394 794.5015 null]
+926 0 obj <<
+/D [922 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-711 0 obj <<
-/D [706 0 R /XYZ 85.0394 769.5949 null]
+927 0 obj <<
+/D [922 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-708 0 obj <<
-/Font << /F21 714 0 R >>
-/XObject << /Im1 707 0 R >>
+924 0 obj <<
+/Font << /F21 930 0 R >>
+/XObject << /Im1 923 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-733 0 obj <<
-/Length 1059
+949 0 obj <<
+/Length 1063
/Filter /FlateDecode
>>
stream
-xÚµVËn«HÝç+XÆRh÷ƒWÏŽ`l3Âà|£ÑÜY›ÄH‰± ¹Vþ~ªéŒ‰f3ò¢«éãªS§ªDÃð#ši!‹S®ÙÜ@&&¦¶}¿ÃÚ+¬-îˆÂ&C¦ÁL¾XÕ #ÃâšÎ 䀳KÐ Øâȶlªé¶É‘Å(èÇìn:§Tãˆ[ÔÒ²Í6m8¦Ö£²Ý_÷^uü<•¯ûfòwö»fbdc¤ÃX¶ba:'Æ…'B@nkúî'$*¡£ „"HU¤)@cãa¢S ÓLk0íÁt“÷&ÁÒ
-Mq:œ¥ŸuS¼×râU‡º:5åÇûC‡Ý¢‰Îš&þI©¤ž`Jë;?ëõ$Œ"Ó²,Œ@!¹ù­ø=Z¿„ߪO˜ ·ùàõßä§ÿ§üx” &Lö¥ºÕKsÎOâÜ×£ký ³)ÅŽfS<-ç[ù:°~‰¾UÏtÅ” >E:ëâô^ÖuY$§¦’ãG]¨|¶ ï„r¯æïÕ®|}É»iu’ö®¬›SùüѨ›}©ª¾Éÿ¥ûS~ø”Æñãt¬jµ|.›½´:œøR}(=_
-…ƒ
-ÙiíôP5å¶è5¸Nøx%í~<¹ÊªTëùÛ›L„;ˆcËg±Ë¢nšsÄ %'6âŒÚ-$[úªÕâyö4áôÞMÔ— •ã:‰3&gb÷ºi‡3i»Ñ¬ûèIcVè+vÃP*JâFYà«Å§ [J+ñn2“ÛŽ`FÇ)eBýXB³eGñ ò‘nfA´¸
-¬ÖaÐåò“x.Ç•ŸxKX˜Øƽû„Aöç¨`g!n8vÇŽ´ìæAùiŠ:rŒ_ÿ‡þ$áåÀ¨ÓëQQ÷1Tö<Nº¨*|ºö½À :ßk9v'ntó \´ @0²Æbzq”úl€xTÝ•»èµ¸>Z}Zº"J–ÆXÒU/Ý„í×^úy¯Tbq:ˆ,(aãU7©ßå&Ý·óŽ¥Ó‡Ž‡]œŒ5w»ÑË‚8—ÒÎw¤Qä/Â`áGž?Ž·žWxP‡ŒË-›1™0ò7éeHåØM‚´—"Þdc&ñk`ùŒ‡mÑïSÐgTV±ñ9#c×~³r‡|æßm™›«„ n[p@šà•|{•ô`ý}{•PJ±ÞûD¿zL\_tmš”ÂvcÖXnª7‰·ÏOàHyiäù]4ªï-dûJ¡¤Ø«J¿^ÙŒ.'/+á¢9”yëÁ0ááÀnúÔ•î™pOÇÄöMsüm:=ŸÏBaTÖ[Tµ¤^§7·¶z´2‰gé~²þpz”¦endstream
+xÚµV]“ª8}Ÿ_ÁãX5D’0ûÆ *[.àÚÚ»ŒâHÕŒXÂ\kþývH
+c2Š˜I)Lî¬ê&#ˆB5šhÞ.Q7hf#Š)×t›qdQø ŸÓ‡ñŒ#nKKwšEáŒh*Ýþõè–ǯSñ¶¯G§¿kÌ@¶Á¢†!±0žaó“Nmq[Ó/p?!S ÅA®"O"†a>t a²Þ´zÓîÍIoòÎÄFobiù‡:?òZÎ’¯ªÎ?*9qËCUžêâóã©ÅnÐH§Ø
+Dá1F„Boè`pÛU¤·ÏeÀWàí”AQ¶Šø±Y,Û|ÛÒÍêÖRî³×òWÞK!;­™ʺØä× ¯¤ÀÇ<SYj={—‰ð â†Å†™@ì"¯šFæ58¢&…’cqJì’.<ÕjÑ,}qòèÄê‹ŸÈqG?ü©7•3±{¤Eˆ™´pÚ~t¥1+pü¥;A %vÂÔ÷Ôâ‹Ÿ.¤{s'žÊm §1%ÔR¡~$¡é¢¥x‡|èë©ί‚ûËUà·¹ÜcÍä¸ôbw #Û|tžýÀOÿìì,Ä͉ݲà »™Ÿ†^’ –ƒCÅ×ûá?IxÑ3jõzVÔßy”=‹â6ª
+Ÿ¬<×w‚§VãØsŽí‰Þ|M`YC1Ý(L¼?ÖÀ
+<*‡ÎÒ™wZ\¬¾,%M"H,n«—¬ƒæk'ý,Ž–*±(éE” ãU׉×æ&Ý7òŽ¥“§–‡]5wÚÑMý(–ÒNcg QèÍî…®7Œ5žWx –[6c<¢6ä­“ËʱûI'E´N‡L¢+ÖÀ,ô.÷Û¢Û§ Ï ¬bãsŠ‡"®¼:géôù̾Û27W ÁÂܶà€dà{•t`ý}{•‚¶'¼ó)ˆÞ{L\_tMšÞh&µ†úsf(ð>;#奖çw^«¾·í+…â|{.KuþºE=¸œÜì½€‹æPd“ÁÃÞô©#ÝSáž ‰íëúøÛx|>Ÿ…¨¨6¨lH½onmõ€¥ ‰'ê~¾þN!–Éendstream
endobj
-732 0 obj <<
+948 0 obj <<
/Type /Page
-/Contents 733 0 R
-/Resources 731 0 R
+/Contents 949 0 R
+/Resources 947 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 715 0 R
+/Parent 931 0 R
>> endobj
-734 0 obj <<
-/D [732 0 R /XYZ 56.6929 794.5015 null]
+950 0 obj <<
+/D [948 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-731 0 obj <<
-/Font << /F22 737 0 R /F14 740 0 R >>
+947 0 obj <<
+/Font << /F22 953 0 R /F14 956 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-743 0 obj <<
-/Length 2884
+959 0 obj <<
+/Length 2886
/Filter /FlateDecode
>>
stream
-xÚí]wÛ¸†ïó+tWûB(¾ ^:Ž“u·ÉæÄÎé×ö‚GflõX¤KQ¾ €# œÍn²±tr!ÙÒp&ó>Àf3jÿ±™Q„Š\β\E™š-V/èìÚ~öæsß‘J%…°?D>+aˆ2<›ÍáA^^¾øãkÎf\’Ìdlvùiô¥8á\ä³Ë«ÖU[VíúøŸ—ê r’k®»ïÓÙ\s"0ý7ÙñœQJΫ¶©¯6‹vYWÕ‹³ËŒ‚hÊäL›œd’².”áÃæz6¼ù°»ûþøØÇPv;D´ãÞ¥ IØ®Sœæö­±i×YF´d. ¤Ïƒ¢G‹ú®<žsû¶þ4¼¾ª›•Íæñ\™üˆØ›¯gù"ó/ùÿMRã3½#Ûç膻Bîÿ3ôDÂÀ(BŠ´êÎbí(⎢ŸšcfŽ®‹jùߢ?£¶€º¼Y®£%E¶?ÀL’â³™L
-0ÄHÙRkš”H)¨ó@Šï¥ô)‘bGê{ €eÄ!ñq]^ ï–Õ4.Bég È$>{Éd
-Á$† ê|Ä„e„)ª&ÜcÒ$îbRTWññÅ~.´|–TLâà3–Œ0Äp€Š 8DÂÀp@8P;ET\„ÃáïuÕ‹Mù³žÕ|ƒÑÅg<'`ˆáEpŠ„á„:8©œ“\ÉP®ôK‡Óɦ½©›ekg<÷åN¹R6÷eÓ_“²}¬KBÖR‘€†[ªˆI$ba HàΙ’$˲|¦ %F©±.*«Ø÷ÍrU4Ão [¼66g‚ïÕÀ•L0Ä(€B DÂÀ(@hC2•i@w\Ü÷ÅÍþ\)>Ç…O]2ÀãJƒp ãu>r¡4Ñ*€ á¹hËⶽyD†¦ù¡†YKFbH@U$"a`H ÎÇBJ¢4kåjˆÓbq³¬®'«aØÞ›“„ø$& 1B HršH!¨óqÐœHÍÇ’B…’âuÝü§èدzTäw2ùš×Ÿ½d4€!†TA#†ê|<8%B˱ÎÐnðˆÍ6À:úÛÍm»¼»u_ùPßv“ß\èç>óðéJfb,@9"a`,ì8‡;Ç~Ó[æÉ„ b˜[Ù/Ïß½r—ëzÓ,¼âå¿7˦\ùñh¶ÂŸºÅ -î­HÕd–àÑìì:m,H›&-„[«[Ü?¸ÁÓ ¢.;Ãû.Cý›!Ks# ?èÙrœzvACäìÚÒá&Æê<ð“ ¢„Ì?~sûôýGxBA\2j‹‡é ù<'3 1† ŽC‘00†Pç!m¯ÐB»•ï°íý¶\Õ~1h#™Ë8OÇ'7`ˆÅCÀ‰„ƒ:àÈœaÜ¥=ìŠ?®ñ†÷ç]»Û:,;ŸU÷Pu5´KôßY¯7]Å÷{jâúµÚ#B²’A
- ø]ll}ý}Š’õ†˜þPDÿH˜þ¨óñj@É8ED˜‹\,¯«b8ùÙ¡ ý2’¸!šS6&û‰$y»94Œ´sü¾¯cº­=†ÒŽ÷Øú!7‚P“K×Å0¬ž\ÝÛéŒ_bo²*‹vÓ”ëÉL…ƒ}få0dDVwŽÛghºiÉÌ®×X¡Î3Jòœ ¼ K‡ïêvùÉÎì홺Gw|«a À‹‘zBCäÜ#,Fê=¦ŒÖ…ͯ.¼z¨Š•/ë>Þ]­½š›L ú¿!ryNfh´Ã*b턹å
-€°u^-ÆÖNwãd˜QУ¦¨ÖŸB»iw3þù__îÆ×yöœÁ™DÅg3`ˆ¡ÕbÓ]§±80TPï;Þ¨ÜøŠÈ·¦\ÜÝ.[X*}¨…~ËáÈËÌ0ă2cŒEâÀC½×2F‰M_î! ײ³_À¦ýú1sÝïÊvsוHbŸáðéK†bp@y08"q`p Þý
+xÚí]wÛ¸†ïó+tWûB(¾ ^:Ž“u·ÉæÄÎé×ö‚GflõX¤KQ¾ €# œÍn²±tö´¥áÌÎû
+x6$a»N9pšÛCcÓ®³ŒhÉ\HŸE.õ]y<çö°þ4ü|U/6+›Íã¹2ù±?l¾žå™Éÿß$5>Ó;²}Ž`¸+äîù?CO$ Œ"Ôy H«î*ÖŽ"î(ú©9fæ躨–ÿ-ú+j ¨Ë›åú1ZRdûÌ$)>›É¤
+êœqNLžYç<'\_³È¾já6Vü„×›êªè†ˆâ¶3ŒØ»*䉘øL&c 1L R&‘00LPç#&,#LQ0á“~$q7“¢ºŠ/ös¡å³¤bŸ±d€!†TÁ!†ê|ÄÚ)¢â"à ¯«^lÊŸõ¬æŒ.>ãÉ8C '¨(‚S$ 'ÔyÀIåœäJ†r¥/X:œN6íMÝ,[;ã¹/wÊ•²¹/›þž”íc]²–Š4DØREL" AwΔ$Y–å3e(1JuÉP™Xžo–«¢y~y[Øâµ±9|¯†¨d
+€!F¡ Fê|¤@’©L
+¸£àⶸ<(nöçNñ9.|ê’¹
+¿Z×U½n— ÷Ð̈ƒ2fûHBÎ’
+‹µÁPá_ù™óœ˜ØûÆ»Õõ Î…~‰‰&Áº"15s_êb["_ø3yoÿ>ªendstream
endobj
-742 0 obj <<
+958 0 obj <<
/Type /Page
-/Contents 743 0 R
-/Resources 741 0 R
+/Contents 959 0 R
+/Resources 957 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 715 0 R
-/Annots [ 746 0 R 747 0 R 748 0 R 749 0 R 750 0 R 751 0 R 752 0 R 753 0 R 754 0 R 755 0 R 756 0 R 757 0 R 758 0 R 759 0 R 760 0 R 761 0 R 762 0 R 763 0 R 764 0 R 765 0 R 766 0 R 767 0 R 768 0 R 769 0 R 770 0 R 771 0 R 772 0 R 773 0 R 774 0 R 775 0 R 776 0 R 777 0 R 778 0 R 779 0 R 780 0 R 781 0 R 782 0 R 783 0 R 784 0 R 785 0 R 786 0 R 787 0 R 788 0 R 789 0 R 790 0 R 791 0 R 792 0 R 793 0 R 794 0 R 795 0 R ]
+/Parent 931 0 R
+/Annots [ 962 0 R 963 0 R 964 0 R 965 0 R 966 0 R 967 0 R 968 0 R 969 0 R 970 0 R 971 0 R 972 0 R 973 0 R 974 0 R 975 0 R 976 0 R 977 0 R 978 0 R 979 0 R 980 0 R 981 0 R 982 0 R 983 0 R 984 0 R 985 0 R 986 0 R 987 0 R 988 0 R 989 0 R 990 0 R 991 0 R 992 0 R 993 0 R 994 0 R 995 0 R 996 0 R 997 0 R 998 0 R 999 0 R 1000 0 R 1001 0 R 1002 0 R 1003 0 R 1004 0 R 1005 0 R 1006 0 R 1007 0 R 1008 0 R 1009 0 R 1010 0 R 1011 0 R ]
>> endobj
-746 0 obj <<
+962 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 688.709 539.579 697.4212]
/Subtype /Link
/A << /S /GoTo /D (chapter.1) >>
>> endobj
-747 0 obj <<
+963 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 676.5858 539.579 685.5919]
/Subtype /Link
/A << /S /GoTo /D (section.1.1) >>
>> endobj
-748 0 obj <<
+964 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 664.4876 539.579 673.4937]
/Subtype /Link
/A << /S /GoTo /D (section.1.2) >>
>> endobj
-749 0 obj <<
+965 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 652.3894 539.579 661.3954]
/Subtype /Link
/A << /S /GoTo /D (section.1.3) >>
>> endobj
-750 0 obj <<
+966 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 640.2911 539.579 649.1477]
/Subtype /Link
/A << /S /GoTo /D (section.1.4) >>
>> endobj
-751 0 obj <<
+967 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 628.1929 539.579 637.0495]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.1) >>
>> endobj
-752 0 obj <<
+968 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 616.0946 539.579 624.9512]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.2) >>
>> endobj
-753 0 obj <<
+969 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 603.9964 539.579 612.853]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.3) >>
>> endobj
-754 0 obj <<
+970 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 591.7985 539.579 600.7547]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.4) >>
>> endobj
-755 0 obj <<
+971 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 579.7002 539.579 588.6565]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.1.4.4.1) >>
>> endobj
-756 0 obj <<
+972 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 567.6019 539.579 576.5582]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.1.4.4.2) >>
>> endobj
-757 0 obj <<
+973 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 555.5037 539.579 564.46]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.1.4.4.3) >>
>> endobj
-758 0 obj <<
+974 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 543.5051 539.579 552.5112]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.5) >>
>> endobj
-759 0 obj <<
+975 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 531.4069 539.579 540.413]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.1.4.5.1) >>
>> endobj
-760 0 obj <<
+976 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 519.3086 539.579 528.3147]
/Subtype /Link
/A << /S /GoTo /D (subsection.1.4.6) >>
>> endobj
-761 0 obj <<
+977 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 496.5559 539.579 505.288]
/Subtype /Link
/A << /S /GoTo /D (chapter.2) >>
>> endobj
-762 0 obj <<
+978 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 484.4775 539.579 493.4338]
/Subtype /Link
/A << /S /GoTo /D (section.2.1) >>
>> endobj
-763 0 obj <<
+979 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 472.3792 539.579 481.3355]
/Subtype /Link
/A << /S /GoTo /D (section.2.2) >>
>> endobj
-764 0 obj <<
+980 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 460.281 539.579 469.2373]
/Subtype /Link
/A << /S /GoTo /D (section.2.3) >>
>> endobj
-765 0 obj <<
+981 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 448.1827 539.579 457.139]
/Subtype /Link
/A << /S /GoTo /D (section.2.4) >>
>> endobj
-766 0 obj <<
+982 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 436.0845 539.579 445.0408]
/Subtype /Link
/A << /S /GoTo /D (section.2.5) >>
>> endobj
-767 0 obj <<
+983 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 413.5759 539.579 422.1635]
/Subtype /Link
/A << /S /GoTo /D (chapter.3) >>
>> endobj
-768 0 obj <<
+984 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 401.4527 539.579 410.3093]
/Subtype /Link
/A << /S /GoTo /D (section.3.1) >>
>> endobj
-769 0 obj <<
+985 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 389.3544 539.579 398.2111]
/Subtype /Link
/A << /S /GoTo /D (subsection.3.1.1) >>
>> endobj
-770 0 obj <<
+986 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 377.2562 539.579 386.1128]
/Subtype /Link
/A << /S /GoTo /D (subsection.3.1.2) >>
>> endobj
-771 0 obj <<
+987 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 365.0583 539.579 374.0146]
/Subtype /Link
/A << /S /GoTo /D (section.3.2) >>
>> endobj
-772 0 obj <<
+988 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 352.96 539.579 361.9163]
/Subtype /Link
/A << /S /GoTo /D (section.3.3) >>
>> endobj
-773 0 obj <<
+989 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 340.8618 539.579 349.818]
/Subtype /Link
/A << /S /GoTo /D (subsection.3.3.1) >>
>> endobj
-774 0 obj <<
+990 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 328.7635 539.579 337.7198]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.3.3.1.1) >>
>> endobj
-775 0 obj <<
+991 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [532.6051 316.6653 539.579 325.6216]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.3.3.1.2) >>
>> endobj
-776 0 obj <<
+992 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 304.6667 539.579 313.6728]
+/Rect [527.6238 304.567 539.579 313.6728]
/Subtype /Link
/A << /S /GoTo /D (subsection.3.3.2) >>
>> endobj
-777 0 obj <<
+993 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 281.9139 539.579 290.7706]
/Subtype /Link
/A << /S /GoTo /D (chapter.4) >>
>> endobj
-778 0 obj <<
+994 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 269.8356 539.579 278.9413]
/Subtype /Link
/A << /S /GoTo /D (section.4.1) >>
>> endobj
-779 0 obj <<
+995 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 257.7373 539.579 266.8431]
/Subtype /Link
/A << /S /GoTo /D (section.4.2) >>
>> endobj
-780 0 obj <<
+996 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 245.6391 539.579 254.7448]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.2.1) >>
>> endobj
-781 0 obj <<
+997 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 233.6405 539.579 242.6465]
+/Rect [527.6238 233.5408 539.579 242.6465]
/Subtype /Link
/A << /S /GoTo /D (section.4.3) >>
>> endobj
-782 0 obj <<
+998 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 221.5422 539.579 230.5483]
+/Rect [527.6238 221.4426 539.579 230.5483]
/Subtype /Link
/A << /S /GoTo /D (section.4.4) >>
>> endobj
-783 0 obj <<
+999 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [527.6238 209.444 539.579 218.4501]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.4.1) >>
>> endobj
-784 0 obj <<
+1000 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 197.3457 539.579 206.3518]
+/Rect [527.6238 197.2461 539.579 206.3518]
/Subtype /Link
/A << /S /GoTo /D (section.4.5) >>
>> endobj
-785 0 obj <<
+1001 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 185.2475 539.579 194.2536]
+/Rect [527.6238 185.1478 539.579 194.1041]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.1) >>
>> endobj
-786 0 obj <<
+1002 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 173.1492 539.579 182.1553]
+/Rect [527.6238 173.0496 539.579 182.0058]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.4.5.1.1) >>
>> endobj
-787 0 obj <<
+1003 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 160.9513 539.579 170.0571]
+/Rect [527.6238 160.9513 539.579 169.9076]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.4.5.1.2) >>
>> endobj
-788 0 obj <<
+1004 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 148.8531 539.579 157.9588]
+/Rect [527.6238 148.8531 539.579 157.8094]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.2) >>
>> endobj
-789 0 obj <<
+1005 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 136.7548 539.579 145.8606]
+/Rect [527.6238 136.7548 539.579 145.7111]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.3) >>
>> endobj
-790 0 obj <<
+1006 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 124.6566 539.579 133.7623]
+/Rect [527.6238 124.7562 539.579 133.7623]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.4) >>
>> endobj
-791 0 obj <<
+1007 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 112.5583 539.579 121.6641]
+/Rect [527.6238 112.658 539.579 121.6641]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.5) >>
>> endobj
-792 0 obj <<
+1008 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 100.4601 539.579 109.5658]
+/Rect [527.6238 100.5597 539.579 109.5658]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.5.6) >>
>> endobj
-793 0 obj <<
+1009 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 88.3618 539.579 97.4676]
+/Rect [527.6238 88.4615 539.579 97.4676]
/Subtype /Link
/A << /S /GoTo /D (section.4.6) >>
>> endobj
-794 0 obj <<
+1010 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 76.2636 539.579 85.3693]
+/Rect [527.6238 76.3632 539.579 85.2199]
/Subtype /Link
/A << /S /GoTo /D (section.4.7) >>
>> endobj
-795 0 obj <<
+1011 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 64.1653 539.579 73.1216]
+/Rect [527.6238 64.265 539.579 73.1216]
/Subtype /Link
/A << /S /GoTo /D (section.4.8) >>
>> endobj
-744 0 obj <<
-/D [742 0 R /XYZ 85.0394 794.5015 null]
+960 0 obj <<
+/D [958 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-745 0 obj <<
-/D [742 0 R /XYZ 85.0394 711.9273 null]
+961 0 obj <<
+/D [958 0 R /XYZ 85.0394 711.9273 null]
>> endobj
-741 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R >>
+957 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-798 0 obj <<
-/Length 3163
+1014 0 obj <<
+/Length 3289
/Filter /FlateDecode
>>
stream
-xÚí[wÛ¸Çßý)ôh?Åýò˜ûɶM²±÷¥Û}`dÆÖ‰$z%9©ûé Š8´À‘ÐÆili÷ìÚ‰9œñüÂ`@d#êÿe#¥‰vÜŒ“DQ¦F“ù ]ùŸ½9aí1ãpÐõüâä/¯…9â4×£‹Ï#©ájs2K¨µltqùûé‹÷ï.^½»8?ûãâ—“Wñ¬Ð3£¢>åŸ'¿ÿAG—>€_N(ΪÑ7ÿJ˜s|4?‘J%…3;9?ù5žütcšüM%\hžøU8¿JýCÅFF9¢›_DKØÙ˜qJOß”‹rY¬§‹«³1Wôô¯åÝêll5?%gcåx|_¤sßíd÷¥¦>ëFè.Ÿ[Ú,¯FÍ7¡ZÁn ·ÕÚ>­§[qõSq`¬ Þ+ÒM©Ž¬ð–•óéÕ"‚²¾.›oþQ-üw†ê#1(1!«ÙÄ
-9Îb
-eÉÅ)̳ËË峧åjÕò·ªúr{Óþá·Uzžùšï>–“jcs¹™ì˜Ç@À æ!/ÙšCLs˜w.†5OÄiŽzo5×Îi„‹šó!Í×Uóõ]1/q
-ÞM?}šµÇ¼®–ób3⸟]昊\™¡!"s/Ո̩8™·½3è½m´1„ù2²q®êÊàsqf˜½°‘vzu½þVÖÿŸçU5óÓŠáì>Œý² qow“55œ5p:,[[^S•TkE˜d¶ÉÖf¬+iÌ×pzÚZË;_N¥|Ê%s…¾ìO0Ä>IPŒ‰D¨÷Ȇ„1Ê[6xËÆÇÛE׺)*^å¼ò“.gÔÁͪI ÉÌ&b¤@±0Rq`¤lyOŽ¹‚K]ƒ©nÇÜ­¡¶ëàŠõ´Zr>—Ër1)‡3N¾÷x °ñÍÍpÆÀé°LmyM~¦˜%Æ´«€:Ž·ÉÔ¼ž†¹Å«Y9/k?QÌj¿2ÈGHiö' bŸ,(ÆI"ŒÔ{˜´RMŒÔ*à2ܨü½XO®CQ^Õ¨hÃ=í=TB:³Q†*P.n‡QIÄ¡‚zg\)˜)aÒv°lpõzÈÝb]üël,œ:.­îJLe.(Ð¥'J*Ü{ŠåD[Á
-
-0Ä@Ra $âÀ@A½w HM”íšʱ®l3²”Í
-©Í¦¦³Ã ÂaÌl!ƒ¹Äpωa2n'2³êêªÞI–(TÆyNíZÏQò vÆg£ 1v „<‰80zPï&ýáNwKô¡øÙc¢óÿÙeõÝîËlN€!Æ Ô
-ã$Æ ê=^e’”N¤Ô×#m»myM}W-ìwr],ejÕÏrR)Ý÷ázY¬< ZðÚՄôfà 1x |BÓˆƒõáÎÃb@;UŸ ?\UËÔLGR¢­¹¤ö *TLo.<Ч'ŸÐƒð¤â@àÁ½wðK˜”°FÕ·§î ÏŸ·åòn\.—Õ2µø§,q҆ſ4/´Ô r2™Í 0Ä8J‰áýu©80NPïíLÆ÷ê„1êÓî«š³oË2Å÷ó˜8¨ Mƒ¹Ò|}<¦;%`ˆ¡åÄPJÄ¡„z()I¨e¼C‰?J»gÄ’¹'T¥BZ³‘†2P61¼ +† ê= #9¡Ò©™ÝW4çÅj]&kRÝGI§wöáú°f9!ÇÙü
-Ê8¼U*ö¶+Ìuxo€"‚ƒ&Â>>û< ï)ôœm>óßÝÌÐ7·tZaïm¹Á"ñ]¿cî¼´É–øÿqJñÿýÕÂÝe}k‘ØžÅ-%J+5~þ*š±t:Eî‰ÙBÿíÈTìendstream
+xÚímS#7Çßó)\uo ê¬=K/ Ëæ’ì²ÜÚ{UwI^8f\ñ1ö&äÓŸÆ3­icMƒrû8©Z{ÚÝôÿçVK£±y¯ÿóž6Ìxá{Ö+¦ ®{ãÙAÑ» Ï}{À›súpRŸõÍðà/¥íyæ0½áûžÒš ½y1Ç
+çxoxñãáÉ›³áéÙppôóðûƒÓa|U왲zÉß~ü¹è]„
+½@$B5Dœ/'Bè¯n¯ýëâ?^l~^„&Ò:»o"ï éÌFR¨`¹(TqP¨Þ#™´®D4 "gƒNÿƒ YL§‹zža ±Ÿ’¦Ilf“‚ )R°ZÂv“’ˆƒ"…ô¤hΤjgÌìÛN WÙ CŠ¬ÅA"ŠÒ;p C‡Áu;¸Ø†ƒ;É_ËÛdõÐÊ퇔˜Äl@!‰$é
+D ¤w¸ü©µf…óŒªÁÐw¯x|UPÜáúfÕ\Ëúøõh>º,gå|UÉaŸ$/h@ö²Ñ@†X
+D¤w¨J²ÂÄ9H0nºŽW“ÏÑtrög½-oÓЋõ¥ÐûuÍ4,ÐlX! Œ‚% é`‘œ²P-,MWr¼^…J1YV>”x«MhI´Ú÷"w4f#‚ )D°LÂw#’ˆƒB„ô‡î˜÷Î#¼jÎ8iV»ÿV=TüTèâdy{½Zü: ÇÍ£7ëëëÅ2Œ2V=?p:‰¤fƒ )b°h1‰8(bHïPT
+ŠSÎa:¯g7õ¿¿­'7“UY­{ºG¼ÙóË Kål‚!EVQÝ%â "½sa˜’\õT`ÉË8ªª(r¡ž|³žL/bó溜¯š…hnãvâãÓó¸ýºlž]Ì럯&óõáE¥ú2mhü#s%Ć„„[I”¼SÂT„„´÷VB'˜/¤ÅŠ¿ áàä¸>0EQl 8XLGËI(!^Š/ZÎãßš­$2¤”Ť”LÄA)Izoʹ²sñÒ7çÐ"n‹øÍwg/ê#_ÿø}²ºªªN¡îŒzý ¤,›†ÖŽ‚ "»oæHA¡@¹nßÓÚ1§
+‰`€²œØœ¿ÃD|s7•W®}wŸVmHJ¶ÜÈÒ'<¥8齕\æ
+ÔþÉÅ_¼­ÕÂ<jµ!Ùj#CJmœoJíD”Ú¤w(õR1k‘ÔͲsb®7¬V“‹iÔnß±?„œ&»Ùà´v7H;
+›Ý (j(×
+¬œì¾+ é¨ §[.MK®©\—ãÉûÛ]tÊùåvîà >9^ÌfñŠØtsžü\”}ìY!d&[udH©Ž3/U·ê‰8(ÕIïêÒ;f÷­ê¦VýízÞÞ <ÍÊ‹»³ˆÎ»8î^2~¾v‰cr%Ɔ„Ä[i&$NÅAHL{‡õbé 3º#ˆz½ø»ó¦éaA¸ÞÕ’h½àû‚rœ 2¤
+¤3dH¡‚åRÝZRqP¨Þãe4¡-sº– .²Z¹¯Fõ¥×ûõð‡€©ÌR `©(PqP Þ[P”fÖŽ@ (/ÊjšOÚQ(.y¿»]–_ÉËÏqi$f)›dH1€UPÝnRqP Þa\‘’Y£ÚqEÄ»ˆgõýU íì¾j¨@:³QA†*X.
+•D*¤÷¶\άí¸"öãÊ_R™
+2¤@ÁRQ $â @!½· žÙ‚sÊ~\Ùe
+ª³FãisÎV ÒLðPŸês«ÑªlÛ˜H—ûFjsžÍ2¤xšªî?©8(žHïÀ“•ÌqbS ?Ÿ€§ûÇ2çùÓ«CÛln!Å ÖŽâ&Å é¸1œéЀDnä½ÜŒóÕ²Ú›º ô¬àRÜSŒ´{šŸ£ÐÉä8›dHñƒ5¤øIÄAñCz~”gZ‰vSŸŒŸ4ÒZ<\:9\fs‚ )N°Vª{ãZ*ŠÒ;p"-Ó¼žô½˜Læãéú¢LQb˜õü¾–Çqñ¼ºå&ÃÙð´v;H?
+Ý (r(×
+Ž¨¶+ïÒbŠ0VÐ环Fóy™Zì“Ž)­MsÞùÕrt 0R<«>¦Inþ7*€ù}
+Q8™Ývˆ‰_4Ûž%?Æ·ú—sæµÿÿ÷Ú¶_¿« ÎulÖ®`ÚhÝ“¡G—uñœLº·àÖg¡ÐÿÞÄ
endobj
-797 0 obj <<
+1013 0 obj <<
/Type /Page
-/Contents 798 0 R
-/Resources 796 0 R
+/Contents 1014 0 R
+/Resources 1012 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 715 0 R
-/Annots [ 803 0 R 804 0 R 805 0 R 806 0 R 807 0 R 808 0 R 809 0 R 810 0 R 811 0 R 812 0 R 813 0 R 814 0 R 815 0 R 816 0 R 817 0 R 818 0 R 819 0 R 820 0 R 821 0 R 822 0 R 823 0 R 824 0 R 825 0 R 826 0 R 827 0 R 828 0 R 829 0 R 830 0 R 831 0 R 832 0 R 833 0 R 834 0 R 835 0 R 836 0 R 837 0 R 838 0 R 839 0 R 840 0 R 841 0 R 842 0 R 843 0 R 844 0 R 845 0 R 846 0 R 847 0 R 848 0 R 849 0 R 850 0 R 851 0 R 852 0 R 853 0 R 854 0 R 855 0 R 856 0 R 857 0 R 858 0 R 859 0 R ]
+/Parent 931 0 R
+/Annots [ 1019 0 R 1020 0 R 1021 0 R 1022 0 R 1023 0 R 1024 0 R 1025 0 R 1026 0 R 1027 0 R 1028 0 R 1029 0 R 1030 0 R 1031 0 R 1032 0 R 1033 0 R 1034 0 R 1035 0 R 1036 0 R 1037 0 R 1038 0 R 1039 0 R 1040 0 R 1041 0 R 1042 0 R 1043 0 R 1044 0 R 1045 0 R 1046 0 R 1047 0 R 1048 0 R 1049 0 R 1050 0 R 1051 0 R 1052 0 R 1053 0 R 1054 0 R 1055 0 R 1056 0 R 1057 0 R 1058 0 R 1059 0 R 1060 0 R 1061 0 R 1062 0 R 1063 0 R 1064 0 R 1065 0 R 1066 0 R 1067 0 R 1068 0 R 1069 0 R 1070 0 R 1071 0 R 1072 0 R 1073 0 R 1074 0 R 1075 0 R ]
>> endobj
-803 0 obj <<
+1019 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 758.4766 511.2325 767.4329]
+/Rect [499.2773 758.5763 511.2325 767.4329]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.8.1) >>
>> endobj
-804 0 obj <<
+1020 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 746.445 511.2325 755.4012]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.8.2) >>
>> endobj
-805 0 obj <<
+1021 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 734.5129 511.2325 743.519]
+/Rect [499.2773 734.4133 511.2325 743.3696]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.8.3) >>
>> endobj
-806 0 obj <<
+1022 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 722.4813 511.2325 731.3379]
+/Rect [499.2773 722.3816 511.2325 731.3379]
/Subtype /Link
/A << /S /GoTo /D (section.4.9) >>
>> endobj
-807 0 obj <<
+1023 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 710.3499 511.2325 719.3062]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.9.1) >>
>> endobj
-808 0 obj <<
+1024 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [499.2773 698.3182 511.2325 707.2745]
/Subtype /Link
/A << /S /GoTo /D (subsection.4.9.2) >>
>> endobj
-809 0 obj <<
+1025 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 686.2866 511.2325 695.2428]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.3) >>
+>> endobj
+1026 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 674.2549 511.2325 683.2112]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.4) >>
+>> endobj
+1027 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 675.998 511.2325 684.7301]
+/Rect [499.2773 662.3229 511.2325 671.1795]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.5) >>
+>> endobj
+1028 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 650.2912 511.2325 659.1478]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.6) >>
+>> endobj
+1029 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 638.2595 511.2325 647.1161]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.7) >>
+>> endobj
+1030 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 626.2278 511.2325 635.0845]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.8) >>
+>> endobj
+1031 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 614.0965 511.2325 623.0528]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.9) >>
+>> endobj
+1032 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 602.0648 511.2325 611.0211]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.10) >>
+>> endobj
+1033 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 590.0331 511.2325 598.9894]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.11) >>
+>> endobj
+1034 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 578.0015 511.2325 586.9578]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.12) >>
+>> endobj
+1035 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 565.9698 511.2325 574.9261]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.9.13) >>
+>> endobj
+1036 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 553.9381 511.2325 562.8944]
+/Subtype /Link
+/A << /S /GoTo /D (section.4.10) >>
+>> endobj
+1037 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 541.9064 511.2325 550.8627]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.10.1) >>
+>> endobj
+1038 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 529.8748 511.2325 538.831]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.10.2) >>
+>> endobj
+1039 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 517.8431 511.2325 526.7994]
+/Subtype /Link
+/A << /S /GoTo /D (section.4.11) >>
+>> endobj
+1040 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 505.8114 511.2325 514.7677]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.11.1) >>
+>> endobj
+1041 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 493.7797 511.2325 502.8855]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.4.11.1.1) >>
+>> endobj
+1042 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 481.7481 511.2325 490.8538]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.4.11.1.2) >>
+>> endobj
+1043 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 469.7164 511.2325 478.6727]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.11.2) >>
+>> endobj
+1044 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 457.6847 511.2325 466.641]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.4.11.2.1) >>
+>> endobj
+1045 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 445.653 511.2325 454.6093]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.4.11.2.2) >>
+>> endobj
+1046 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 433.6213 511.2325 442.5776]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.11.3) >>
+>> endobj
+1047 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 421.5897 511.2325 430.5459]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.11.4) >>
+>> endobj
+1048 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 409.558 511.2325 418.6637]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.11.5) >>
+>> endobj
+1049 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 397.5263 511.2325 406.6321]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.11.6) >>
+>> endobj
+1050 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 385.4946 511.2325 394.4509]
+/Subtype /Link
+/A << /S /GoTo /D (section.4.12) >>
+>> endobj
+1051 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 373.4629 511.2325 382.4192]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.12.1) >>
+>> endobj
+1052 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 361.4313 511.2325 370.3876]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.4.12.2) >>
+>> endobj
+1053 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [499.2773 339.111 511.2325 347.8432]
/Subtype /Link
/A << /S /GoTo /D (chapter.5) >>
>> endobj
-810 0 obj <<
+1054 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 663.9862 511.2325 672.9425]
+/Rect [499.2773 327.0992 511.2325 336.0555]
/Subtype /Link
/A << /S /GoTo /D (section.5.1) >>
>> endobj
-811 0 obj <<
+1055 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 651.9545 511.2325 660.9108]
+/Rect [499.2773 315.0676 511.2325 324.0238]
/Subtype /Link
/A << /S /GoTo /D (section.5.2) >>
>> endobj
-812 0 obj <<
+1056 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 629.7788 511.2325 638.3664]
+/Rect [499.2773 292.7473 511.2325 301.4795]
/Subtype /Link
/A << /S /GoTo /D (chapter.6) >>
>> endobj
-813 0 obj <<
+1057 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 617.7222 511.2325 626.5788]
+/Rect [499.2773 280.7355 511.2325 289.6918]
/Subtype /Link
/A << /S /GoTo /D (section.6.1) >>
>> endobj
-814 0 obj <<
+1058 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 605.5908 511.2325 614.5471]
+/Rect [499.2773 268.7038 511.2325 277.8096]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.1.1) >>
>> endobj
-815 0 obj <<
+1059 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 593.5591 511.2325 602.5154]
+/Rect [499.2773 256.6722 511.2325 265.7779]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.1.1.1) >>
>> endobj
-816 0 obj <<
+1060 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 581.5275 511.2325 590.4837]
+/Rect [499.2773 244.7402 511.2325 253.7462]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.1.1.2) >>
>> endobj
-817 0 obj <<
+1061 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 569.4958 511.2325 578.4521]
+/Rect [499.2773 232.7085 511.2325 241.7146]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.1.2) >>
>> endobj
-818 0 obj <<
+1062 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 557.4641 511.2325 566.4204]
+/Rect [499.2773 220.6768 511.2325 229.6829]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.1.2.1) >>
>> endobj
-819 0 obj <<
+1063 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 545.4324 511.2325 554.3887]
+/Rect [499.2773 208.6451 511.2325 217.6512]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.1.2.2) >>
>> endobj
-820 0 obj <<
+1064 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 533.4007 511.2325 542.357]
+/Rect [499.2773 196.6134 511.2325 205.6195]
/Subtype /Link
/A << /S /GoTo /D (section.6.2) >>
>> endobj
-821 0 obj <<
+1065 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 521.3691 511.2325 530.4748]
+/Rect [499.2773 184.4821 511.2325 193.5878]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.1) >>
>> endobj
-822 0 obj <<
+1066 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 509.3374 511.2325 518.4431]
+/Rect [499.2773 172.4504 511.2325 181.5562]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.2) >>
>> endobj
-823 0 obj <<
+1067 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 497.3057 511.2325 506.4115]
+/Rect [499.2773 160.4187 511.2325 169.5245]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.3) >>
>> endobj
-824 0 obj <<
+1068 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 485.274 511.2325 494.2303]
+/Rect [499.2773 148.4867 511.2325 157.4928]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.4) >>
>> endobj
-825 0 obj <<
+1069 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 473.2424 511.2325 482.1986]
+/Rect [499.2773 136.4551 511.2325 145.4611]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.5) >>
>> endobj
-826 0 obj <<
+1070 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 461.2107 511.2325 470.167]
+/Rect [499.2773 124.3237 511.2325 133.4295]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.6) >>
>> endobj
-827 0 obj <<
+1071 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 449.179 511.2325 458.1353]
+/Rect [499.2773 112.292 511.2325 121.3978]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.7) >>
>> endobj
-828 0 obj <<
+1072 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 437.1473 511.2325 446.1036]
+/Rect [499.2773 100.2604 511.2325 109.3661]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.8) >>
>> endobj
-829 0 obj <<
+1073 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 425.1157 511.2325 434.0719]
+/Rect [499.2773 88.2287 511.2325 97.3344]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.9) >>
>> endobj
-830 0 obj <<
+1074 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 413.084 511.2325 422.0403]
+/Rect [499.2773 76.197 511.2325 85.3027]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.10) >>
>> endobj
-831 0 obj <<
+1075 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 401.0523 511.2325 410.158]
+/Rect [499.2773 64.1653 511.2325 73.2711]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.10.1) >>
>> endobj
-832 0 obj <<
+1015 0 obj <<
+/D [1013 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+1012 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1078 0 obj <<
+/Length 3422
+/Filter /FlateDecode
+>>
+stream
+xÚíYSIÇßùz˜xPmÝÇ>­m°ƒ íÁ8vcŽ…hƒb„ÄHÂÇ~ú­VwUeCuŠÚlˆ‰ËX©LåÿGYG³õÿ±U„
+'ÆI¢(Sƒñåœû{µÇÚ÷ Û†ð]ÏO÷þñR˜#Ns=8ý>Ëj-œžýºÿâí›Ó£7§ï~?ýqïè4~(t̨¨?ñϽ_§ƒ3ïÿÇ=J„³jðÙÿ…æ\îI%ˆ’B„ŸL÷Þïý?üëÚ4÷E”°DYn2ß„sðM˜’ÄãF9¢믢 ÷¡~àB÷O/ªú;yK,5%”IãÝÕãѪ:Ÿ/¾¶o„.$%Ú†÷½»XŒ–ÕÁPR»O†ŠÒú‡tîÿ±»¡½â–hNYJï-±çƒæÅ ”/Ø ¡ámùn~dioÅpÈÅÁƒzOðHC´fÂ#îÏŸ×Õâë°Z,æ‹e e‰“V´o~HóñGKM/'!“Åœ
+y-¦bÔ@Ýï§&F ê=QÃ1ÒH"5b#5—£åªÊöMÂs#½O¼2½ú»
+9.&bA 1‚2q`¡Þ#AÚ¹fØ ’÷EÐæ–Ç}Ÿ–§˜>Rb.KI†)­Rrq ¤àÞ)ÖKAS£6‚2¿ªµÎ‚¢ýg1³¡©±ŒíTSR\ÌO²Ãðbô܃sØ1ŠX¡Y‚Gß<wheŒ|Ô­LÈe1%ÀÃj¥T?'™80PPïqö­µ V+H!¬™}?ŸÏ§Õ¨õmK‡÷à¶rtGBºŠa
+ÝB& Ô{â×Ù€ðl<®–Ë‚óÙjÝ^̧u§±CÍD/!qÅX
+`ˆQÑÑ¥í/Fê=R¡¯×·¤Â4Tü2ŸU §Žî/F³åÇõ Bö„EL\)ÐÁ¢#ŒéŸ‡äâ@°À½',,%Tw¨° ß5P¼›/ÚÄëÉrUc!ŸZ‹˜¸b*’Åô´2A`H`®Úê,,h× ñöªZŒVëIézòñu¹ª.›×'Õr~½îPÆU€årRÓb¥z\«±1ÅÒCL[˜`LÜL˜º¨÷$¯Ò„qÓ­BQ?ˆ³ÉM‚¦·äW¼—€£b€!F
+M»uÛ¨ÿììl½Éi4 «Üãô+ýb4¾XwNëí)9Ät 1¥aºm•9¦5ê=‰--ÖuK®»^½Ž[Ü^ú_ûvH(„Øá±`ÌX1Àã*bû„äâÀx@½'„&’ÙÎÞ!OªåÕ|¶¬ÂâÃt2móê7ªèÉ»_ü,T+?/&MeZ2ùà»õðõ‹Å†˜¸0½¶¿Âœ‹õwÄJ.‰”—ÌƱí .S, ž ½ñà7Û<=èå(dº˜#`ˆq•´ýEÊ\G¨÷ÄãD JPöž8Ú¼±Úºm(<ÅŒó 1^ b¶¿d™‹ãõžx¡”(ª@áÉmæŃ0Y®&ãåp|1šÍªinW¾UD*ë64B’›-8Ù³XÌ0Ä*Ùþâd.ŒÔ{dDXo d*Bqú-ÙÜÀ(÷‘èc!f«”hˆ°ÐQa!Âî=±`4Q:AùæCî«ÅõrU ÿ¨¾öÝ€Àí¦ÁŠ•[; )-æ%Ùa¸
+‹á
+n~~­£ý;_s àîc/ÀêgÈpg#¼í'ËñuFïŸþ“i!$ÝÉg! C‹†"P#‘L "¨û„ˆ„ÖûÄ"¢Eä}µJ7«œž¾^ƒ ŸF˜å
+§èŽß}òoæVìðd$hØ&±‘d‡$B¹Ææ;á!a,^ï#ê‹!×|¼]]„S²7§¾ë¥”I3(¯&ŸêÉŠl—;¡Åb@€!FT‰Ñþò¹@0FP÷i¸* a2Þ
+bPAUQ¨2`P¡îTÜSd”Pñ¨~x{rüêøMîÁ„†/Œé4TC÷€Èú»vA=CB‹y†/P0”—L /¨ûÄ óó#*àE”ðrüæÅë‡G¹Õ~$®E0\l_wRYL
+0ÄHR¡¤dÁHAÝ'R(#\ H‘%¤øÙTng‰&VºJŒR»5 ).&bA í?¼‘ #uGÅÖ®y*ÏévPüüøÍa˜1Õþº9*>ú²ªfuÙæŸ~DÌèþ*‹3ÚƒªÂ6É^½9:yV×ýNsÍ“öó<*d<ýŠ?} „L•r
+endobj
+1077 0 obj <<
+/Type /Page
+/Contents 1078 0 R
+/Resources 1076 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 931 0 R
+/Annots [ 1080 0 R 1081 0 R 1082 0 R 1083 0 R 1084 0 R 1085 0 R 1086 0 R 1087 0 R 1088 0 R 1089 0 R 1090 0 R 1091 0 R 1092 0 R 1093 0 R 1094 0 R 1095 0 R 1096 0 R 1097 0 R 1098 0 R 1099 0 R 1100 0 R 1101 0 R 1102 0 R 1103 0 R 1104 0 R 1105 0 R 1106 0 R 1107 0 R 1108 0 R 1109 0 R 1110 0 R 1111 0 R 1112 0 R 1113 0 R 1114 0 R 1115 0 R 1116 0 R 1117 0 R 1118 0 R 1119 0 R 1120 0 R 1121 0 R 1122 0 R 1123 0 R 1124 0 R 1125 0 R 1126 0 R 1127 0 R 1128 0 R 1129 0 R 1130 0 R 1131 0 R 1132 0 R 1133 0 R 1134 0 R 1135 0 R 1136 0 R 1137 0 R 1138 0 R ]
+>> endobj
+1080 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 389.0206 511.2325 397.9769]
+/Rect [527.6238 758.4766 539.579 767.5824]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.10.2) >>
>> endobj
-833 0 obj <<
+1081 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 376.9889 511.2325 385.9452]
+/Rect [527.6238 746.5057 539.579 755.462]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.10.3) >>
>> endobj
-834 0 obj <<
+1082 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 364.9573 511.2325 373.9135]
+/Rect [527.6238 734.5349 539.579 743.6406]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.11) >>
>> endobj
-835 0 obj <<
+1083 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 352.9256 511.2325 361.8819]
+/Rect [527.6238 722.564 539.579 731.5203]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.12) >>
>> endobj
-836 0 obj <<
+1084 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 340.8939 511.2325 349.8502]
+/Rect [527.6238 710.5931 539.579 719.5494]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.13) >>
>> endobj
-837 0 obj <<
+1085 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 328.8622 511.2325 337.8185]
+/Rect [527.6238 698.6222 539.579 707.5785]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.14) >>
>> endobj
-838 0 obj <<
+1086 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 316.8305 511.2325 325.7868]
+/Rect [527.6238 686.6513 539.579 695.6076]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.15) >>
>> endobj
-839 0 obj <<
+1087 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 304.8985 511.2325 313.9046]
+/Rect [527.6238 674.6804 539.579 683.6367]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.16) >>
>> endobj
-840 0 obj <<
+1088 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 292.8669 511.2325 301.873]
+/Rect [527.6238 662.7096 539.579 671.6658]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.1) >>
>> endobj
-841 0 obj <<
+1089 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 280.7355 511.2325 289.8413]
+/Rect [527.6238 650.7387 539.579 659.695]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.2) >>
>> endobj
-842 0 obj <<
+1090 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 268.7038 511.2325 277.8096]
+/Rect [527.6238 638.7678 539.579 647.7241]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.3) >>
>> endobj
-843 0 obj <<
+1091 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 256.6722 511.2325 265.7779]
+/Rect [527.6238 626.7969 539.579 635.7532]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.4) >>
>> endobj
-844 0 obj <<
+1092 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 244.6405 511.2325 253.7462]
+/Rect [527.6238 614.826 539.579 623.7823]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.5) >>
>> endobj
-845 0 obj <<
+1093 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 232.6088 511.2325 241.5651]
+/Rect [527.6238 602.8551 539.579 611.8114]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.6) >>
>> endobj
-846 0 obj <<
+1094 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 220.5771 511.2325 229.5334]
+/Rect [527.6238 590.8843 539.579 599.8405]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.7) >>
>> endobj
-847 0 obj <<
+1095 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 208.5455 511.2325 217.5017]
+/Rect [527.6238 579.013 539.579 587.8696]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.8) >>
>> endobj
-848 0 obj <<
+1096 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 196.5138 511.2325 205.4701]
+/Rect [527.6238 567.0421 539.579 575.8988]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.9) >>
>> endobj
-849 0 obj <<
+1097 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 184.4821 511.2325 193.4384]
+/Rect [527.6238 554.9716 539.579 563.9279]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.10) >>
>> endobj
-850 0 obj <<
+1098 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 172.4504 511.2325 181.4067]
+/Rect [527.6238 543.0007 539.579 551.957]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.11) >>
>> endobj
-851 0 obj <<
+1099 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 160.4187 511.2325 169.375]
+/Rect [527.6238 531.1295 539.579 540.1356]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.12) >>
>> endobj
-852 0 obj <<
+1100 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 148.3871 511.2325 157.3433]
+/Rect [527.6238 519.0589 539.579 528.0152]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.13) >>
>> endobj
-853 0 obj <<
+1101 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 136.3554 511.2325 145.3117]
+/Rect [527.6238 507.0881 539.579 516.0443]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.14) >>
>> endobj
-854 0 obj <<
+1102 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 124.3237 511.2325 133.28]
+/Rect [527.6238 495.1172 539.579 504.0735]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.15) >>
>> endobj
-855 0 obj <<
+1103 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 112.292 511.2325 121.2483]
+/Rect [527.6238 483.1463 539.579 492.1026]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.16) >>
>> endobj
-856 0 obj <<
+1104 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 100.2604 511.2325 109.2166]
+/Rect [527.6238 471.1754 539.579 480.1317]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.17) >>
>> endobj
-857 0 obj <<
+1105 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 88.2287 511.2325 97.185]
+/Rect [527.6238 459.2045 539.579 468.1608]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.2.16.18) >>
>> endobj
-858 0 obj <<
+1106 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 76.197 511.2325 85.3027]
+/Rect [527.6238 447.2336 539.579 456.3394]
/Subtype /Link
-/A << /S /GoTo /D (subsection.6.2.17) >>
+/A << /S /GoTo /D (subsubsection.6.2.16.19) >>
>> endobj
-859 0 obj <<
+1107 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [499.2773 64.1653 511.2325 73.1216]
+/Rect [527.6238 435.2628 539.579 444.219]
/Subtype /Link
-/A << /S /GoTo /D (subsection.6.2.18) >>
+/A << /S /GoTo /D (subsubsection.6.2.16.20) >>
>> endobj
-799 0 obj <<
-/D [797 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-796 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R >>
-/ProcSet [ /PDF /Text ]
+1108 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [527.6238 423.2919 539.579 432.2481]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.6.2.17) >>
>> endobj
-862 0 obj <<
-/Length 3454
-/Filter /FlateDecode
->>
-stream
-xÚí[SÜFÇßùó°U túªîÞ}ØÅ€R1ö©lm’‡ñŒ *3™ Äûé·5R·Î0­3ô&&®Š1èèœ9ÿŸNßP÷‡ Œ"TX9ÐVE™Œ&;tpé~öf‡µ×ìû‹öáU¯.v¾y-ôÀ›ñlpñÜËj \ŒÚ=|wzq|zq¾÷ËÅw;Çá¦Ð1£¢¾ã¯;?ýBcçÿ»J„5jpçþA ³–&;R ¢¤þ;×;ç;ÿ
-7?]šÆ>ˆ†(Ãuä“p> 㜫]tÊ’Lp±ü(áÎqýAÜå \.1†J磾l6΋ټÍöGWò̯g­ _M–Tƶ6çÎ&Ÿäå|oŸ+ºûf:œL†Ó½}Éõ.ÙÛW”>â_ÒÚ‡]yObÅ É8e]×4™^š/ΠJÞn®«´~ÿ¥JÙZ^õX#¨÷Ž©‰R”F8ý39ʦ”—ż¨Êæ;ÃrÜ|ñÃlx™;Qì#"ÑË‚ÏV2 ÀcaE „…H ¨÷Žá$Ë `mda>]ÌæùxÿSþ92Är“m(FÒÇ/©õâÄøœ& 1bV4Cˆ‰Äƒzïˆá‚“±ŽþE‰Ù\6¸O““^@|
-“† +!€DâÀ
-º#D´„œçóyQ^¶­úÅ÷K䶙ÎÏp2?Àã*ˆñ‰ãõÞñ#9aîÚÀlù9)oó©ï¾ÞܘŠ¶æœ¼¿us#¶C‘ÅdF€!ÆTÉ°~F"q`Œ Þ;F%T‹ŽÕ2òn~•Oî~—K*EÓ-Í‹Ûz¸"${ÉíÏb2#Àcª„1‰cõÞõW™&Ö2Ñ1†/nHY±ËÜm™ô‹qÿŒ,×¹¯÷üLÎ÷gÅeé¾dõì
-Û¶M!ëÉLCŒ)¨*ÆT$Œ)Ô{ÇUÄR ™â LýåÝÙÉ›“ÓYR»®•ûNsÝJ™ÚÛ·O¬?xdHh2.ÀÃ
-†á‰Ãõp‘Vw=¸ˆ\NN¿ÿáè8¶Rš‰>^¸xvmUHe*(ÐeE*Ó¿j‹÷ÞbÑRAPd
-(n4Û]’#m$úq–z­CRœ 0Ä
-dD?‘80<Pï~XJ×°X¿ M¶ËÄu° çá —Ëß®ÿnšÚ„'ÃÔÙa,91”ÖƒÀHÂ\w=!ˆd~-Xº2¸^c©«8Öð—8.öùJ¡³Ã@
-꽫Ô®8@%ÓáÄW|z뻩ýIn¾j}&’u†˜Î0Ó¦3Z,LgÔ{ÐYXM˜¦èìgɺIù·ÃÂiYËQ¾IlWfžú<VøÈ©‚BCDЕ”šþ­±8Aqï õ‹-Œ‚
-°èú¬Éøó)Ó!ÉjCLm˜oLíH˜Ú¨÷Nm]ß3 Ôö“QçÕèSÞO:ùæÝ&ѳ?yyÿ ©íó‘¬60ÄÔ†ù6ý‡!cq`j£Þ;µ3J,—PmÕª}XMnœ´Šëbþ¹Ñö®˜_5>®ôµ3P<9é™ÔD„Ãnf ñÔz…½@ø”% 1  $¦ÿhc, ˆ5ï,ò¢#ᮚ7‹¶õä]™Eôóùh1 TVå¬çÓasܤ7oþÖ.€‡å ¬G¼~ße¾úwÄÁÛayZó›Jõù,KÛ<-;²õ\ÊÁh”ÏB!,ç˩ϪsûÞ•ÉåÏävb%ý©ó O~ê€!öÔAA1Š"q`4¡ÞMLN§)öº7à¶L²¶|^M«j)²BêÆcíeõûÈt¾%BiáçóE1ŽÝʸ޾4íe/üàÈÿC¬5™X`ˆ ¡±ýûôbq`Ä¢ÞÃÄ œ0ž lw$º„¤˜ãÒxæF½øº±b]{›ËŽËÛfñ¨*›sñ"/§ örå3ŸÌ0ĸ‚Êb\EâÀ¸B½®\±t¤ÈŽ+¿Ãü‡YØð_¥Ô™»ó¥oÖ[Ö(Ñ4¬¿^”£æ R¿„ƶªöT¨ !ÕŠ¬T±8¨pï¾yåZ×ßã-Sþ|dï‰Ø®{«U¶«Žãsš 0Ä€šaÀDâÀ€Yóq¥Hû>+ÓŽ.öc»Ójñá:Ÿ]¹Ö«®F½Éiì:Ðé.G†9 &Û¿Ø×Ý
-KÂ=ÑgF
-"xû¾8‡ÕdâÏø¼oÚf—I=€—r;žIŒ|š“#`ˆ=FPFŒ›HA¨÷®1¯ûsRˆB'ñdþ×v”\Ví„â]5ýäž©¿7ÿºªîš/FCº£ù«~)Òesø´­ÖÕÂßájn{×ö/ÿáŠ83O©¥õ9IVbŠÃœcŠGâÀG½‡ªáÆ–,kߊb–}·ºjœ”£F±ººqáø÷áÕ°¼\éÝùµÀÂïW:]L>ÔË "³Ï  Ò”Ì
-endobj
-861 0 obj <<
-/Type /Page
-/Contents 862 0 R
-/Resources 860 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 715 0 R
-/Annots [ 864 0 R 865 0 R 866 0 R 867 0 R 868 0 R 869 0 R 870 0 R 871 0 R 872 0 R 873 0 R 874 0 R 875 0 R 876 0 R 877 0 R 878 0 R 879 0 R 880 0 R 881 0 R 882 0 R 883 0 R 884 0 R 885 0 R 886 0 R 887 0 R 888 0 R 889 0 R 890 0 R 891 0 R 892 0 R 893 0 R 894 0 R 895 0 R 896 0 R 900 0 R 901 0 R 902 0 R 903 0 R 904 0 R 905 0 R 906 0 R 907 0 R 908 0 R 909 0 R 910 0 R 911 0 R 912 0 R 913 0 R 914 0 R 915 0 R 916 0 R 917 0 R 918 0 R 919 0 R 920 0 R 921 0 R ]
+1109 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [527.6238 411.321 539.579 420.4267]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.6.2.18) >>
>> endobj
-864 0 obj <<
+1110 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 758.4766 539.579 767.4329]
+/Rect [527.6238 399.3501 539.579 408.3064]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.19) >>
>> endobj
-865 0 obj <<
+1111 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 746.3946 539.579 755.3509]
+/Rect [527.6238 387.3792 539.579 396.3355]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.20) >>
>> endobj
-866 0 obj <<
+1112 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 734.3125 539.579 743.2688]
+/Rect [527.6238 375.4083 539.579 384.3646]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.21) >>
>> endobj
-867 0 obj <<
+1113 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 722.2305 539.579 731.1868]
+/Rect [527.6238 363.4374 539.579 372.3937]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.22) >>
>> endobj
-868 0 obj <<
+1114 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 710.1484 539.579 719.1047]
+/Rect [527.6238 351.4666 539.579 360.4228]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.23) >>
>> endobj
-869 0 obj <<
+1115 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 698.0664 539.579 707.0227]
+/Rect [527.6238 339.4957 539.579 348.452]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.24) >>
>> endobj
-870 0 obj <<
+1116 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 685.9843 539.579 694.9406]
+/Rect [527.6238 327.5248 539.579 336.4811]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.25) >>
>> endobj
-871 0 obj <<
+1117 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 673.9023 539.579 682.8586]
+/Rect [527.6238 315.5539 539.579 324.5102]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.2.26) >>
>> endobj
-872 0 obj <<
+1118 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 661.8203 539.579 670.7765]
+/Rect [527.6238 303.583 539.579 312.5393]
/Subtype /Link
-/A << /S /GoTo /D (subsubsection.6.2.26.1) >>
+/A << /S /GoTo /D (subsection.6.2.27) >>
>> endobj
-873 0 obj <<
+1119 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 649.8379 539.579 658.6945]
+/Rect [527.6238 291.6121 539.579 300.7179]
/Subtype /Link
-/A << /S /GoTo /D (subsubsection.6.2.26.2) >>
+/A << /S /GoTo /D (subsection.6.2.28) >>
>> endobj
-874 0 obj <<
+1120 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 637.7558 539.579 646.6124]
+/Rect [527.6238 279.6413 539.579 288.747]
/Subtype /Link
-/A << /S /GoTo /D (subsubsection.6.2.26.3) >>
+/A << /S /GoTo /D (subsubsection.6.2.28.1) >>
>> endobj
-875 0 obj <<
+1121 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [527.6238 267.6704 539.579 276.6267]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.6.2.28.2) >>
+>> endobj
+1122 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [527.6238 255.6995 539.579 264.6558]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.6.2.28.3) >>
+>> endobj
+1123 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 625.5741 539.579 634.5304]
+/Rect [527.6238 243.7286 539.579 252.6849]
/Subtype /Link
-/A << /S /GoTo /D (subsubsection.6.2.26.4) >>
+/A << /S /GoTo /D (subsubsection.6.2.28.4) >>
>> endobj
-876 0 obj <<
+1124 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 613.4921 539.579 622.4483]
+/Rect [527.6238 231.7577 539.579 240.714]
/Subtype /Link
/A << /S /GoTo /D (section.6.3) >>
>> endobj
-877 0 obj <<
+1125 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 601.41 539.579 610.3663]
+/Rect [527.6238 219.7868 539.579 228.7431]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.1) >>
>> endobj
-878 0 obj <<
+1126 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 589.328 539.579 598.2842]
+/Rect [527.6238 207.8159 539.579 216.7722]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.1.1) >>
>> endobj
-879 0 obj <<
+1127 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 577.2459 539.579 586.2022]
+/Rect [522.6425 195.845 539.579 204.9508]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.1.2) >>
>> endobj
-880 0 obj <<
+1128 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 565.1639 539.579 574.1201]
+/Rect [522.6425 183.8742 539.579 192.9799]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.2) >>
>> endobj
-881 0 obj <<
+1129 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 553.0818 539.579 562.0381]
+/Rect [522.6425 171.9033 539.579 181.009]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.3) >>
>> endobj
-882 0 obj <<
+1130 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 540.9998 539.579 550.1055]
+/Rect [522.6425 159.9324 539.579 169.0381]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.4) >>
>> endobj
-883 0 obj <<
+1131 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 528.9177 539.579 538.0235]
+/Rect [522.6425 147.9615 539.579 157.0673]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.5) >>
>> endobj
-884 0 obj <<
+1132 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 516.8357 539.579 525.9414]
+/Rect [522.6425 135.9906 539.579 145.0964]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.5.1) >>
>> endobj
-885 0 obj <<
+1133 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 504.7536 539.579 513.8594]
+/Rect [522.6425 124.0197 539.579 133.1255]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.5.2) >>
>> endobj
-886 0 obj <<
+1134 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 492.6716 539.579 501.6279]
+/Rect [522.6425 112.0489 539.579 121.1546]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.5.3) >>
>> endobj
-887 0 obj <<
+1135 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 480.5895 539.579 489.5458]
+/Rect [522.6425 100.078 539.579 109.1837]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.3.5.4) >>
>> endobj
-888 0 obj <<
+1136 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 468.5075 539.579 477.4638]
+/Rect [522.6425 88.1071 539.579 97.2128]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.6) >>
>> endobj
-889 0 obj <<
+1137 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 456.4254 539.579 465.3817]
+/Rect [522.6425 76.1362 539.579 85.242]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.3.7) >>
>> endobj
-890 0 obj <<
+1138 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 444.3434 539.579 453.2997]
+/Rect [522.6425 64.1653 539.579 73.2711]
/Subtype /Link
/A << /S /GoTo /D (section.6.4) >>
>> endobj
-891 0 obj <<
+1079 0 obj <<
+/D [1077 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+1076 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1141 0 obj <<
+/Length 3413
+/Filter /FlateDecode
+>>
+stream
+xÚímsÛÆÇßëSð]¥™êŒ{Ƶ/:–§J'•”éLÓ¼€HˆBM4AZã~úˆ»ãR<lt±[6ãÉ’°Øåþ·¸'€t”Ùt$Q†™‘6‚ÈŒÊÑx~”¦öoßQwÌ©?èuv}ôì%×#CŒbjt};R&7'ËI–çtt=ùåøüÇW×ß¼º¾:ùõú»£o®ÃY¡gšñî”oŽ~ù5Ml
+eŠNÅHKCg|óQìïˆu}rJ¹ÌŽ¯ïÊ“Sfß\­ŠUÕ®ªqÛÿü²šÙ¿˜œ““S™eŸÛ‹0æýÏò@Ma¬öÆæ)$l/ýËé¨s  v§Ðp_ýów‚ÐLïa厂ñ€ºï`‘t¤…¶¯ 4t,°lóf]¯Ê¥ý)ÏÌgŠÁ''Å'3™`ˆ‘Å¢Y>LJ$ŒÔý¶rpI„Ê+¡r¼*æ¾t”Ë·å2^F¶ –?½…ö™HbBÃL£BGÁ„FÝo…fœð\Q 4sBÿ»©Ð?•³.êqù[j->aõ9YQ`ˆ)
+SJ33¬h$LQÔýVQJ ÏT”;E/˶™=¢ÉæŠ=½‚=(·ÏG²ÜÀ“æ•;&7ê>È­Œ!ŒÁB-œÚWÍøu¹êµ½xöão‰®2ñ¨íÓ‘*6°C´†É¦4”:¢4ê{+t®‰}Ùê,ÎçÍ|aE½©fÕê]¯ê}µºë‚³c³s.M„É”  ;ÍÙÅ«ýQ;íAÜhwL¾‡ ÿܺ„ƒ(ô K&!˜a lÅ ”s°†ÁÇ8öãM¥l_>×ùƳ¶
+’¹E‡IîG¨›QÐõ‰‰/›õͬlïìõ«+HCù gxì` ƒÈ(^àçCò±ï6Ö‚¤2Ýâa?/‘‡ÁÎy3Ÿwųk4?õj››y7ˆâ0¶InT!Í©
+"jGFžH D¨{we—R¡h`(t/Vræºq³‰÷Íòµm]íºkîû7ãÂÁvÑ¿ü'ËØt½Ï•îfíÏpW„ÓÞ»>äôo¶¢ÓüP0(¸ÏI²àÀæ<&8ê>T ! ×Æ+Î\Õ¸¨Ç½d]Ÿ>t꺑j?krWÔÓ¾ž_ ¬
+7òj=¿é¬“'T
+!ðiJ†
+%Òþ.P {
+Âc&uKÆM} ¢ r}((2>«ÉÈ
+ u¿:“„Ë
+Ív„>-Úwõ8Yn-Žÿ¼³'Ó-v'»sû*›u;{×íÑbï)‘ÿ ÉCL"˜#ʆ7/ÅÁ$B݉˜á„©(Äwòs¶—7¬S˜ïZ-‹º-Æ~x‘gÕæ&)“ñOÓÄüL•Ø!êÁôaâE¢@´C}o¥Ë)¡¹Ò‰]é¦Eå$›–«n…¼ªo›nI«_ÎÚÙ,c¨‹y¹Ä*¬‘›‰•[rùñ5sŸ,Y³­¦ÈªÙ~˜f˜ï­fÊtON3@4¹+ÚzsÏÏpS›À„Öà!ßÒº÷‹¾N—ÅüäTï,[~¨ Âá“$‹ 1•`¦(~BP,L'ÔýV(©IÆ(J9¡êÖ¥÷ÆË4iæEU?«Ã3¢ZðŒ¨ñ]9~í¨jߪ–óvw'ÛåËóþÈ´H¿ËkP'ÿA’u†˜N0Q” o‹‚鄺w£ &1Ül/_ºmì,»ìl³I×™<l4³âÓ™Ì
+0ÄXr¡¬DÁXÙsÛ¨Í#<×}á?ë¶sðãŠzí÷.Š)²_;X?v¿64@ökïDEùðSUàù°\ì¹­c2{¼í!ö«bg›e)nŽ'ÕôËØñðäæ„‚É-b-êR £ uïi£&'ŒqOëi»kºž¥ÔÜþpÜ‚ ©¸AC·Á)žwˆ‚à†»¸åŠPáTu¶YúêŠ[ݶåøtÒÞö½·ùëÒvxžhúÝùD'c 1Œ ”b`¡îFZL‘ØÁÈÂã9š7åì‰?5ø°ã³›Ì0ÄØêQ1¼Ç4Æê>°£(1ZsÇŽ|Èδìömy¸®} š|¾“i†MPO*Ø0M‘@0šP÷&aHn¤§IíÐÔmß6¯»µWID} ¢|Γ‰†QPS*.R$Œ(Ô} Šk’Sî‰Ò;DµåjUuSY‡õápò OÆ b8AA©žÕŽ‚ᄺ81I4wô8#ù.NÕ´þßæ©êBðHï ’Ou2HÀ Ji‹É0H‘@0P÷$ʉƃdzº‰õÉéf"½ßm¤$;ô» ò9N&bA ©~fm,Œ Ô} (£D*÷03B³nôB®ÉCúýù$'# 1„ ˆTß´ CuïÊ ¹ Q@æy˜¡üø3”^ƒTÀ€ÂT˜ÊáÎR$
+„.Ô·‡Kk"2ßï¦ V§ÿ6ëe]Ì˪[ÇJðIÿÞ“>½ÉßzÌ°ï<ÙJGÕð„Ò~Ø÷ Ž·Oõ'~ŸE†;dZ¿ùCjq(Eó‰é}úÓŸðO~{ƒ&Cj?„=¤ÂW)ž2Cò<ú}öJŒ”ìý¿¹qû“Bž}ãÓ†°,Ó£î{¹Üè´z‹ÜÄ°9
+„þ¿í†endstream
+endobj
+1140 0 obj <<
+/Type /Page
+/Contents 1141 0 R
+/Resources 1139 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 931 0 R
+/Annots [ 1143 0 R 1144 0 R 1145 0 R 1146 0 R 1147 0 R 1148 0 R 1152 0 R 1153 0 R 1154 0 R 1155 0 R 1156 0 R 1157 0 R 1158 0 R 1159 0 R 1160 0 R 1161 0 R 1162 0 R 1163 0 R 1164 0 R 1165 0 R 1166 0 R 1167 0 R 1168 0 R 1169 0 R 1170 0 R 1171 0 R 1172 0 R 1173 0 R 1174 0 R 1175 0 R 1176 0 R 1177 0 R 1178 0 R 1179 0 R 1180 0 R 1181 0 R 1182 0 R 1183 0 R 1184 0 R 1185 0 R 1186 0 R 1187 0 R 1188 0 R 1189 0 R 1190 0 R 1191 0 R 1192 0 R 1193 0 R 1194 0 R 1195 0 R 1196 0 R 1197 0 R 1198 0 R 1199 0 R 1200 0 R ]
+>> endobj
+1143 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 432.2613 539.579 441.3671]
+/Rect [494.296 758.4766 511.2325 767.5824]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.4.0.1) >>
>> endobj
-892 0 obj <<
+1144 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 420.1793 539.579 429.285]
+/Rect [494.296 746.3946 511.2325 755.5003]
/Subtype /Link
/A << /S /GoTo /D (subsection.6.4.1) >>
>> endobj
-893 0 obj <<
+1145 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 408.0972 539.579 417.0535]
+/Rect [494.296 734.3125 511.2325 743.4183]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.4.1.1) >>
>> endobj
-894 0 obj <<
+1146 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 396.0152 539.579 404.9715]
+/Rect [494.296 722.2305 511.2325 731.3362]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.4.1.2) >>
>> endobj
-895 0 obj <<
+1147 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 383.9331 539.579 392.8894]
+/Rect [494.296 710.1484 511.2325 719.2542]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.4.1.3) >>
>> endobj
-896 0 obj <<
+1148 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 371.8511 539.579 380.8074]
+/Rect [494.296 698.0664 511.2325 707.1721]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.4.1.4) >>
>> endobj
-900 0 obj <<
+1152 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 359.769 539.579 368.7253]
+/Rect [494.296 686.084 511.2325 695.0901]
/Subtype /Link
/A << /S /GoTo /D (subsubsection.6.4.1.5) >>
>> endobj
-901 0 obj <<
+1153 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 337.1969 539.579 345.9291]
+/Rect [494.296 663.4123 511.2325 672.2689]
/Subtype /Link
/A << /S /GoTo /D (chapter.7) >>
>> endobj
-902 0 obj <<
+1154 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 325.1348 539.579 334.091]
+/Rect [494.296 651.3501 511.2325 660.4558]
/Subtype /Link
/A << /S /GoTo /D (section.7.1) >>
>> endobj
-903 0 obj <<
+1155 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 313.0527 539.579 322.009]
+/Rect [494.296 639.3677 511.2325 648.3738]
/Subtype /Link
/A << /S /GoTo /D (section.7.2) >>
>> endobj
-904 0 obj <<
+1156 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 300.9707 539.579 309.9269]
+/Rect [494.296 627.2856 511.2325 636.2917]
/Subtype /Link
/A << /S /GoTo /D (subsection.7.2.1) >>
>> endobj
-905 0 obj <<
+1157 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 288.8886 539.579 297.8449]
+/Rect [494.296 615.2036 511.2325 624.2097]
/Subtype /Link
/A << /S /GoTo /D (subsection.7.2.2) >>
>> endobj
-906 0 obj <<
+1158 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 276.8066 539.579 285.7628]
+/Rect [494.296 603.1215 511.2325 612.1276]
/Subtype /Link
/A << /S /GoTo /D (section.7.3) >>
>> endobj
-907 0 obj <<
+1159 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 254.2345 539.579 262.9666]
+/Rect [494.296 580.5943 511.2325 589.3064]
/Subtype /Link
/A << /S /GoTo /D (chapter.8) >>
>> endobj
-908 0 obj <<
+1160 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 242.1723 539.579 251.1286]
+/Rect [494.296 568.4873 511.2325 577.4934]
/Subtype /Link
/A << /S /GoTo /D (section.8.1) >>
>> endobj
-909 0 obj <<
+1161 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 230.0903 539.579 239.0465]
+/Rect [494.296 556.4052 511.2325 565.4113]
/Subtype /Link
/A << /S /GoTo /D (subsection.8.1.1) >>
>> endobj
-910 0 obj <<
+1162 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 218.0082 539.579 226.9645]
+/Rect [494.296 544.3232 511.2325 553.3293]
/Subtype /Link
/A << /S /GoTo /D (section.8.2) >>
>> endobj
-911 0 obj <<
+1163 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 205.9262 539.579 214.8824]
+/Rect [494.296 532.2411 511.2325 541.2472]
/Subtype /Link
/A << /S /GoTo /D (section.8.3) >>
>> endobj
-912 0 obj <<
+1164 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 183.3541 539.579 192.0862]
+/Rect [494.296 509.5694 511.2325 518.426]
/Subtype /Link
/A << /S /GoTo /D (appendix.A) >>
>> endobj
-913 0 obj <<
+1165 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 171.2919 539.579 180.2482]
+/Rect [494.296 497.5072 511.2325 506.6129]
/Subtype /Link
/A << /S /GoTo /D (section.A.1) >>
>> endobj
-914 0 obj <<
+1166 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 159.2098 539.579 168.1661]
+/Rect [494.296 485.4252 511.2325 494.5309]
/Subtype /Link
/A << /S /GoTo /D (subsection.A.1.1) >>
>> endobj
-915 0 obj <<
+1167 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 147.1278 539.579 156.0841]
+/Rect [494.296 473.3431 511.2325 482.4488]
/Subtype /Link
/A << /S /GoTo /D (section.A.2) >>
>> endobj
-916 0 obj <<
+1168 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 135.0457 539.579 144.002]
+/Rect [494.296 461.2611 511.2325 470.3668]
/Subtype /Link
/A << /S /GoTo /D (subsection.A.2.1) >>
>> endobj
-917 0 obj <<
+1169 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 122.9637 539.579 131.92]
+/Rect [494.296 449.179 511.2325 458.2847]
/Subtype /Link
/A << /S /GoTo /D (section.A.3) >>
>> endobj
-918 0 obj <<
+1170 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [527.6238 110.8816 539.579 119.8379]
+/Rect [494.296 437.097 511.2325 446.2027]
/Subtype /Link
/A << /S /GoTo /D (subsection.A.3.1) >>
>> endobj
-919 0 obj <<
+1171 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 98.7996 539.579 107.9053]
+/Rect [494.296 425.1146 511.2325 434.1207]
/Subtype /Link
/A << /S /GoTo /D (subsection.A.3.2) >>
>> endobj
-920 0 obj <<
+1172 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 86.7175 539.579 95.8233]
+/Rect [494.296 413.0325 511.2325 422.0386]
/Subtype /Link
/A << /S /GoTo /D (subsection.A.3.3) >>
>> endobj
-921 0 obj <<
+1173 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [522.6425 64.1455 539.579 73.0021]
+/Rect [494.296 400.9505 511.2325 409.9566]
/Subtype /Link
-/A << /S /GoTo /D (appendix.B) >>
+/A << /S /GoTo /D (section.A.4) >>
>> endobj
-863 0 obj <<
-/D [861 0 R /XYZ 85.0394 794.5015 null]
+1174 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 388.7688 511.2325 397.8745]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.A.4.1) >>
>> endobj
-860 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F39 899 0 R >>
-/ProcSet [ /PDF /Text ]
+1175 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 376.6867 511.2325 385.7925]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.A.4.2) >>
>> endobj
-924 0 obj <<
-/Length 885
-/Filter /FlateDecode
->>
-stream
-xÚíÙOOÛ0
-‚¶e›¶O?§Í+už(œ"„ ÏïÅï§`'Pòð¥6ÌxáKëÓt9]¼œ‡¿}. =§Š'Uø¬ãIqt*mé™7”“›RiÍ„Þ æwÊÉìrôéËùää|r1¾šœ'“4*Î \6Cþ,.¯x9 œœIïtù'üÀx/ÊE¡´dZIóP\_Ӏ诛Ðì•
-¤4á~ë§L!”&2}Ôd¼gNÕj2;šÖwóå¿Õ²n<ÉÒ!¥©î vZ ;!å
-! Ñé$g™ç·}v iy½¨gÕô¶žÞOWË›qe´½ZPœãÞ‚P %÷Àv ÊB "Ó'AV3¯LÜʹ=Aí­H÷ × ŠsÜ[
-¤át/«s…P‚ÈôI‘Ì{wg
-‹h¯‡ýÿûïÿSz C”0Üc¼[X¦J™> Ó‚q©ãÆ x˜Ô†Øú×ÙõSÝ<sR¯÷äЛ
-¤xრQ™B(^dúÄKqÆ{»°Øðz\ΦáÜðóýŎôö†)o¸ã ˆ%W¦Ê™>yŽÐq÷¢Itª
-·$±V˲‡*½¬®´ãÌJ+rï«Ã70¯5¼ýíøóK|e™tNä/WXÏ綔š…±¶{Ÿ»ßOCÅÿx3B*endstream
-endobj
-923 0 obj <<
-/Type /Page
-/Contents 924 0 R
-/Resources 922 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 715 0 R
-/Annots [ 926 0 R 927 0 R 928 0 R 929 0 R 930 0 R 931 0 R 932 0 R 933 0 R 934 0 R 935 0 R 936 0 R 940 0 R 941 0 R ]
+1176 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 364.6047 511.2325 373.7104]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.A.4.3) >>
>> endobj
-926 0 obj <<
+1177 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 758.4766 511.2325 767.5824]
+/Rect [494.296 352.5226 511.2325 361.6284]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.A.4.4) >>
+>> endobj
+1178 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 340.4406 511.2325 349.5463]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.A.4.5) >>
+>> endobj
+1179 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 328.3585 511.2325 337.4643]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.A.4.6) >>
+>> endobj
+1180 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 316.2765 511.2325 325.3822]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.A.4.6.1) >>
+>> endobj
+1181 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 304.2941 511.2325 313.3002]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.A.4.6.2) >>
+>> endobj
+1182 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 292.212 511.2325 301.2181]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.A.4.6.3) >>
+>> endobj
+1183 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 280.13 511.2325 289.1361]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.A.4.6.4) >>
+>> endobj
+1184 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 267.9483 511.2325 277.054]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.A.4.6.5) >>
+>> endobj
+1185 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 255.8662 511.2325 264.972]
+/Subtype /Link
+/A << /S /GoTo /D (subsubsection.A.4.6.6) >>
+>> endobj
+1186 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 243.7842 511.2325 252.8899]
+/Subtype /Link
+/A << /S /GoTo /D (subsection.A.4.7) >>
+>> endobj
+1187 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 221.2121 511.2325 230.0687]
+/Subtype /Link
+/A << /S /GoTo /D (appendix.B) >>
+>> endobj
+1188 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [494.296 209.1499 511.2325 218.2557]
/Subtype /Link
/A << /S /GoTo /D (section.B.1) >>
>> endobj
-927 0 obj <<
+1189 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 746.5215 511.2325 755.6272]
+/Rect [494.296 197.0679 511.2325 206.1736]
/Subtype /Link
/A << /S /GoTo /D (section.B.2) >>
>> endobj
-928 0 obj <<
+1190 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 734.5663 511.2325 743.672]
+/Rect [494.296 184.9858 511.2325 194.0916]
/Subtype /Link
/A << /S /GoTo /D (section.B.3) >>
>> endobj
-929 0 obj <<
+1191 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 722.6111 511.2325 731.7169]
+/Rect [494.296 172.9038 511.2325 182.0095]
/Subtype /Link
/A << /S /GoTo /D (section.B.4) >>
>> endobj
-930 0 obj <<
+1192 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 710.7556 511.2325 719.7617]
+/Rect [494.296 160.9214 511.2325 169.9275]
/Subtype /Link
/A << /S /GoTo /D (section.B.5) >>
>> endobj
-931 0 obj <<
+1193 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 698.7008 511.2325 707.8065]
+/Rect [494.296 148.7397 511.2325 157.8454]
/Subtype /Link
/A << /S /GoTo /D (section.B.6) >>
>> endobj
-932 0 obj <<
+1194 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 686.8453 511.2325 695.8514]
+/Rect [494.296 136.7573 511.2325 145.7634]
/Subtype /Link
/A << /S /GoTo /D (section.B.7) >>
>> endobj
-933 0 obj <<
+1195 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 674.7905 511.2325 683.8962]
+/Rect [494.296 124.5756 511.2325 133.6813]
/Subtype /Link
/A << /S /GoTo /D (section.B.8) >>
>> endobj
-934 0 obj <<
+1196 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 662.8353 511.2325 671.941]
+/Rect [494.296 112.4935 511.2325 121.5993]
/Subtype /Link
/A << /S /GoTo /D (section.B.9) >>
>> endobj
-935 0 obj <<
+1197 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 650.8801 511.2325 659.9859]
+/Rect [494.296 100.4115 511.2325 109.5172]
/Subtype /Link
/A << /S /GoTo /D (section.B.10) >>
>> endobj
-936 0 obj <<
+1198 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 639.0246 511.2325 648.0307]
+/Rect [494.296 88.3294 511.2325 97.4352]
/Subtype /Link
/A << /S /GoTo /D (section.B.11) >>
>> endobj
-940 0 obj <<
+1199 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 626.9698 511.2325 636.0755]
+/Rect [494.296 76.2474 511.2325 85.3531]
/Subtype /Link
/A << /S /GoTo /D (section.B.12) >>
>> endobj
-941 0 obj <<
+1200 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [494.296 615.0146 511.2325 624.1204]
+/Rect [494.296 64.1653 511.2325 73.2711]
/Subtype /Link
/A << /S /GoTo /D (section.B.13) >>
>> endobj
-925 0 obj <<
-/D [923 0 R /XYZ 56.6929 794.5015 null]
+1142 0 obj <<
+/D [1140 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-922 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F41 939 0 R >>
+1139 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F39 1151 0 R /F21 930 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1203 0 obj <<
+/Length 660
+/Filter /FlateDecode
+>>
+stream
+xÚíØ;oÛ0
+Ü[PÍùü²Qˆg›ì-ZHßg9iïvEú‹/qÃCO~:×q0ê¤ (UHÎ[6ýàMYf¬…àMwé¯ïDc…`ªKÑ ê(²úµ}éG¾›Õ
+Û>U˜C·ŒG•($‡*›~@åËðç‘ ¨lªiÚÝ•3vÖt&Ma¿'kŠsšâ~‚ÁqM‰Brš²éM
+3»è'`hÀd^Q`ŽWÜ`°0Î+QHŽW6}àeü…ÓF^ØóògÔ¶j›×M÷ñgf_—€5lýTXq`Ö»Öæ`¥
+ÉÀʧ`9ËC¸¥¼‡õmWÓõ¦ªéWÎÅŸŸoÞÂ,êL¢ÂžOæDÅ=+ÆE%
+ɉʦDYÍP™pÓ( Õî–µ\W»õ‚¢”óQuXaë'Ês°âÖ‚•ã°…œÀžQ£8Ó !õÌÿC­Åÿ?’;>8ôwÒ9‘^®äŽ!KümD7W·Ø_£K= Š*ÿ ïK¿endstream
+endobj
+1202 0 obj <<
+/Type /Page
+/Contents 1203 0 R
+/Resources 1201 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1216 0 R
+/Annots [ 1205 0 R 1209 0 R 1210 0 R 1211 0 R 1212 0 R 1213 0 R 1214 0 R 1215 0 R ]
+>> endobj
+1205 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [522.6425 758.4766 539.579 767.5824]
+/Subtype /Link
+/A << /S /GoTo /D (section.B.14) >>
+>> endobj
+1209 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [522.6425 746.5215 539.579 755.6272]
+/Subtype /Link
+/A << /S /GoTo /D (section.B.15) >>
+>> endobj
+1210 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [522.6425 734.5663 539.579 743.672]
+/Subtype /Link
+/A << /S /GoTo /D (section.B.16) >>
+>> endobj
+1211 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [522.6425 722.6111 539.579 731.7169]
+/Subtype /Link
+/A << /S /GoTo /D (section.B.17) >>
+>> endobj
+1212 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [522.6425 710.7556 539.579 719.7617]
+/Subtype /Link
+/A << /S /GoTo /D (section.B.18) >>
+>> endobj
+1213 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [522.6425 698.8005 539.579 707.8065]
+/Subtype /Link
+/A << /S /GoTo /D (section.B.19) >>
+>> endobj
+1214 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [522.6425 686.8453 539.579 695.8514]
+/Subtype /Link
+/A << /S /GoTo /D (section.B.20) >>
+>> endobj
+1215 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [522.6425 674.7905 539.579 683.8962]
+/Subtype /Link
+/A << /S /GoTo /D (section.B.21) >>
+>> endobj
+1204 0 obj <<
+/D [1202 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+1201 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-944 0 obj <<
-/Length 2175
+1219 0 obj <<
+/Length 2174
/Filter /FlateDecode
>>
stream
@@ -3519,55 +4264,55 @@ xÚÝYÝoã6÷_áGXëø%‘ìãî¶ÅÅî’¢½>(c kK®>’ºý 9C[ŠåÍö6ÀE€ˆ¤†äpæ7¿Ê|Éà/M–2iÕR
ìn+×í 7Éz[­‹Žî‹º3k•¼iPÿ¦½1É°ó›ûE†Î•8þдØ(ÝÎmŠ¾ª7´ÏÐo›¶êAÍ#Ž4ŽdÃáh‡¢¦•h+F
žœˆ‡UûÃÎíÁEðëJ€¢ý¶ðîÒYR¬û¡ØíŽ8¾/¶¢)A$؆F~öË2XÂuëRPÂȼŠ¢eÑ(Vuqå
4¨joßñË`wÖj†Ž‚÷f|SHÚê~èÃ"Ùœ?ü¨ßü¾ZEÌs•J• B±b©È%bž§
-<ð|߬o¹ù`&͵KÞºö85ØÓNBƒÅp€ñs°o?||Oñ
-†A8Bs]ÜÖá®—0F4•Ò`„LC‹ÖîÐGî˜('˜NY.ÔœvâEí BÖÀ^Q1òc3 a2ZI-RÃa‹ šQö·¡ÂF¤- |Щ¦®1|¡O$ˆieòX´U3Ð<W?âbMVóaøj±8ùÒJˆ<WúÒ2‘WìÀu\.iS£x”è‹îÓ
-Ò (L¹^ŒùÉë¸sÕwhC%yª³\Omx ƒ¡„
-5
-(ÁÝîx‰kàXÛòä¾)Óò³B£:Ò96&'ȉj\@4@a&
-²MáÓŽ‚Ëx¿õŸC ®•’p¹gbçN"ùéß?¾AÉmÓõ#IàµPÏ|>Ø‘¢wI>Ü‚éž_»'‚€k÷ÓWT¾^Gôè”_g¸¢Ÿ[Ì3‡è‘徫~÷›ý>Ue¿½ÞWÓ÷/ÞèèWäB¡Êò—ÀËeʤˆëÏiX¥9ï0|?£^Ÿ+¯Ì,~ÆÊ
+<ð|߬o¹ù`&͵KÞºö85ØÓNBƒÅp€ñs°o?||Oñ
+FŠüäuܹê;´¡’<ÕY®§6<ÁG‰ÐB
+žD8^øú &®*‚îóSˆÏš|SXuYµ)©Ú„âüѳoSSiùS¯wUý•eg(£ãÜsÙºOëàïg7b¸„%Wð¡Ðñ€^Á;NÀNTÿ¯ÕâÛ»Ó÷›CHᙺQ
+ÿñæ·Å/¿²e¹`Ë,•ÖdË'è0°&TŠû…’Ðd™‰#»Åíâ_ÿ㬨ǨP¸ªÎc°5#º§K­â™V܇3üôEjŠfø
+–Q£­¢+O(Ÿèº³ß…Ù¤
+µ¾€Ð5༚ºÜ¸c3Í¡vÃH-Ôø·¿‹ß
endobj
-943 0 obj <<
+1218 0 obj <<
/Type /Page
-/Contents 944 0 R
-/Resources 942 0 R
+/Contents 1219 0 R
+/Resources 1217 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 954 0 R
+/Parent 1216 0 R
>> endobj
6 0 obj <<
-/D [943 0 R /XYZ 85.0394 769.5949 null]
+/D [1218 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-945 0 obj <<
-/D [943 0 R /XYZ 85.0394 582.8476 null]
+1220 0 obj <<
+/D [1218 0 R /XYZ 85.0394 582.8476 null]
>> endobj
10 0 obj <<
-/D [943 0 R /XYZ 85.0394 512.9824 null]
+/D [1218 0 R /XYZ 85.0394 512.9824 null]
>> endobj
-946 0 obj <<
-/D [943 0 R /XYZ 85.0394 474.7837 null]
+1221 0 obj <<
+/D [1218 0 R /XYZ 85.0394 474.7837 null]
>> endobj
14 0 obj <<
-/D [943 0 R /XYZ 85.0394 399.5462 null]
+/D [1218 0 R /XYZ 85.0394 399.5462 null]
>> endobj
-947 0 obj <<
-/D [943 0 R /XYZ 85.0394 363.8828 null]
+1222 0 obj <<
+/D [1218 0 R /XYZ 85.0394 363.8828 null]
>> endobj
18 0 obj <<
-/D [943 0 R /XYZ 85.0394 223.0066 null]
+/D [1218 0 R /XYZ 85.0394 223.0066 null]
>> endobj
-948 0 obj <<
-/D [943 0 R /XYZ 85.0394 190.9009 null]
+1223 0 obj <<
+/D [1218 0 R /XYZ 85.0394 190.9009 null]
>> endobj
-949 0 obj <<
-/D [943 0 R /XYZ 85.0394 170.4169 null]
+1224 0 obj <<
+/D [1218 0 R /XYZ 85.0394 170.4169 null]
>> endobj
-950 0 obj <<
-/D [943 0 R /XYZ 85.0394 158.4617 null]
+1225 0 obj <<
+/D [1218 0 R /XYZ 85.0394 158.4617 null]
>> endobj
-942 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R /F39 899 0 R /F41 939 0 R /F48 953 0 R >>
+1217 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R /F39 1151 0 R /F41 1208 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-957 0 obj <<
+1231 0 obj <<
/Length 3187
/Filter /FlateDecode
>>
@@ -3585,63 +4330,63 @@ H•²/hÊ
®£fw"®höx׺©;°Çn|>”°ÃÓ¶PˇýjÎÖzýÁ”rþ!È£+Œ­$üE™ Bö‘Q™…­Ê"ôãÇœ/Áò±r=?5M[ô°ÌÏ[€Ì°u¸Âz ÆmÜo<)¶ó=P¿+{’‘OíRzwdîØPÖ6ôV`0ÐhõðlÓã>§¦|êv=£lÁá“xý1‡š[ÚÍ„C9ßšÞ4â¦Å7ɵkù ’ß ÿe¬ˆ¦¯¸Çÿ¤ùâãý×þ{Ôñ¿Ä T0iª_ð‡)¶ˆÌ€
@Ÿ!þêó4Ï©Êendstream
endobj
-956 0 obj <<
+1230 0 obj <<
/Type /Page
-/Contents 957 0 R
-/Resources 955 0 R
+/Contents 1231 0 R
+/Resources 1229 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 954 0 R
-/Annots [ 963 0 R 964 0 R ]
+/Parent 1216 0 R
+/Annots [ 1237 0 R 1238 0 R ]
>> endobj
-963 0 obj <<
+1237 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [272.8897 207.1951 329.1084 219.2548]
/Subtype /Link
/A << /S /GoTo /D (types_of_resource_records_and_when_to_use_them) >>
>> endobj
-964 0 obj <<
+1238 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [190.6691 179.6723 249.6573 189.0819]
/Subtype /Link
/A << /S /GoTo /D (rfcs) >>
>> endobj
-958 0 obj <<
-/D [956 0 R /XYZ 56.6929 756.8229 null]
+1232 0 obj <<
+/D [1230 0 R /XYZ 56.6929 756.8229 null]
>> endobj
-959 0 obj <<
-/D [956 0 R /XYZ 56.6929 744.8677 null]
+1233 0 obj <<
+/D [1230 0 R /XYZ 56.6929 744.8677 null]
>> endobj
22 0 obj <<
-/D [956 0 R /XYZ 56.6929 651.295 null]
+/D [1230 0 R /XYZ 56.6929 651.295 null]
>> endobj
-960 0 obj <<
-/D [956 0 R /XYZ 56.6929 612.4036 null]
+1234 0 obj <<
+/D [1230 0 R /XYZ 56.6929 612.4036 null]
>> endobj
26 0 obj <<
-/D [956 0 R /XYZ 56.6929 555.4285 null]
+/D [1230 0 R /XYZ 56.6929 555.4285 null]
>> endobj
-961 0 obj <<
-/D [956 0 R /XYZ 56.6929 530.6703 null]
+1235 0 obj <<
+/D [1230 0 R /XYZ 56.6929 530.6703 null]
>> endobj
30 0 obj <<
-/D [956 0 R /XYZ 56.6929 416.0112 null]
+/D [1230 0 R /XYZ 56.6929 416.0112 null]
>> endobj
-962 0 obj <<
-/D [956 0 R /XYZ 56.6929 391.253 null]
+1236 0 obj <<
+/D [1230 0 R /XYZ 56.6929 391.253 null]
>> endobj
34 0 obj <<
-/D [956 0 R /XYZ 56.6929 164.815 null]
+/D [1230 0 R /XYZ 56.6929 164.815 null]
>> endobj
-965 0 obj <<
-/D [956 0 R /XYZ 56.6929 137.4068 null]
+1239 0 obj <<
+/D [1230 0 R /XYZ 56.6929 137.4068 null]
>> endobj
-955 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F39 899 0 R /F41 939 0 R /F21 714 0 R >>
+1229 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F39 1151 0 R /F41 1208 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-970 0 obj <<
+1244 0 obj <<
/Length 3415
/Filter /FlateDecode
>>
@@ -3661,60 +4406,60 @@ txÕÁ(1Âùãqt0úØÇ‘C×µLm›§:ÂÄ$è’y¦
·o¾Àbº¦úž&\Õ=¯d‚Ó÷aŠKѨðÀæ@pð
–þvA•c«ÇøÀ†û,¤ÆAg€hCõoœ€}¼ew8ýš*çÐð‡#çô/œÿn1]/‚0Péú\í8 °ef´>+sŒBOD‡+^ .ùRéØ{
endobj
-969 0 obj <<
+1243 0 obj <<
/Type /Page
-/Contents 970 0 R
-/Resources 968 0 R
+/Contents 1244 0 R
+/Resources 1242 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 954 0 R
-/Annots [ 973 0 R 974 0 R ]
+/Parent 1216 0 R
+/Annots [ 1247 0 R 1248 0 R ]
>> endobj
-973 0 obj <<
+1247 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [519.8432 463.1122 539.579 475.1718]
/Subtype /Link
/A << /S /GoTo /D (diagnostic_tools) >>
>> endobj
-974 0 obj <<
+1248 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [84.0431 451.8246 133.308 463.2167]
/Subtype /Link
/A << /S /GoTo /D (diagnostic_tools) >>
>> endobj
-971 0 obj <<
-/D [969 0 R /XYZ 85.0394 794.5015 null]
+1245 0 obj <<
+/D [1243 0 R /XYZ 85.0394 794.5015 null]
>> endobj
38 0 obj <<
-/D [969 0 R /XYZ 85.0394 570.5252 null]
+/D [1243 0 R /XYZ 85.0394 570.5252 null]
>> endobj
-972 0 obj <<
-/D [969 0 R /XYZ 85.0394 541.3751 null]
+1246 0 obj <<
+/D [1243 0 R /XYZ 85.0394 541.3751 null]
>> endobj
42 0 obj <<
-/D [969 0 R /XYZ 85.0394 434.1868 null]
+/D [1243 0 R /XYZ 85.0394 434.1868 null]
>> endobj
-975 0 obj <<
-/D [969 0 R /XYZ 85.0394 406.5769 null]
+1249 0 obj <<
+/D [1243 0 R /XYZ 85.0394 406.5769 null]
>> endobj
46 0 obj <<
-/D [969 0 R /XYZ 85.0394 301.1559 null]
+/D [1243 0 R /XYZ 85.0394 301.1559 null]
>> endobj
-976 0 obj <<
-/D [969 0 R /XYZ 85.0394 276.6843 null]
+1250 0 obj <<
+/D [1243 0 R /XYZ 85.0394 276.6843 null]
>> endobj
50 0 obj <<
-/D [969 0 R /XYZ 85.0394 200.1512 null]
+/D [1243 0 R /XYZ 85.0394 200.1512 null]
>> endobj
-977 0 obj <<
-/D [969 0 R /XYZ 85.0394 175.6796 null]
+1251 0 obj <<
+/D [1243 0 R /XYZ 85.0394 175.6796 null]
>> endobj
-968 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F39 899 0 R /F41 939 0 R /F21 714 0 R >>
+1242 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F39 1151 0 R /F41 1208 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-981 0 obj <<
+1255 0 obj <<
/Length 2457
/Filter /FlateDecode
>>
@@ -3733,39 +4478,39 @@ S¦…€Äüœºã2±öŠ 41ÑÍ–,÷úBäí]¨u›«˜úDOâ‚ÙLë–3žatÙ±º÷5vxnïH‘šªmÝóìAߌå
M­
 ZãŠÜƒ[æž.ÇñS!L%:P–ô˜¥Hé!”·i"®"!G­š¼ü…3Ãø(M¶æÒ?/ÕºðõwÕNïÉzê-çÕÃÿ­@úÂ?Dþ ÇD÷ÿï2ýý¥Ê2¹ü—ŠÌ OÕÈŠ%ºaÜÿ?sËùy;:»endstream
endobj
-980 0 obj <<
+1254 0 obj <<
/Type /Page
-/Contents 981 0 R
-/Resources 979 0 R
+/Contents 1255 0 R
+/Resources 1253 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 954 0 R
+/Parent 1216 0 R
>> endobj
-982 0 obj <<
-/D [980 0 R /XYZ 56.6929 794.5015 null]
+1256 0 obj <<
+/D [1254 0 R /XYZ 56.6929 794.5015 null]
>> endobj
54 0 obj <<
-/D [980 0 R /XYZ 56.6929 717.7272 null]
+/D [1254 0 R /XYZ 56.6929 717.7272 null]
>> endobj
-983 0 obj <<
-/D [980 0 R /XYZ 56.6929 690.4227 null]
+1257 0 obj <<
+/D [1254 0 R /XYZ 56.6929 690.4227 null]
>> endobj
58 0 obj <<
-/D [980 0 R /XYZ 56.6929 550.0786 null]
+/D [1254 0 R /XYZ 56.6929 550.0786 null]
>> endobj
-984 0 obj <<
-/D [980 0 R /XYZ 56.6929 525.2967 null]
+1258 0 obj <<
+/D [1254 0 R /XYZ 56.6929 525.2967 null]
>> endobj
62 0 obj <<
-/D [980 0 R /XYZ 56.6929 393.0502 null]
+/D [1254 0 R /XYZ 56.6929 393.0502 null]
>> endobj
-985 0 obj <<
-/D [980 0 R /XYZ 56.6929 363.1913 null]
+1259 0 obj <<
+/D [1254 0 R /XYZ 56.6929 363.1913 null]
>> endobj
-979 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F39 899 0 R >>
+1253 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-988 0 obj <<
+1262 0 obj <<
/Length 2097
/Filter /FlateDecode
>>
@@ -3781,406 +4526,513 @@ hZã|jY/ýE‰áÝN6“dy 8xp]7b~{é0h”~’e±½„3×rÓ,Ã,*r¸2Ư{ë³½ŸØøÎê±×꛼cµ¬Ë"
Ìk
âþî^̲EÑÅk˜èP<sgÕ1B ÚÖP!žÅj˜K±dx ’;mêá6¨BÐ ¾I½Ÿp
endobj
-987 0 obj <<
+1261 0 obj <<
/Type /Page
-/Contents 988 0 R
-/Resources 986 0 R
+/Contents 1262 0 R
+/Resources 1260 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 954 0 R
-/Annots [ 994 0 R 995 0 R ]
+/Parent 1216 0 R
+/Annots [ 1268 0 R 1269 0 R ]
>> endobj
-994 0 obj <<
+1268 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [519.8432 268.1131 539.579 280.1727]
/Subtype /Link
/A << /S /GoTo /D (acache) >>
>> endobj
-995 0 obj <<
+1269 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [84.0431 256.1579 143.5361 268.2175]
/Subtype /Link
/A << /S /GoTo /D (acache) >>
>> endobj
-989 0 obj <<
-/D [987 0 R /XYZ 85.0394 794.5015 null]
+1263 0 obj <<
+/D [1261 0 R /XYZ 85.0394 794.5015 null]
>> endobj
66 0 obj <<
-/D [987 0 R /XYZ 85.0394 769.5949 null]
+/D [1261 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-990 0 obj <<
-/D [987 0 R /XYZ 85.0394 574.3444 null]
+1264 0 obj <<
+/D [1261 0 R /XYZ 85.0394 574.3444 null]
>> endobj
70 0 obj <<
-/D [987 0 R /XYZ 85.0394 574.3444 null]
+/D [1261 0 R /XYZ 85.0394 574.3444 null]
>> endobj
-991 0 obj <<
-/D [987 0 R /XYZ 85.0394 540.5052 null]
+1265 0 obj <<
+/D [1261 0 R /XYZ 85.0394 540.5052 null]
>> endobj
74 0 obj <<
-/D [987 0 R /XYZ 85.0394 447.7637 null]
+/D [1261 0 R /XYZ 85.0394 447.7637 null]
>> endobj
-992 0 obj <<
-/D [987 0 R /XYZ 85.0394 410.3389 null]
+1266 0 obj <<
+/D [1261 0 R /XYZ 85.0394 410.3389 null]
>> endobj
78 0 obj <<
-/D [987 0 R /XYZ 85.0394 348.7624 null]
+/D [1261 0 R /XYZ 85.0394 348.7624 null]
>> endobj
-993 0 obj <<
-/D [987 0 R /XYZ 85.0394 311.223 null]
+1267 0 obj <<
+/D [1261 0 R /XYZ 85.0394 311.223 null]
>> endobj
82 0 obj <<
-/D [987 0 R /XYZ 85.0394 189.9853 null]
+/D [1261 0 R /XYZ 85.0394 189.9853 null]
>> endobj
-996 0 obj <<
-/D [987 0 R /XYZ 85.0394 156.0037 null]
+1270 0 obj <<
+/D [1261 0 R /XYZ 85.0394 156.0037 null]
>> endobj
-986 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R >>
+1260 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1000 0 obj <<
-/Length 605
+1274 0 obj <<
+/Length 591
/Filter /FlateDecode
>>
stream
-xÚ¥TÛr›0}ç+x3EÕô˜ I;ŽÁÓvÒ<8FI˜bD¹8ÉßW “Ä}ê0 Ú=»«³GZ°‹ôƒ]ÂPáF"€ aænwr5vé`ãAþ4ê4u¾^ÐÈP„$tÓ‡I-çØM³[@ ƒž®€@²^.¯W@Ÿ{>a\/ãÕ‰ -.+ù™¤ñ<ñ|* ξ,Óxe b Î6'×ëÕY<Z7ëÙ*žÇ‹4ñîÒ+'Nßz˜ö‰íøãÜÞ!7Óí^9RÁ™û¬ ±ÄÝ9£”ŽžÂIœ›·‚tH=ªFÐŽ`œ*Ç$<"£ržÒštU¥êVfVµJÖ›6/­b¯M+wMß±®K&‚\ŸpF‚gÉ™–•P+ %ãت]•²1Ö¦ÌÌ¢ö8èJëU¥IÙ³ØÔæàQ³ìv÷²¶‘æ».ó¿ÈK“¨´{´±´ßoiv¡`‘zŒ?“u¾×}ëÞún0†‚1#Ï^ÖM®zv„Þ„S0Ï·/Õ¨‡Ö@ßûJy™©çÆÄ4ÝöÉ@ëù
+xÚ¥TKs›0¾ó+t3AÕtt’:3Nƒû˜4Ç()SŒ\ÀIóï+!°Iâž: ³«}|ì~Ú…
+ÕºÕõ«3uEó»$hô®ËZ«¤iëâa׺BÿÚ*Æ‘]…#;`ÞþÒþ{ã¿¡0FLzX¦ñÐS‘ŒÙ¾(Klô¡ða3?VþP%6endstream
endobj
-999 0 obj <<
+1273 0 obj <<
/Type /Page
-/Contents 1000 0 R
-/Resources 998 0 R
+/Contents 1274 0 R
+/Resources 1272 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 954 0 R
+/Parent 1277 0 R
>> endobj
-1001 0 obj <<
-/D [999 0 R /XYZ 56.6929 794.5015 null]
+1275 0 obj <<
+/D [1273 0 R /XYZ 56.6929 794.5015 null]
>> endobj
86 0 obj <<
-/D [999 0 R /XYZ 56.6929 769.5949 null]
+/D [1273 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1002 0 obj <<
-/D [999 0 R /XYZ 56.6929 744.7247 null]
+1276 0 obj <<
+/D [1273 0 R /XYZ 56.6929 744.7247 null]
>> endobj
-998 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R >>
+1272 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1005 0 obj <<
-/Length 1215
+1280 0 obj <<
+/Length 1159
/Filter /FlateDecode
>>
stream
-xÚÍWÉŽã6½÷W}’ˆæ¢}êt$‡ @ Ì!“-Ó¶0²¨H”N0ÿž"‹”í¶fæ0‡>ˆK±êÕ«â“Å~lQ¤„Š2YäeBRÊÒEu| ‹=ìýøÀ¼M’
-’&BÀdf7NEAÒ‚ç‹øÚÉ·ë‡Õœ-8%YÆÓÅz7ÅÊr8 àÀzû{ôrQý2æ)ÄòõÏx,!y‘3{ŒBˆŒ°R8û_äQ¡ñoª?…ƒ/º}O)ß½4µn½¾(I™ñÌ{É¡yž87?µp0g‘9ÔƒѨš€ÀòYá³ë—¬ˆô©Þ*´ôÑo ã~¯£¶8­nx§²ÑíÞ»¬ÍGûÜ5u«¼ÑN÷ŒªýpYÆ"çÑ»eÉ£KÌØæf³aŒ”iÊ]6áð*9èVnOÔI6£‹•†X0¨TodÝâDwŽ57”1u»ÈT –‘dܳ˜0’Ñ’¹¸‚°eÌ(…bÈcâ½¼¥br ;G‚žù.
-\·Ðš­lÀ0M#£í3q‘S ¿ï4B‡žÉx=7ÞòÏQõµ­½ì0#Îôh×ÖÖSív$6Np¼°[4¤Ñâ
-ê­½>k„’)œã¦U–~;9ûÅs=pdü)G%§ÂÚÉ®×GrÛ6H–¬šK¼K„ðÁJNXV„ÐOžnóëÅOsM‰Õš|Z ^’¢ÈË[»mÝC 4ÔßY>®”©Vörl76€] ½ÓýW;¹œËíª¯®³
-©ÞBg‘Íç°üÚ{áwÜ㣇fé¿vm˜Àº{íªuðÛÖÝFV¼ƒí¶Wƒg‹qà~l.³¿uë=<:°­ÛØž'²ïäã 7¯Ý„ÞPýl–»º Q]Éæ C ½Ç§9L­6õÎÝê/s:£÷ tÜ×IïyÐ{ÿâyÍA÷pëìÝþJÙwâÍJ'ôNåáêÞ«< aáU¤ß3h¬á$å`cÒàjˆçjoHüý‘)Î{ΓáHhJroEDõ—K (bؼ!¼E¿§„夼ð~\4¼Ökô:×È“zóßà"¥ãf«Óß„O`fPYJE0·{pÏc+JøO(®±Íi(„Lá¯H¨×RöÿRؾñÕö´ps/ºo°«ßé`cîÔ\VÕ$ AìÑûÌÅý”ðÉöõ*v‘\ÅÆ aGá9‰ÔVíäؘ¹@@ÃØk3ñÙœºkÉôçOá%× ®Ô¬t°7rÌ)Mþ9~ø~=}Ü„O‘û4÷ùLâ‹ ~û\w¼ %æ&G6¯üm°éCê>Ú¿x>—Ãendstream
+xÚÍWÉŽã6½÷W}’ˆæ¢}êt$‡ @ Ì!“-Ó–0²èH”NO‘EÊ›2sÈ%ðA\ŠU¯^-¤Ù‚Â-Š”PQ&‹¼LHJYº¨Ot±‡½ïŸ˜—IRAÒD˜ÌìÆ©(HZð|_+ùzý´úŽ³§$ËxºXï&[YXoÞjy4ª_Æ<¥‘Xþ¶þ%$/rfQ0‘V
+'ÿ“<(þEõ§pðMw)åû±—¦ÑWÃ%)3žy-#4ϧæ‡æ,2u3ت ,Ÿ~ý’‘>5[…Rƒ>ø­aÜïÕ`Ô§Õ-¯T¶ºÛ{•©q´A]ÛtÊ ítÀ¨ÆÇA‘e,r}X–<ºØŒ­oÖÆH™¦Üyc ¯’ƒîä¦õDd;:[i°ƒJõF6Nôѱæƃ2¦éö™bÁ"’Œ{F2Z2gW¶Œ¥ y8{o÷TLŠd§H0Â3Ÿ hRõêµÈª±îÚw\yýl”yj“ yY×p@d)¸Ý¶úÜØXØé
+¦ÝŽÄ$ Žw
+xfŒE_aNX0˜ÀSš¨¿S•/ŽJí‡/bƒ¦Nʯzßœ–±1—²éLœ¥åK­ˆÆV…BIØm
+JxI1|«ÄR{}Ö8!S8ÆM§,ývrö‹çf¨qdü)G%§ÀÚÉ®×r›6H–¬Ú‹½‹…¿ðÃJNXV„ÐO^nóëÅ¿_æ’£5é´¼$E‘—·rÁûºÿäøµ“mÓC\4&Å=î˦“}^)S­l9m7Ï.HÉhòd×.¿oýˆï`¢Ñy'øŸ{ ¸@েÌé¿v€F1yçŠÜ…®öÛ­ÖǬ>}ΆÜn{5xB‡ÀÍô§î¼Þg'²MÛóDöGùüŘ˜÷ã„.±~Ö÷]Ó+­®d[ëÁpúùeS§M³óôwzži~ÅôÌ•@2BIOWW‚¿›^GSë
+Ó–ÿ¼\g¥» ÜE
+¾qÂôrœº=ȘZ\ ö\FØÿxd²ó‘ód¦·$4%9‡‹{¦úÃ9šfؼ!¼‚¦ÿH ËI)xáõ8kØ;ߥo…­<©»çÃ¥ÛŽ›­>L/‰ÁÌ ²”Š,`îö$àžÇV”ðl×ØæÚ,˜Lá5]Ö·[öhLs&¾Ñ¡0ÌC/—U5U}hõö5¡æ^uº…®û]}á¦×=}»ž^êáý-Rb_ósoù _dð!AK"8YXù½±é_Á£µ
endobj
-1004 0 obj <<
+1279 0 obj <<
/Type /Page
-/Contents 1005 0 R
-/Resources 1003 0 R
+/Contents 1280 0 R
+/Resources 1278 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1011 0 R
+/Parent 1277 0 R
>> endobj
-1006 0 obj <<
-/D [1004 0 R /XYZ 85.0394 794.5015 null]
+1281 0 obj <<
+/D [1279 0 R /XYZ 85.0394 794.5015 null]
>> endobj
90 0 obj <<
-/D [1004 0 R /XYZ 85.0394 769.5949 null]
+/D [1279 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1007 0 obj <<
-/D [1004 0 R /XYZ 85.0394 575.896 null]
+1282 0 obj <<
+/D [1279 0 R /XYZ 85.0394 575.896 null]
>> endobj
94 0 obj <<
-/D [1004 0 R /XYZ 85.0394 529.2011 null]
+/D [1279 0 R /XYZ 85.0394 529.2011 null]
>> endobj
-1008 0 obj <<
-/D [1004 0 R /XYZ 85.0394 492.9468 null]
+1283 0 obj <<
+/D [1279 0 R /XYZ 85.0394 492.9468 null]
>> endobj
98 0 obj <<
-/D [1004 0 R /XYZ 85.0394 492.9468 null]
+/D [1279 0 R /XYZ 85.0394 492.9468 null]
>> endobj
-1009 0 obj <<
-/D [1004 0 R /XYZ 85.0394 466.0581 null]
+1284 0 obj <<
+/D [1279 0 R /XYZ 85.0394 466.0581 null]
>> endobj
102 0 obj <<
-/D [1004 0 R /XYZ 85.0394 237.1121 null]
+/D [1279 0 R /XYZ 85.0394 201.2466 null]
>> endobj
-1010 0 obj <<
-/D [1004 0 R /XYZ 85.0394 206.4074 null]
+1285 0 obj <<
+/D [1279 0 R /XYZ 85.0394 170.5419 null]
>> endobj
-1003 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+1278 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1014 0 obj <<
-/Length 1863
+1288 0 obj <<
+/Length 1768
/Filter /FlateDecode
>>
stream
-xÚÍXYoÛF~ׯ üDÑz/’ËæɉíÔA⸲R£Hó@‘+‹…¤¬ºEÿ{gR”LÙnk öšùvvÃGÏG~HC'9ò0ñœ8açÖÞˆ¥™´D“>Õ›ÙèøœNˆBŸúÎlÑã%‚8³ä‹ËCcà€ÝË“gã õ°{}6{žû34züéêlz2¸;»øty=ž8äîÛO®f-ÅÓ<Þ~º<¿x÷yËgüuö~t6ë´èkJ0S*|}ùŠ~?ˆ…Âs60Àˆ„!uò÷ò8cíL6ºýÔ1ì­ê­ƒÈŒ(óé
-F!uÓ…šåî}9&îÚô—úÍ(ÚfiŽ–fáææÆÌwG 6i³4ë…l6eõÍL+£Ô›ëRëåÂ,™ 6YìÚ}Eb¨í4{5è£
-¶›ƒ¤%²‰ÒÌôK…#§[øtòFwÌ2N¥>‡©.?þf(¬…éªdû¨(ñÀ „ÑöVAV9)«ÄGû/#ÏÌÒÖëy­žBnLŽÐ×|ð(å ¦Üî.WM
-ÂœÂ|0ÜJÔ¡•RY¯<ô£Š„ù:˜•êÖ1éЯ¹-õaWci”өηõß·>ú{²qÌãAO˜¯£yT†}NJ4TWN 2õ}"ÔÏ3ä‹€¶¿m}i’Dý ÐþÐJ¬dõ¯€tQÅT›ÌfÂïþIËn6&„¸e™Õ{uØçöÝŒYàšÂ¨oüÃrœF2³.xaäÙߢ³eª«, Vr›A"ë¸JçÚ½ckÀ8ÊÌZZÀK\É¢Žæº6Uäit[€7Hcå婪Ôò´HëFaqg‰Œ/‡–6ee+$p_FkMsRó*]Ê=ÕëûºQ‘B»‰í‰-r„PV5&Æd™yÚ;~EÎ×··Ý|ǽ耭{À&Xtè±ÀõrÆ ;O&UÏýå»}n<@Lˆ¡b€Ê¶R)ÅÑÛòÿ\c¯endstream
+xÚÍXYSãF~÷¯Pñ$WáaáÉ Ë†kˆqB¥6û ¤1V­,y%ÇI忧ç’d#›JJsõôñMOwˆ…á#–ë!/¤¡å‡r1q­x9ÀÖ¬}M32D£.Õ»Ùàä‚ùVˆBzÖlÞá Äš%Ÿl†(l_]χ#êbûÝøj<9»œ|Žq©oŸ}?¾™½ŸªU¦é'ãïÕÌ-,¹®ý³¡8»ž\\~øi:úŽ=»¼ž ?Ï~¼Ÿ5w­"˜ u¿>}ÆVÆý0Àˆ…km`€ Cj-ŽËë0ff²ÁíàdžagUníE‰`D™G{`rH¦ÀCn€ËwCä1Ê$L''ч±=[¤•ê™¶^pÕIø<Zgµ°r(t]*wGYVlF_×¼Ü*Ú?TåÛSÕûó´oŸ‘z^¨6/jÕY•ÅcšhÁ%×e•>êaÅËÇ4æ»üÔakÊ"7ì”Ô Qøá®ðV%ÊP(Ž©«ÒMWƒÈ(òÈËJÏ-£Õ*ÍÔ`^”{heE±ºâ/Ï™%IÉ+3¡>Â𑾿¹æ{$i€6ÍGb?ŠÊUtdP[÷ŒUÈÔÛU£wUó²÷8æif¤dEe‹¢ª}ÔK ‡•Î·Ï#MöîCá΀\ò= •ªí©›~ƒ6ÿ-Z®2ŽâbùjÊ·«Ã%÷GÏZ{y³sö\Ÿ~1×ffQ×ÏÁÝ4¹¸a<Ñ
+tèErÆ)LÌ ìÔ)ÂpÉ!è©n½ˆ4ï8Ky^ëéMšezºÈsk¿²å‘µΔk1…éÔ‹T©¦ô0j }z¬¬Ó%ÿn¿ô¡ô1µ(Ô¾ç{¯ª$ ÔŠAìV’o—Ñ££ëA Ô> ¼t×ìØe526¨CP@¨Ó”©; `;³¨ã‚D&àñÑ0bÏfW£|Ï>»ߊ»êøÔžýr5»C¨gOyU¬%þ±¾/ÓÆWÔXÜÑé´½açQí€@Àó°kieÝn¿@š„PnþŠøìúì@åo e 9S˜n6xïøÔ±!Î %̾œÀ”CePò0%Í-> OGðÿ%Áž~xˆ ïFL0† ÒœÄÇ â죂Û`v•Ž¼·E…¼%*ØE¡ã¿
+¡¦cÞ+Aa‡AiŽ&í«ø¿Ž‹ÐÀˆ¬w dÝçù“g:õ¡°
+˜8I wÝöÇ?ób
+|HÜï\*“Iv‹LÖ»bF¼ÂS‘…Å@ ¢IG<\Û-MÚ„ÄÌ<Ï~w99Wë:ëÊ¢ŽjÞ0Yjé"qwä¯
+3!“£¢mõÙ΢z0«=9ðIF§~(K3ÑFªI ŒUñZÄy-*¨ŠÔ¥M)~Ë ö¥Þ,Õ]i–÷Å£¬Ž¿ÍübAa zð2JŠe¶Õ#¥ —hg¢_ãF¨Q®Tº’ã¾Ç=ÖÿŸNUÛŒuKô¼*šº º?ºÁöGx¶«™Ö&h› ·®tFT
+ÊTˆiivíÚÔ«×eΓ=5’´Š£.mÃU;GÝ©ÔE^à9"–JØCàxy¥™Zÿqdkà“µ› jÝ
+Na>¤¯xÁã/jY»—|‘´7ŠÂ-Ý M¤³•PQŽŠ2Q£ýëq€:Ž¦­Ö÷£J\„¥r8.ù ¬ "~AªíŪNAÕ1̃`àùFŒ!Mr¡äå‡~-zP©Ä¢VÊKu¦}?N[êÃFÓ=¦SYl‹3¼îb¿§ ”Cˆ¹Ê[öOÂ]Có¬ûœ„èéÌEc½â°õbz|í/×<ÇG,„i¸Ï(ôY«•P=x¢ºù7Û£û_`#~›endstream
endobj
-1013 0 obj <<
+1287 0 obj <<
/Type /Page
-/Contents 1014 0 R
-/Resources 1012 0 R
+/Contents 1288 0 R
+/Resources 1286 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1011 0 R
-/Annots [ 1019 0 R ]
+/Parent 1277 0 R
+/Annots [ 1293 0 R ]
>> endobj
-1019 0 obj <<
+1293 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [55.6967 190.8043 126.3509 202.8639]
+/Rect [55.6967 61.5153 126.3509 73.5749]
/Subtype /Link
/A << /S /GoTo /D (rrset_ordering) >>
>> endobj
-1015 0 obj <<
-/D [1013 0 R /XYZ 56.6929 794.5015 null]
+1289 0 obj <<
+/D [1287 0 R /XYZ 56.6929 794.5015 null]
>> endobj
106 0 obj <<
-/D [1013 0 R /XYZ 56.6929 480.2651 null]
+/D [1287 0 R /XYZ 56.6929 372.6686 null]
>> endobj
-1016 0 obj <<
-/D [1013 0 R /XYZ 56.6929 441.7923 null]
+1290 0 obj <<
+/D [1287 0 R /XYZ 56.6929 334.1957 null]
>> endobj
-1017 0 obj <<
-/D [1013 0 R /XYZ 56.6929 373.7178 null]
+1291 0 obj <<
+/D [1287 0 R /XYZ 56.6929 266.1213 null]
>> endobj
-1018 0 obj <<
-/D [1013 0 R /XYZ 56.6929 361.7627 null]
+1292 0 obj <<
+/D [1287 0 R /XYZ 56.6929 254.1661 null]
+>> endobj
+1286 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F21 930 0 R /F22 953 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1297 0 obj <<
+/Length 2693
+/Filter /FlateDecode
+>>
+stream
+xÚÕZK“Û¸¾Ï¯Ð%NÅDˆ9­×·*öÆ–³ÇUáˆÄ¬DjEjÆ“ÊO @$Žìò)5`³»ÑÏÀÐEt‘K’ðB,²B™P¹Xío’ÅÞýtC-Mìˆâ!ÕË›?¿æÙ¢ EÊÒÅr=à•“$ÏébY}Š^üõù/ËWïoc&“ˆ“ÛX¦Iôöùß^áÌx%eôGñâÝÛ×o~úøþùm&¢å›wooã,)|yýÛw¿¼:÷áöóòç›WK¿ŠáJiÂõ~¿ùô9YT°àŸo‹\.à!!´(Øb#$'Rpîfv7nþîÞšOC–“<'2gYÀtŒ.¨ \¤ld;Y
+ XݷǺÙàs«64÷e½3|As­«7èÚ·“¥w]¯ö8Ht–ó&\µM¼¥yÔîvFªù@«£•º;m6~Þso¼a»a+cXâ½;²,‡8Îr~v®wïKo!d3p÷¼2ë"F ’Hª£ZÓTõ&À‚¹<·4Ï\Éó¬°[Ð/Ä¥ <͘ç3Aõ.Ù1X?Ë…%mº]Ûþv:x
+ )E3Kx@çlŽå^G?Ï£ÒÌhósŠÝgWí~nƒð¤Â‘MŠ.‡9 ;ÁwøôûIÑÃðdË ëØÎxbe¤` G˜ÿѺ¾^k­Ö.êƆGÿ¸S“ jOýáÔû8Ü—=¹¨~ xJ²ÌÁÀI’†ë¼%Š‡T®X]ÖyO5Š¡Ì>É9{Z¦#
+ÈÅEá•
+9º4é“dQÕîKc!¨uƒ60õE¿Ü ÇÆ”ðüÏD&¡ ‚@´ñoˆràD‘§.lZxï4Úëø6#ítÐÆx (Ðk0vØ©ÞÒ·kÏ ³S6 ÍØ„t@V¤ÑËx[v6–$hžðtRÁZ]ç(¨ö/·± ,êj-ç릇B»rE qdBÌ•øÜA<»ÏL|›Š¢ë/®ÖÒè®ìWÛ)«‡mí&Õµ:õXç©cìØWTU®¶ã$(ñgWw6êõLñ´½C? gKÙ(m>N“èùîò}{À6ŠÜ}=Ы•êºúÎ%݃i?©ßçja¥]f €"–C6ˆŒP‘ñMIÁS ãPªØ
+q‡\1Äl3J2>²ŸÆ¦ãòS|ݸõf^PØ(¸ª¿Î-ÕôW]ö9P¯¡6
+ˆe“ÒÊ5°ÉòT°§18ƒ‚øŠzèR÷ÛÊHí€:ê[ýGu8eÒ¦^y‹™´m“D0ef «tNdô£%®Ôº<ízí|³ßÄYØBA\÷~u§ú¥|µEXÓX[ü#`ž&l\­|€½Ñ0§Q½ÛºUÖ]§\ÐÝ9ð\÷nC|j̵´K×áëâèÎF¨úÒ«¦RVÊÃåfyXD†¡> DƒŒ~Wò˜‡žê*4àEJ( ‡è×ê4ä1 <•Mlqù¢Ú5ÇnùpïzF¼
+u"yŸ ×çº(+`:mBñÛ«
+v‚_Ñ&-Ë÷–Ðùs’LŒ“é¨úc­º¯ç½¿ªîzWnBˇ¢—ålÊOøQ‚x# £cÇl»„“¬ðܯb¼ocàÁ
+° ‡åþßv×ùöKð_×^9ø>KRñt{RÍ·WO5=öµXFO2ö´dOuE4åv-¹œ—}yäøÐ9ézÌ2Ž[r=p[r.³ñ6\¿DçÁ i›xðV÷ÎÜö³!=îµÍ—»]ûàdmí$´¡#öÉ´ ”3ß'éù 3Ë4H„¶n6Äðd­`ds€F>ã¶<ËÎ1 ïLØÂ\yך^
+Ã{˜.u{²ßéh²C»ÀÔ‚V;‹|S¯ÐákÇ©glÀ„IÏ4px€P˜aúp+È
+#si¿Xô ªGfœ¥V˜ž2G·ð{Þ÷觑²†l=âà¶VfªÅß;ûFç­sIË«'eóÍ…–
+(>pGÊìéóÉ¥ñ7Þ“†>ïÏê‡]ùè¸Cø½Úø«‰CyìÇWþÔ
+p¬xJ´§¹=vrB þ²¡ðÙ£,ˆ†—
+N8çŒd¬`—·Àvÿ¤?í.îü›¾ü2õÃ%0'üµµQ†Ìè‘2ÂÒTúÄ„íû&·×ˆã<dÏÄŸ¼÷?²œÿ¿Gd„çùÌ9#×çŒ,ñJiõ‹©âþ^.5ÿ+Lendstream
+endobj
+1296 0 obj <<
+/Type /Page
+/Contents 1297 0 R
+/Resources 1295 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1277 0 R
+>> endobj
+1298 0 obj <<
+/D [1296 0 R /XYZ 85.0394 794.5015 null]
>> endobj
110 0 obj <<
-/D [1013 0 R /XYZ 56.6929 167.4388 null]
+/D [1296 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1020 0 obj <<
-/D [1013 0 R /XYZ 56.6929 126.8733 null]
+1299 0 obj <<
+/D [1296 0 R /XYZ 85.0394 744.949 null]
>> endobj
114 0 obj <<
-/D [1013 0 R /XYZ 56.6929 126.8733 null]
+/D [1296 0 R /XYZ 85.0394 744.949 null]
>> endobj
-1021 0 obj <<
-/D [1013 0 R /XYZ 56.6929 98.4089 null]
+1300 0 obj <<
+/D [1296 0 R /XYZ 85.0394 721.0357 null]
>> endobj
-1012 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F21 714 0 R /F22 737 0 R >>
+118 0 obj <<
+/D [1296 0 R /XYZ 85.0394 672.3079 null]
+>> endobj
+1252 0 obj <<
+/D [1296 0 R /XYZ 85.0394 647.0603 null]
+>> endobj
+122 0 obj <<
+/D [1296 0 R /XYZ 85.0394 136.5325 null]
+>> endobj
+1304 0 obj <<
+/D [1296 0 R /XYZ 85.0394 113.5963 null]
+>> endobj
+1295 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1025 0 obj <<
-/Length 2719
-/Filter /FlateDecode
->>
-stream
-xÚÕZÝsÛ¸÷_¡—NåéÅA°O—Ë%×ÜÌ%×ÄiÒÌ”– ‰w©);Îôï À$EJÎø©ãàrw¹Øf3
-l¦SBE.gY.IJY:[ì®èl Ï~ºbž& DI—ꇛ«¿¾Ù,'¹âjv³êðÒ„jÍf7ËOó—ñëÍ«÷× Oé\ë$UtþöÅ/¯på<JÓù?ÅËwo_¿ùéãû×™œß¼y÷ö:Éh.áÍËï¾ûõÕã{®?ßü|õê&~E÷Köþ¸úô™Î–ðÁ?_Q"rÎîaB Ës>Û]ÉTT
-V¶W®þvžºWÇ,—
-MRͳÓq6fº4'JpáLg¿™v0JéüDzXWuÓ– üÚ›kÆؼ®·ýRàÇ;üè,áŠä<˧›ñD]¡,'4eVWK³,×#Œ˜$¹ÚÓ|7ÂE­A l@Á1.9*ã‘KÂ%›Õr„‡ÝáZzÒªÙÖõïÇýO™‚õYæ ÷‡k¦çõúPì`/ô¼p+ÆNòy±Ýâê¢Þí¬`7Ù–•ÁQëìèHWõ×€îï=àì£9<”ÕgU±óœs¸3‡†X g ãXÂÎ3Fò4åÁü¸iËreµZ™ÎË
-›öakpˆÚÁ >¶ûc‹cPjW´äħ)ì šÒ98WÎÆ£×%]ªiŒT§èÊÌá-øy™hDfÏ/(¸—’i_¨õÖ„Ól¾¬w…³Õ`)´AYWøp;¾w¦„ù¿iJÇœ\JÞ&¾ÁËCžeƒÂÛ ÑÎú·ÙMmܮƒí·¦õôõ*2hü’wh7vnyçjþÆ3Þ÷¥4§Bõ}©½¯¯A¨²4Íß®Éø¼)­P\/«ÖŠE[Þ™GB9×K
-œ7àÏá5çß.¥@x
-&ñ‹ì“Û¢]l†¬î7eX4_ÌâØšgE—ýÚ×à \Ú–A7
-üÙ–÷zg=¬]lq‚œ=ee¬ù£óÛÓçõÞºKã¹Ç|`'‹…išò6Ý
-i‡3Ün<f /í4¡Ôq Ñ  ÊáH40ÈÄB¥0 P"º<Nã“QKõ(ÉZócS¬Í¤NB‘jõ,:<œNrT§@B,QàeŸ¾ÇPKEç‘­ÒÔ‡fO$ëqŠp[Oöy„Qp*ט*NIF´ѧF)ɳLyç=Iû°7#¼ 8gYª£Rø•cºA\÷x.¶EÓŒ0U)ÉR!Lÿ2• ’[äÒåŠ.>Â6c$=ûÍ!]Åïä§ä²qËõ´ q£üé¢þ6¶LÕ^ܲÏ#ùrcN$…µ ðõX7 RÍ1d‹qÙļ2R(¨¨¦óó…"#RÈà½÷eH:mñ»ä[®FÄ
-µSR¥ÎKT#bù ¯
-‹ª{r§Q<“ü<
-Ä”-À4ÿà‰—fU·­Ý|ªÅÕE][· ¾ukÚ{c*|´ALËU{ð#áÈ¥(©
- ìÅ8•ñÎY,—èÖMc‚ÓÝä\¶Þ;WÇjaݲðŸnÝ7øÑ­÷Pó¥5ÕÒx)÷e»u7…t]}¤”ª`'ŸQƒ»<¦qA¤ºˆ dÆ…CÖstêò˜Æ‘*º&V‡¤x¹ÜV‡ææþ.Œd1V†Ľ–¡8N•PžÃtX’·ÑGµ¬ÛI~ñL¶Nà†~á‹üþu™_¹3p |Bô,ß°„²¯‰Ê¹ì×ýƒi¥ižÎ{wQÝÕ¶X}>$½Ló!?Gj ßõ
-°Lªœ0Áù EàTÊ,D„ªîÃ0ó-+ù€ó?ÎñHže> ÏœÛÂZq[»R
-Ã;X.e}ôïYoòCÿÊCV¿Š|UTh€oÇ¥W|À‚ ‚È´×8Àâ@˜cø/Èþ³ùÛ¾Y‘Ðh]VÀnK9àIЖ~;6~䫽&³B1úÄC, Älnüê ØyèrÀþõ@<â±ÁÜCú“(Bdê {Šèò˜F‘ê"ŠŠ’”«gu<º<¦QD¤ê…¨¯˜ !PMŸ:KA¤êb䤭“U:Ðý“³&Œ†@ÿ/ÊI¼8 ÏãÕÒhªò^qèG¶ÎƒSÂÈ9%üKâ¼j‰ ÷‡Œs
-ÙW°uµ>ÚórÓ]ò¬ÖÀ¾Â¡í‚¢ÿÂÄCqœxgÖ¡eí…áFçâ.]tÄqÑ]£Š*"c+˜òºu_a¤ÃÌ]ôÂtó°G)ªüŸäϾëji\°u™7ÎËK¼‘Ür¯ƒ"!‚sT]uŽ#)¦sTfü Üh0a&ç$2r»ŽŒNò‘àihžÂÈ*l1ÙÔŽÜG®¼0»äº¶ðûxê±³ž²ŽlÕãVn©Æß[ÿĆPmCÉÊ+G³np- üE3ÃàqËíÓζ¸¡öýx†1êZ20‹›9xË?Ý›Ei9›¡8¿«0òû Ñ4\ªÁÎI>µÆÜø ûèè~<Z{1,ö×&í
-°L³ø<qu¹UJ
-?°ú4`ƒ‚À•°qâI[„4Ú´áb+Þ³œÆsì–Ä»ÀËíé Ü”ΞuU9œ¹¼Ešé0ô›-Rbÿ³hD wsÏþ¦ÇÿëWZóq'ö2‚Ó¨”U>*ÿÑéTóÿQ”mFendstream
+1307 0 obj <<
+/Length 3388
+/Filter /FlateDecode
+>>
+stream
+xÚÝ[ÝsÛ¸÷_¡·Ê3Ÿ$зÜ]rM;Í]m_;\h‰²™H¤N¤ìsþú.>Eˆ å4ÓéLÆÁåb¹Øß.h2ÃðGf"C™¢j–+Ž&b¶Ü^àÙ=Üûé‚8š…'Zô©¾¿½øî Ëg
+©Œf³Ûu—DXJ2»]½Ÿ3ÄÐ%pÀów¯þþúrAžß¼¾¾bþOø1×?ÿòúúÕeÎç·o~ws¹È±âóþòê—[OqžÇ?¿{óö§_|.?Üþõâõmx‹þ›Ìô+ü~ñþž­à…ÿzSRÌžà#¢m/¸`HpÆüÌæâæâaï®y4¥9.0‚‹Ù‚q$aýÉb™€qŠErIa ÊeAù”ô”/ J‰Y ÒÊÿµ-îË"€@’|–óeyN¾F¤ #OŠä©´Hu±-W‹åC¹ü´lêõå"Ãxþ~ñññó?î´Äß½¬Ç‹d´Ì% ¹¬ª}¹ìšý³%–eTG鹦xæð’Ô³\W›R —àòKŠ³ÀñT¡å„d³´&˜X҇ѢO5ÜÆ`¥žêDgŸ›z°¡„IP´àÓª„´¯fgy,ÂíƒSL$-Qˆd¹rŠIˆyÂ[rØDæ·f·¿$rÞÜï‹­õaóhkÇ…ýÙmWîíø7Œé¦´ãuã&Ûçº+þpÏÔ+Ǩ©Û
+¬—Ï—„9óLåˆq¦¾Âú,ÆÝ2PuËL
+Ĥ̿F¤‹q· T©½s®¸úøûãÁ1—I'‚/ÜŽ.7EÛ&ˆ* ©—\4 ~L@œžasèv‡.Á1&› 1é—GŽÅS‚)Äsýa¿„ %ýo¹:+òoXàê¾nöÎ¥ïÇ&‚$.õ1ÁŒ"ðf}àBR:)¾Ëº¨6 Ûjyú’õ7ø’C{þWÒP¨D9–Ü
+ùŸ¼î Mø¯³^KqŒÛlR¹T •çÙKSi~.•f @ãt:•ö©ÆSi êŹf»“É”CN#"Ÿ!P%dˆ’)8=V
+îU/KKõýÛw?Ú‘Bô*‰`Á‘%gÔ¹‡ÌÑv»fßµNžÍÆŒ>ô
+¯Ï+mxþôP]¨ìÃO.Ø«bÓj+ÊÙ¼n:'°Ý…reç«zÄø¥ÕSÊÔeŽ
+¹ëO­e¿|(êºÜXæÛfU‚q1°ú·kk³ÿe™Èâ´þÜløÚ_Êù!%ƒZ˜JqÆÞ( ™û©êšCçkF›ö W-UîîS¥­Ñ†Õv·)ž£P{0u‡­«ÊöxQ´>æ÷þóXiÕ "M£Ïb¼Z
+Tg«%‘‹jTý"õXŒWK*lÛDQ$Ê•ôö­ûÕ}ªˆÉgŒÂÈö,Xv!/É‘RNO9îÎrÔ®”~düžÏòûT¦J PX¨ìÅpÔEÒŽ”ˆE^ŠH'¬íÈBRá–Ih"×8Ò…TäÅ=‘há8æˆQêß´r.hq˜¬í¯Í²Á9«ú~àžÞ’y0]9mî}*kî2aîʘ{¹iŠÕ
+íf[4ª&VÈÁ4¦ÕÔ£šP“§ŠÕ¦(Fë¹^%Ç
+ç÷ .Æ S9ê…£l¼_<VåSJ–Øíe…,†Áʧu¨†ÊŒ³ÆJ’X›ý­Np_=–õq“Ç÷CšÅŒŸÙãÕÄ{*»Çk€5©MŽ*Û©MÒ£ÛóÞe0DApœÔf ªód—s
+)(.*°Mc*wÛliËüƒ\Fu+#ÀàÅÉ™@ôö¬ƒ}#×Ö°±¦1bƒÏ1}Ì¢ x²7÷÷3;¸Ž”îèýZð5Áätý:‡J€ì@ ‰Á‹:'Æ€›ï?éVN–éjÛ;æ4_ø¶€¾Ð•qU’jo‡»ÃݦZÇwÙ•ûªY]ÁPú÷¡ù[-åI/¸icÉ%lŠn`±<wfSÚ®tŸ@Á,ÿöúß–àúº-;<SÌJ÷ÝCyPZB;]9>ºßp_j91±¬N,ê$2žšŽZÅ¡k¶ðνN«UÕB‡¥råÝÃI¸¬!˜ñs¦ªßÂ/<FZ™‡²Æ\Øe~?8r$ÝC¡_Qf¾ÏwZ'q…¸ ±ªÛ¶L5DDîH£j±M·`cïJ»¬U±½‘(E ¼&}$4ÍT'&ŠËW F-ƒZŠÐŠ¢£ððÊÚ×ýsªsMÔøLUö„!ªBßh¹/‹.uÂ'
+ûO±PÓÀ¦O5Žl•–G×b&ë&EÔìú6
+mDM«3P õ‡PŒÆ
+õGq` ŽÂâÀ¬…8Šx× `XÏy/%}ˆs¤%¾§í#ÎNYðqØ&Ø&㺕óblÃ!f“lÛpŽ$Z
+ûÆŸÃ6ž~Ñ Uhžò± ¼bÛ@ˆ@4’f°ç–äŒ
+Ù¯›tôWÌUáT
+ Ѩ´<[7Œ.Z+|¹Ò Â} —¼÷ÉŒ€ X
+Ç Tç¦í2ÂV¸µ-VeÿŽý
endobj
-1024 0 obj <<
+1306 0 obj <<
/Type /Page
-/Contents 1025 0 R
-/Resources 1023 0 R
+/Contents 1307 0 R
+/Resources 1305 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1011 0 R
+/Parent 1277 0 R
+/Annots [ 1312 0 R 1313 0 R 1314 0 R 1315 0 R 1316 0 R ]
>> endobj
-1026 0 obj <<
-/D [1024 0 R /XYZ 85.0394 794.5015 null]
+1312 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [219.3839 329.5541 281.1025 341.6138]
+/Subtype /Link
+/A << /S /GoTo /D (options) >>
>> endobj
-118 0 obj <<
-/D [1024 0 R /XYZ 85.0394 769.5949 null]
+1313 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [491.4967 274.4996 511.2325 286.5592]
+/Subtype /Link
+/A << /S /GoTo /D (dynamic_update_policies) >>
>> endobj
-978 0 obj <<
-/D [1024 0 R /XYZ 85.0394 749.3395 null]
+1314 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [102.5211 265.1945 156.7673 274.6041]
+/Subtype /Link
+/A << /S /GoTo /D (dynamic_update_policies) >>
>> endobj
-122 0 obj <<
-/D [1024 0 R /XYZ 85.0394 221.8894 null]
+1315 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [243.8464 219.4451 306.1963 231.5047]
+/Subtype /Link
+/A << /S /GoTo /D (options) >>
>> endobj
-1030 0 obj <<
-/D [1024 0 R /XYZ 85.0394 197.4323 null]
+1316 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [425.9845 164.3905 495.353 176.4501]
+/Subtype /Link
+/A << /S /GoTo /D (dynamic_update_policies) >>
>> endobj
-1023 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F53 1029 0 R >>
+1308 0 obj <<
+/D [1306 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+1305 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F41 1208 0 R /F53 1303 0 R /F22 953 0 R /F14 956 0 R /F48 1228 0 R /F55 1311 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1033 0 obj <<
-/Length 3426
+1321 0 obj <<
+/Length 3086
/Filter /FlateDecode
>>
stream
-xÚå[Ý“Û¶¿¿BoáÍX>H‚lŸœÄN™Ú‰ïÒ´ãø'RwŒ)R©;Ë“?¾»øâ(y’δ“Î=€‹ÅbñÃîÇVþØ*ŠIœòt%ÓD”E«Íîá·o¯˜¡Y[¢õê«Û«/_
-¹JIóxu»ðJM¶ºÍß‚r hðúùß_\¯yDƒ›o¯£(ø|TýÍ÷/Þ>¿–apûêÍë›ëµ¤i|ý·çßßZŠË<¾~óúå«oìù\¿¿ýîêÅ­›Åp¦Œ
-œÂ¯WïÞÓUþ&Ñê *”°4å«ÝU …BØ–êêæêÇpð«êêÓ\QEa´Z‹$0¾ŠÅ$qe r³„C!JI,¸pÊÙ@ù #QšF+G…ʯ³]‘¯7Åæç¦.®×1¥Á»uþ˯߼·µ jêË—‘pcÖ %B.›*k[M4’§$Idj¨¿ÆÃOD0ûÈ2lŽÝþØy8ŽÉÇî"Ǽ<›®9œ<L£Ä<bS¦O¦°J¸¦L®ÖŒ‘4Šøïåþá¢È?Óˆ–÷us(4) ¤!#I(,×_<Ì8‘± ÁSv¨=\¸ )šúgrÙfeR±¥¥N¦“¬ÿ„“œÛóO^Cá ‘4 džòŸžîg
-êÙ¿F(M¡öþ%6ï<l"’J[Í•U€âáJ’p*‡ —ÉX¼’4"RJÿchÖ"…rœùŽC4
-Kïʺl»C'ŸnRæã“(b 5ª´6„Åf_
-
-yV™àHG©;¯¾h5ûÍCV×E¥™ïš¼
-èÁ¶dQAàæ°–ñ¼†TgTd©Æ:#Œ£·AD•,…Éï<\”)ûò*Éâþ[dcwÄcY<ùdoøYPÆáü¢`ßçué¨æÊŸsè]¤ ks¸ôÎüïËÇ¢îyqÔ@À »`Hµ¼ÆŽJ¯ñšß"âØs‹< ›—翼Ê!8 )ÀâYm:ª¹:'«  )ÁUéó"Ùühwð'|»¬ÄØ3S>¼‰¯-€¯ËS).Ø€êŒ-X*m àÔíÖžÁ£ˆ!Ä\ôOa0÷”Ãî<«PG5×èØ@A)&ÁF*}Û«ôìb›ÐänB»Ë 5¡à’MJDÄà 61 :c–J%ºEñÉ&Ëÿ”(á‰Ø°ô¼RÕ\«c»
-´6•ƒ‰tèÏͳ5m.l…J«…/rÌL°<Fåç%á ‘ÕÖÇÌp*ò²3Í:ow…þi—åÅðK\ÚJ5¦Ë0ņs¡ãÐTë zwÂ/C¥AÌmôuM„ÒÆêvšXßXÚdÇV©Ë ßë
-SÙ<l4IüÒuVéŠuÕ²3¬î a{ 7Rð7†Ê¤†èxÌþ^sn}>nóP|0&Vœ{e¥/ ¼3u›a{T ƒ#?¯L7gEXÑÚÐ}³®+v{µ6ÜÅÙœNxnA?F¬§‡²òN¡UgÖû7°ö©¨ñ 6‰’89_CªeürTZ¬ìi½Æˆò‡Ùÿð²>êYöžìL¥~Ov¤Óuv§Œ0Nzìâqª-3]í×]7÷V?,q¬° ¯›þ'ÝRƈeÊDB„Nn%Ë–I‡eÒb™Ëu‡mrˆm˜£Ç¹)dk·È–8ŒÀ&E,mÂB76šP33®þØâ™óÐ!/ÛÏ|Ц 
-}çŒAº!ŠÔÞ—ÆAÞªÆ4Œ 
-êÅDzíÊú¾ç1µ57Ì<äc¨*t0“¦A‰Xž&8“nyÈ ݦ}+…­Ql±û´ú÷­õƒ   ¦Ö­™nØ?æyI.8 cwK3LY4/„¯îþééÁÊ r:øOÍÍ™®VúlP7
-ÐZwwZÀ3™úš81gËÇ(hmêìßhdM™·˯‹Âæ‡ DM­;ÕǃM®Î»Í oØ•;;à,Ç:Æ,åòþ¢à%¾[RÙ_–Jåö»¬kçéVg¹ŒÎë¨æãŽ7‹Á
-¦ÐÄîʼ SÜ»·k£ÙãúpwdöC|wÙDˆÔ]ƒ™Uä
+xÚÕZKsÜF¾ëWÌ-£ª ÝO’]{òú‘(U+'–öU‰Ô Gâ†C*CŽd¥òã4ºùÒ[ÞË–Ë¥&6Ðhàk
+l¨"°¯6A(…lì«âŽ}9ƒ±
+W Ú·~Hž/7!cëŸqůÞkÝùDj fy/‹”˜zó
+ÄqdÓÔ4:0Q:†mžTÕÄ4}Y‹Ó<eéó”220¸=ÄôéÓ§á>ŠP–¿êkdÓ†klS!ºâ"Ø=¥tߨïŠä.OÁ«Âx}zÜ%uZáƒY×%zÜ/y¼.O "ï^Šämé%Z|V†áújO}E”ÌM\=¦Û .ÜAÆŠ¸çÑZX•²_éî[`7ìºGë$ÏiÐÓžQFåxì+”û¶h¦_ß>X €¾MN•ÿ
+)„›rCªUHã­-‘¡Ù|Hö5ê„LV6ÒH=$n‚myxÌÓÚ.U ½~í?¸}ø‡FÞÌMÑd, 6}­ ÑüⴾϙÝ
+Ùm†¿yYÜ[ëÁø.¥¿´Ô=Øô¸v¡‘‹`0]¶ópÑpYåË:Û¿LĦâA¬$ÿ?FŠ³@1kÍ(FÖœŠž9?¦UŠNŒ;{ýáöêý¿i|H«*¹÷ž±/P¨À€°áìö‡"1È]ØþÛÌö{.Ô÷˜nËbŸÝDë(ˆÂpI´ç‹îÙŠÃÛ”é‰þè!C†Î0
+žÓÏYUgÅ};GWjE,8º}¸JŸ,¶³ÎÏMŒëx!ÊCò”mû@Ô[|Õ¡ÇWü¦¢÷û¤²8„4€›‚¨ ö'Àëê‚÷\]
+ÇÌí¢]ñu /yéг=?x}AÏæ0îÐrB9÷)Q‹ÓáŽß“=D¨ÁÍÀ þˆ±ðfÏzÈjú›<•Ù®¸~‘¦.`j“ég@Ô"ðÊ=ó¶Þ3ðevðËýDH¹wn+gŒ#Çl)ë²Í˜çB“TuRW#¹pSJ³ ×såö£KA.Éa z‚ÿ‰‰ï1«5šƒÇ úü¶êÛ½1ÝìwÞ|:Š(ÁŸ7_—í¼ù.\Åo§ôø’—çñi^tƒO#Ñ“øÔ}{iĺ¼¿Gä‘<"Upd@ Ì#¸Xÿ4zAl1–‘šäUI¤»”(.çrD÷qúù1϶Y¿}—QŒnk7¥Å— 4˜F'Ô7³ èR§÷åñe#¢0EslZ_€’ 9<À='âZ‘æS¨|¬™1+hÆiÝEðXû ÂÛobÎð–H|¥t&7uç…˜`1Ç) 0uSÃæsÎýÔöh†YqW„Ô6‡ ©Õª+%A,bÿ©õ—´K0k,ù`OГmD½¤Õ_¦V qu-çârÒrÊ„>i*Ñ Õ™9G–#Ìœ´œVB}‰å DŠ"í<ƒŽ«X/å/]¶|ð\(sw:<îî\½»ÚçÍ6Ù>¤lþ?/„y2j–iSJËÁDn©"Øhæ8J-%´œ‡áüJ®ñJû;[Æ ¤Õ½¥¾…¥^n¸q8ê€ôßTD²«wã_˜f»tŸœò†œˆ@½BÇ1‘t 3 Åû¥ÍèdØY%Ú3á\>k£†*T" +¬~9£ê·S‘ñm¢P>ÿÖ¥¾–²9Z“Ã8ÍæJ(ái«ì²÷Á†Ë…Ô±,á”?ëlý8ù2_‹Îùš€:G ÆçWÔpWÔ/cDŒ<Õ_ùšT±+¨•ú¾ƒ…Ÿ Ãx¡'*ñ­]§3å°x·օú;.d]ÔÀA°ÚGÔ¯õ«v M1N
+öüúë½Î/nøR†Ôe›ñ>ÏE fùèñïqä,<”Ù(¹ €ç+0È“â z ÁÕ@2¿w,öξ‚­!ׇä×ì’¯mÃ`oOÞxÈ/4pùNZÔôL¥SE‡d—z1´O§û"´­!æûs4†ý£ÓÎ@ÛvíºÎÕ¿ÞDìôÃðÝãXÕø®+(ãvDG‡æ&òèBT¸ùrÂÝÈ–"øqÃI*¹y,èXN ôØñ,B€‹Øx
+¦´¡¢öY¨Ý†Ö§ca àPKW
+ X…ó®tØfpÅsÙœÿ˜lÓ³«y¹MÇj$wºcÕ|UP‚˜zõ„õñÊoÇÝÉõYì­Jú”ºôìÎåq³ÝtÉ@Bª»`º.ÛyÓ5\=ÓÍÞº’¾Cí"„ƨí<×X»¾c€é˜Å}õnÒºš´k“ÕÏ[ׇCRø>-5¬\jœä§9«+ªóE«wØf¬î¹ÜÖ¤ËAÅ${®±ä¾Eu5S}Ñÿ+‹²»!B³tõ×e›±›çBå÷ù©z8èór›@Éôžà÷(8ýÃÙfÆyÓð˜’EKm¥.ÛyÓ4\iÁ§Šù0qÜM£G
+p¥å‚‚žk¬`߆²X4œ¶á}FWRX£bTŶ—ï_io¨ B®—rÙ.ÛŒ½=—¿%9¯I”Æv¨^ì¹Æ‚Ì q_òÛ¬zÌ<6˜ðjر½Ob>µe¢SÓÚâM­¯ËÚ½ª’Ú©¹4ƒ)h*ÑÜHÁ0+¶ùi矚¯²¢ÍR†ÅŒŠ€|¯ù.+v¯Þ|?‘`àL𘸛óð½võ¨I8!ò$£™?¹‚WW×82S>ñyÈüéÝŠÌÚ˹n×Ä·eènöìÉâ»2ÃYÛËb;çLû…³ñÒý^—mÆs=—»@?+w;0Y€ÍËn
+°‘ìé¬'ümÓm¶2Ϫº!êï&V&6ñ•±ú=ƒe“Ù {aÕþ”ÅÛÃ%bç7%Š…K-±×Ì/à“í&y¶swĶ:.‹?Êý~î.@è@‹æbë+ïDl@(‘çÖ×0Ö×,(Ï„V¦·@ÿc4ìàûNþ.«ZâÛë››wohÜZâ#Ôšðñýëµ+ª*ݺß_MbŒÅ„\ÐE§¿ÔQw͹S7/ÆÆÅŸŠªæ2î%­¦ñFµ…Öpþtn¸Ç{®§Ôw†ëÐ 4k~w梾ãÏ:'öþ;ˆýê_¶?ªÿ’ñ9 ,ïƒDÊ)…à|¨¹–q cM¨þ'[–Cendstream
endobj
-1032 0 obj <<
+1320 0 obj <<
/Type /Page
-/Contents 1033 0 R
-/Resources 1031 0 R
+/Contents 1321 0 R
+/Resources 1319 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1011 0 R
+/Parent 1277 0 R
>> endobj
-1034 0 obj <<
-/D [1032 0 R /XYZ 56.6929 794.5015 null]
+1322 0 obj <<
+/D [1320 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1031 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F53 1029 0 R /F14 740 0 R /F21 714 0 R /F22 737 0 R /F48 953 0 R /F55 1037 0 R >>
+1319 0 obj <<
+/Font << /F37 1018 0 R /F48 1228 0 R /F55 1311 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1040 0 obj <<
-/Length 3964
-/Filter /FlateDecode
->>
-stream
-xÚ­[ÝsÛ6÷_á·“g"Ÿ$x÷”¦IëÎ\ÚK|3mhŠ²x¡HW¤âúæþøÛÅIA’;½Éd‚ `±Øß.h~Íà¿6:a2W×Y®͸¾.·WìúÞ}wÅÍÒ-ÇTßÜ]½~/³ë<ÉS‘^ß­Gs™„ïïV?/Þ~ÿ槻wo–B³…Ln–:e‹oþúŽz>Á+­ÿðoüðþö»¿|s“©ÅÝín–ËŒ¼<öÇŸÞÆ}ºù|÷ÃÕ»»°‹ñN9“¸…_¯~þÌ®W°á®X"s£¯Ÿà%<ÏÅõöJi™h%¥ïi®>]ý-L8zk‡Æ$§¥I´YDtBŒDÇ%OL*Íu¦ó$•BZÙÕ«›¥LÕ¢îñW/v7Ü,ªa¿k«H#Õrq·ñ/‹¦éžzP´ÔWý6T»¶h¨÷ÑŽïʪwdCGd«
-ȶu[Q÷Ó¦jQzÀ#ñ(™NxÆì ™k‹mµrdã­H•¤B¥ŽjS¸=”Ýö±uì륔y’åéõ’ó$×ZXâ~èëö!™Ÿg
-æWÙuÆÓÄdŒG…¨–c2+leÆÂfÐ1Ú RÆ?/?1Ê$SJ^`ÀS30=íÔ$™Ð3>ÁîA‘…\ ›
-bÑW»¯ÕŽ:ë-È».†ªy¾áœ/@$ã‹UYµ‘”›¢}¨nø¢§çm±ªüŒtöû‡ u¬žáüê’–Ù?®`^zѹånÿõþ£;*à1åfzTé"ðÀõ¢íjôÅ×jEM«[\Ñ^°c[ôîÛ¿0&šªO’/î÷nøSÝ4Ôºwƒˆë¦ñ³®»Ý-½¢é×D±u‹úÅþÝíÞVsk rbÜ ó;£c2Ïrkx"3Îðú¡Ø Öòdž.nפüjl#`äF³Ì)ÿò1b\%™äŽ‚ÈýcUÖÈg0©ñ¬C&/Kò\zÃû“›ybô¸t*Ç{ N·FN‰¼SAÂâfÉ-µƒc±Âs‘(%fÖ<]ü3ªþŽÜ >žp7\ðDÈ‹ÞF&Ê(9ö68çÁÛØG4î³~%Õèâ³ô‚_“ö+
-YvEY­ ÞÏ€ ¼°®§:^w¦Q u¤>Yø¶-éh·äð
-™_7û~sÒÐϯ ýhݸ¡O~ W/\Y”›s*%Rhäæ’hFdgDã©‚hЃGŒA“Üüƒ9x5
--ˆ §w÷u»zýöûÀ
-›lDX{>uYÆ+QJ1碌GçЬm¯“ÏÀgÞqª|> cÝíÛÕ«Èa¢ô!gùTB§NÂe&<“®Bȸs‹Øjºî µê6"‰L%:åéÑ‘~©žc'
-¨–eÞeÿÂ4CÍÄÉŸÀl*tÇK¤€Ø¤òZÓ?÷¨.«z™?
-KAˆÜÖM±ß?ù‰=]¬¨h-ÑŠó1°>å‘uŽöe‚G^Ê\¸ ˜¾Õ)¤VïZŒÉ´ÅýÎi øFÉÓ|~?úŒåT¼¹iv"ZAr‘3>q«}ü¢L†MÅ¥†0’ùd1n†rS–e/ÄèÝÈsO†X#†f•‡páRîØ\)šòGp†ÐrP¨]HþðŸÕáR _>LVÑ÷]‰7_t6/Í0¹˜ø?ŠT&‚“¡àzzcþi6*ƒC¯‹¨ØÚÔå†(€ô™:¼Áö*Z7½ŸôÞ/€zZž;ø”Ý[Y„„6¡Äc!
-2<ÈóGÞ€©Ú ‘ç°m?ëc·bÓª$3ʳÄ\
-hᣣwêÈ}ÁS,/ÊC
-½È°uïèÀ1EIqm­
-¹ë"ž}éw71åe¬æÌLô-B9ä©Ç‰ÎŠÞ…ö(Ö~„°uõ: ÁÀ]kÍ5P=8wñ2 ÿÊŒ˜V~M*ÇÚ•(s‚Ç/Öµà³Û@=¸±ãcrI…
-”µFVU3íT¿Q1]õüZ›˜Õ[G×Êò¦ qÌjœ£Û¹)|6ÕC•@lO_»y<ûô´0Z:V1Tw"§—Tò[ F5ìé± ÒshP¨tž~!dØä@ ÂF¸UÚ¼àlsî'»ø¡†CåS#CçH‰²„‰`翯Ȃׇ<*_Ün³ý3¸½ß|®‚T³T£§ÔÜ“eË~œÂÝw2씄t”±”_:’Œ±È‘ØÕb)1Øaž…kˆß§qÓ9w90 =9X);Âù¥&?ïj +b"Üå{­;üî„>ú¡Ô{‹°(=#ã¯|NlÀ̬Våpœ0‹íÞFIá**Â~Í‚?¶”KÍU·-¬=MíÊeþ«©|a¯P€+±®Õ¹.yû¢±Õ½Ñ*›r`+ rƒgþª„ ›½M!¤ô|ôÃŽÔ7õ—*†BŪçIn¸œYÉüZI­ †B¬Lú’oÌjLüËÇe˜q9ž2r  £š²3j J)N´{–
-zô¦è\½*îÏrôßýËø3X€à.ºó§ŽzÎ]˜*U
-ÍC·³,ª2Èü‚Q̶¤é!&5U,¤Š„ûDiüsSû²œÿÈ ëÚä¹'*)륋Çb×[¤§Rï U”eõ8¸vûL ¶JQ>½Rém*—á/4•Ý~ eå“ùÜb‘ªôK,c³-Êåv¥ãçaDÈ9œêÙÏƼîµîN?û!YÐ:wý2Ê9GÈ p·(E_-Så/FÊnå?L òCâ>Vë„ïߺϨµ2.¼#,dâEÁÝà  ¹„&6¥Ž„d‡L¼'OUP7ExxãPèß»›Ky*¼Ù1²pOxÂDak¹–qŽ\Ö~àeò]dtþú]VXi@SÊ_˜—d©_ãJÁÇK¸À¿¸s©vPN€-[]F’Cª†ß¹ y¢,~d/
-ž‡WÔÚžŽ:îݵØãŠø™ßD¢=Ø—ti§tØ#lÚ˜èçÈ@ø*ò½I$¿ËÀ¢BîvB¼€º$Ëó™<7O£›_ÒG7»VdëçY¢3Zi
-â!@}ñæ|ÎQ~F×N.?1p”dmþÄ_}HàŸjDjçðßéãþ‹ÃÊ`„7FÄ‹ð’¥dÃŽ)Ü4çsÎߎ³þ?¡.ܯendstream
+1325 0 obj <<
+/Length 3852
+/Filter /FlateDecode
+>>
+stream
+xÚÝZÝÛ6ß¿Â(¨ˆU~Jdó”öÒÜöpI/Ù¶èZ[k ±¥­%g»-ú¿ß ‡¤$›Þ,zo?˜"G$çƒ3¿ŠÏüøLçYn…Vešq=[î.Øl c¯.¸§Y¢Å˜ê‹ë‹Ï¾’ÅÌf6ùìúv4—ɘ1|v½úi.3™] lþúÅ¿^^.„fów/ß^j=ÿþÜó›o^¾}qY¨ùõÕ›×ï.³jþå?^|s(>>Ç—o^uõêÛažË_®¿¾xy¹sÊ™D~½øé6[Ã__°LZ£g÷ðÀ2n­˜í.”–™VR†žíÅ»‹Ç G£îÕ”ä`8˹‚$·I¢"G Å3žÛ<ŠW™‘x Ï´µz©P¼åjõ{ÛTÈìg_i="WEf+` ¤ˆ&s
+›SXOôSbÙ¢È=Ár[v]b©3“ÃkOœæC]ݧ6#3‹š!¢_~ILËÌJaÂvÚæ¶^öe_·Í±¾¥
+Ž&ÛŒ¡ayy’cêú}ݬaÓhæ®ZÖ?3&*”jÁçŽÍÂë;™Cï¶n|·SɘŽ,
+‘S%sc3-lp›²Û$ØœúŒ¬ù=Å )Oô MKÀ ­èÈ$Ö–9¸Å(‘aéé¬E&0 Q`ܳ¸Ü?Üõíz_Þmê%„iÀ ¸raŠ©J×US(V­™ßºÝµ;z"ƒj’ZííÑs«VàÙØ4ÿ~S5 ' ˊܘ±e$¸ƒÀes>æ—ðN¦/÷°Ïg#ÿ†ƒA­Ø¾¯·[j9a‹ù¶-W·º!7¾Nª¬¬˜žMšLÛ±äZGÇéõv-ýûÓ¤ÉwÇ÷AÕî bf8:˲¡Æ]µïêΓ—·=úiפ¿ßY<Ž“sQûE»rw·M9_­³¼`ÁiMâöDð_„“Î-ødÃ{
+â!0Y Œ'—E¦Œ Æ_ýæö®`—X;7™PŠ{Ú¾=ZbUÝ–‡m?¨æóÄ‚`Ýà9¤”S ý-& `߬à äŒEÙ¸‡ñ†]ǧÐÿpçIveúzN·.îbë“Ñ«ÙêæOðçóOSAÂïe²çŸ™f¯Û¾:Ã;\¾¯z¯ð¨®ÚÕ‹e»m½I•t€MRS)£öt#2Xš#š€uQ@X†£ò(˜S“‘
+ù]UÛÿk09¦€
+^¸î7Ô"dTQi†ÅEÊ 7=¾Š<"™{3æV Š¾Äx)ìbÝ”ýa€óR†H£Ôí”ýÎe@oIݦôù©ª%=÷.eî}•›p0 t"‡ÿ¦¥áûò:zßqG¾ìC½òo„ÉÑ"4Òº¹Ã¶›)¿Þ!ôÓÆõ|y‰ûÈB?!
+̘"쉽C‚¶í2¾ æ·ížéö˜mjà `Йå£$óxcj€:Ю»D4E&u°üϪ~ù.v Ih."@uæ® 5å*ŸšÊÍùVvS¹…CSQ÷HÞ@w8rÓD¼*”$6ÅׂeJDزHÉ‹ƒ·QÑÕR–˜6¼º&?ñÔ`;œþ¦õŒÞb}–P¦ÃŽ&gv*¡sJ•™*DØ$ÁSÀá ?ÄØÚ¶í{j%ªBe:çúD¥ï«‡tæ\° H´{šüNN…Þât‰Òm©ÂKÝC‡æ²ª÷)×*0g †|_v4ùªBY6Îḵª†Z䪠ñÅÕë¿YH®ùô¾9Ôc¢»ÂYÅÄ·’wAp‚‘ˆ‰!AWÇ…†\)9:ggä¤À•¼ˆrò†à5.>N‹ ûæþ‡˜˜,th€¯àú ”åÅo/ÊÄ^@«p
+‰yi·Ü×7”$Ô
+
+Aîê4¶_Ϩñv4ùbLŠ3NfÅÅßUËáÈç™ÈÔñf8ÀÆe>ÙÍ Ø‰TÙÄél£ºA’犧ʹóÏ; 2—.ž> ž†p Šµ‚\Qh…ÿ®ÞÕÛrï_o‰"ö´·)G¦áü*Ο^±£zdÕÎóâô[XB:®Ž‘Ë/K ÌqyØ{kß(ùQ¢id_í
+|:ŽOˆ"±æ—>…’VOÄÃÄ^„Wë‹Í*u6m¦lŒ
+<ÊáfˆÂƒÌ0²hWì\íQŽÆðYùÄËÞPdí²ÆHIh˜6X_JTL>…5¦@Áu4â0þiáÅáG}@ÅÖ¦^nˆH¨sØ<쪲ñÓ‡IoÂòÊ¡£åÖ£ ô5B‡±€ÐUð…±€ŒPÉ1Ò¤¨Š@
+Ò¦QØ_?¹"δx’¬Û•±¡\öXìæyôìSma´TT~ZŒP6ÿ˜i@z«áÁÈh†=–ôGv
+•ÞSÀ?„ —4ØÄnÀT…6OЭåÁ
+ˬ•£{NÅìüª÷Ìvàö~ ©
+RM½Z¸8÷䶅i,ç„‚ýeÌéÖ e,çSIÁXB%nµTF¬±æÉô_¹b\(Ë}V
+ì´Ü ÎŸS!¬ß\
+!eØG¼Ô†—·õûäÕñÏB¨„˜!•3\’I “0¼Å— ÌIæú)ŸÐ¼ø7éhqÆÅxÊÓË
+Î 3Ãʘñä3Ç뤮TÒcP˜"%ùrUÚŸYôßõgÌ
+žðg°
+y¢,~O
+_ò†<¨u=-uÜøwÔb¯áj|‰çÁ Ò]¤›ÒW|€G`Ú¤ @øìè³…3ÅÇNTÌÝΈP—dÖÉcò]M¸xò ×kGþéöá(Ñ­4ñ Œþè½øœ“üŒn|~6ÚÀI’5>ó”ôiJWëŸ^8>ô!^7õÎ]àžû¨#ÞlŒÝºÿ§ÓÞ¥>¦a 5.l4K÷ Jà?ñé·ÝðùÅä` ø¾‰ áë“ç©
+z\ŽT0©ßerÚeê«r©3ü<q­Â¢(ÿç/·ñú#Î|ŒRüäK†Máι8Ù9g™¹Hlý¿Ñ7ëendstream
endobj
-1039 0 obj <<
+1324 0 obj <<
/Type /Page
-/Contents 1040 0 R
-/Resources 1038 0 R
+/Contents 1325 0 R
+/Resources 1323 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1011 0 R
-/Annots [ 1042 0 R ]
+/Parent 1328 0 R
+/Annots [ 1327 0 R ]
>> endobj
-1042 0 obj <<
+1327 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [120.1376 318.9001 176.3563 328.1154]
+/Rect [91.7912 473.8206 148.0099 483.036]
/Subtype /Link
/A << /S /GoTo /D (controls_statement_definition_and_usage) >>
>> endobj
-1041 0 obj <<
-/D [1039 0 R /XYZ 85.0394 794.5015 null]
+1326 0 obj <<
+/D [1324 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1038 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F48 953 0 R /F41 939 0 R /F55 1037 0 R >>
+1323 0 obj <<
+/Font << /F37 1018 0 R /F48 1228 0 R /F55 1311 0 R /F22 953 0 R /F21 930 0 R /F53 1303 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1046 0 obj <<
-/Length 1675
+1332 0 obj <<
+/Length 1516
/Filter /FlateDecode
>>
stream
-xÚÝXmoÛ6þî_!û`ÃQ$×Oi¦îдKœlmW Š¤ØBõâYr³`èßQ$eÙ–Û  ¶að‰Òñîx÷ÜsgÃx<D¡¢Ê*@îÅÅ{sxw6"VÆwB~_êÙltôœ O!ÒЛÝötI„¥$Þ,y?fˆ¡ hÀãóãW§Ÿr<¾<½˜p>¾†K»~ýæôâx"‚ñlúúürâ ¬‚ñÉ‹ã73'ñu'¯ÏŸOÏ®6z&f/G§³îý“Ìô~½ÿ€½ür„S’{w°Àˆ(E½bp†xÀ˜{’.G?u
-{oÛ­ƒ‘#QÒÐQÚ $ˆ+Å=Á
-emèŽÍÉê¨X橹/²2+¢Ü,âªüc:_¯¢&«JóP?qÒYm®‘½ÞVy^ÝÕ?èÐ=HÏìùT!)ekùcz?ñCŒÇ«2‰ëVêž•ó AŠs“å(ŸW«¬YFðÉ¢ˆb¿Hø“§íì¤i+]§ñ*m¬hÌ.îo(/§g×ëv]F'ÏŠ6¿½|Ö¼ý9˜¿-¯ñôŒ,Þ]Íßê~zv:O¨Òï~´êým—Œ‘Ï;¦£ÕR‡ª>|³9Io£uÞøuºú”®Œ4¡aø‘Á3¹m°hЋݠ¤çã\*„jef —F“Úïmnoíµ¬›(ÏÓ¤Kõ~r ÆHaÀ<n5¥M|¤½C€ Û$C¡Ðqkð®ZçΈ†‘¹m©cQDe2„-ŸHÀ¾ 9Ü ¤5 ûΊÊ>… %Dh k- Ó¼Š’O}»Á*í¾¦—×õQ¦qcîa—E³\V++ 837p
-»?Zשݽ°7eTØ;¾òÕ„Èqë«š$&KZç—v·¥Û7’W1Ôø
-Ç,-zÌööÒžwQÕÍS³þl.P;õ–ܦ¢Œ˜­¬Aó)-“i]D¹."‡p˦YaÉbǸ¦¸û!s!^ •ò§”ôá¼Ó”¨ £Jz”H²à!m‰"¥™d°)ùF¿¯²í8[ÎQ©#2ÜXvÄ¿6W\æÈòå(äDlõE‡A%Z@m}Ë\BTÀÞ&*¾æ¡yZ˜¢B:á¥î|ÆÂ]–ëÔ¨PãòSZf’üÞ¼‹My@¢ŒD4”"p†„aß™C¤óƒàÛ]›C:û­…ûj uÏ°²ÈÒFóº2ñb,D%b»$Y½Ì#í1¡–
-sÍqÉÁ *$—’ÚøçMº*a†ù”Bî!ÐrLÈ ûÁveG5“¹*5Ü75µ@‡Öîó£4?Üå¹ .øÔ–úzib šˆB¥ú`.(eMÛÅRK<–ÊÊ,ª$»½°&Uå {H C'5]G]кCS 0AL€ŸqD»IžN|&`úÎæe4ˆ6M±R1„r’®š(kãMÆWçÓ_Ì]m÷Âv}žÛq‚¸N©E]§Ô¯+³£‰>º·Ë4Ît
-‚°'Œ<Á³Ó‹W‡!ÜSùhÞssÂ}? á8OSvÔ0ý#kcìÑNúÿÆô %ÿ
-Æ(E\Äalz>; ±žÆGƒØž—Ãë»ù@ìÑNú_„cABÉ`VÛß(÷¾UÂ?U$¯)ü×ÁB ~ÒÄÞWQûШ›ïÊЙ”(Hæ#FaªAZ—F¡{ŸwÝ—V+Õsý/• gÀendstream
+xÚÝX[oÔF~ß_á‡>ìJx2÷KyJQ€ (YªJUÆv²^;];„¨ê½¶×¢ªBû°ž™3gÎùæ;›D~$Òafx¤ G¥ÛŽ.aíÙ‚™¸Š‡R¿¬GO™Š 2’Êh}1Ð¥ÖšDëìÝòÉóã×ë“7«˜
+¼dh ‰—gÇ/OüÌ9, ±ü­“xòêìéé³·oŽWŠ/ק¯ÎV±Â†Ãίï}õúd¿ï|õ~ýbq²î½zJ0³.üµx÷G8üb3ZD70ÀˆC£í‚ †g¬›)ç‹_{…ƒU·u9Á4šªè(@G0<s)ad”9èÖ›¢ñžý1-óG~P\„ÿªi“²Ì3?LëñÑSNFz12¼ÅNãQÞ¦G»*KQZW^~d‡fHjIƒx8ð¦¾.»Cʲ¾ñí&÷i½Ý&UöóÌñ1Ñൖž2Œj§÷§ ª¢¥d8Øš¸Š%ÆË]^ÖI6ci6ÅÊíkk0I 0©ªò´õƒn’P…0üˆ^Õ» `óàEØŸ\7yؽ U² OM¾û”ïÆÊw+¢—ÎV š&þ–¬Î/í®«É!e&¥õ€ˆ AFê<Û&馨â7¹?Îv+½¼®ª¢º «E»ñOµ½®~PiÝƺ ¼µù6¯ÚfîöÀjÖÊ8Üv·Õ^ÌßÎJ®¦Xm;[/´‡Ü
+S†Œ¼‘p`”Wéþ›ºiûñ?þïc~ÛŒä,Iþ„ÙNì±;$V)FºC|òkMÜó—oãªõÿ›¤#}2@ª°ä†pôÅõÝ\$jŒ(¥dÈðI†b„#© ú$‘ˆ(Lï“£(2Zëù ÷ã¡J—~FÆ1" QÚKY­‡¨uqìÝ@sJ’‚èq4¾éYi”£¸×6<Xh
+*^Ï%ÑqÙæ»*i‹O9Ü!ÊG îŸSÅLjy;mvëÂÔçÃ9² Ä(ãšÛ'3&*(ˆ¸¿i‡€ø<ÄúõUH3@ØÜ(Òi>¤Ä5!lÊ&—yB
+ªêpà¶ÎŠ‹Û™Ó4dZCÅ}`—Qí^4iûÒŽzÐz„¡ÐrLS !f‚¥Ûf2ºŠ¡Á€F¬¸¬’Y²ÙË¡³!Ü7ƒù®M
+‡7Y¾=;ýÝ?5a? h_{a>´¤«žV´«žv¹ö;Úäc·z•§…0õã$m‹ºjy¹¤ñ³YÞ¤»âƒoœ RW“ÓFeÓªÿPæh®(¯7ynjà€ŠºÕ¾8\7}9žÏˆXÊû8þhsÚL†®’aÞ»kÀдžÈþJ@ÎDHsŸzÂ\{,&åÛvu† `»Ó¿ƒ®ðØ혔´Þ©˜+(† ÚwÔ#)A„q
+a¨‘ÒÚ·Ôç§Ïž¿}=ŠbHYÊ×På÷™Ù«œ1sx“ÜᶙùÄÆ@3é³÷ÔÇ}"
+e-›ËÄAFàê2B—uöMíÄ”, Hšü€rÜæRðD’†VÐ6îß³~ ô^„¾Âa Íã²ã0¼P¿¼›Ä^%yPt~‰ÄC;ïMâ´Ì»„Ù×ÓŽ‚ùç¢ýËÌÕœeÐbpÃù×h&8Âá» °ìôl}7ÉŒdVΓl`åÁ±óôÿÂ1b(ŠHÀšF5þtuð ÞY‘2öµA!4gs_ºpÔ½o÷wµýçFè ™Ötž à ¼0DЕ‚.ÏÂî±û׉ ŒÿAáôendstream
endobj
-1045 0 obj <<
+1331 0 obj <<
/Type /Page
-/Contents 1046 0 R
-/Resources 1044 0 R
+/Contents 1332 0 R
+/Resources 1330 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1011 0 R
+/Parent 1328 0 R
>> endobj
-1047 0 obj <<
-/D [1045 0 R /XYZ 56.6929 794.5015 null]
+1333 0 obj <<
+/D [1331 0 R /XYZ 85.0394 794.5015 null]
>> endobj
126 0 obj <<
-/D [1045 0 R /XYZ 56.6929 424.8255 null]
+/D [1331 0 R /XYZ 85.0394 556.3324 null]
>> endobj
-1048 0 obj <<
-/D [1045 0 R /XYZ 56.6929 397.5211 null]
+1334 0 obj <<
+/D [1331 0 R /XYZ 85.0394 529.0279 null]
>> endobj
-1049 0 obj <<
-/D [1045 0 R /XYZ 56.6929 368.0037 null]
+1335 0 obj <<
+/D [1331 0 R /XYZ 85.0394 499.5106 null]
>> endobj
-1050 0 obj <<
-/D [1045 0 R /XYZ 56.6929 356.0485 null]
+1336 0 obj <<
+/D [1331 0 R /XYZ 85.0394 487.5554 null]
>> endobj
-1044 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F41 939 0 R /F48 953 0 R /F21 714 0 R >>
+1330 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F41 1208 0 R /F48 1228 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1054 0 obj <<
-/Length 2369
+1339 0 obj <<
+/Length 69
/Filter /FlateDecode
>>
stream
-xÚ¥XKsã6¾ûWè¶TÕÁ‹
-D%턱 -¸îBYt.xj(´:þÆ©ò|"¥u# Lüá£èªW~ãž~ÁÂa¤kƦ=Ÿâò¤ñTtÞôÀ¢)sðjA/á]ÞÁmrèIújº}:£“Šûþ<‰Ž¼bÆî,µý–Îa„–½"–NÕH8 QÕCyjŽ“
-Wþóæ×ßù¦ýü|Ùʳtó>8Fh¹9Üh!Yž§:Œ´7·7ÿ‰Â2ÅŒOÖyÑ>¼<v,Yí‚t;¥9ÜL-,/»ßäˆ/¼YSRÓ›ý0Óqj´Ë4g),ð:þe»3"¹ƒÿ2y{©à©ˆ¦ ¦&ܽÒÍŸÁ¸ÎsE‹f´»ë¤7ðÝûƒÜ¼éáF›Ù¥ãÝœ³»”‘ дŒ[ d€5)÷¹:A–¹X?-·ÒV¦df“¯[àÞ;,(‹Îo€MÔ}=ca§° C£_ÒrœVN÷+Ò«QsP3
-ŸRéÄëÂ-|ÔøAWv8qùššéW5#ý¶}Q9Í
-¤B$·ø@÷OM÷°¦)y/—±Ðññ–
-­a­ ƒE9×ܪ``M¾6ãÿP}@’ ±ŒÐ.ˆ`•\?ô³â.ëîðÐ(yâ><¨b,ó)@+Ã6õáÕ5«þ ±Ÿg1»þ¦?¦,µS%ºêà‚e&ÕóÁ@D1f3¯kXJZ¾qÀÔ2B‹5xy-
-@ ¿Ž† ci:†/†a|n þy›Ö³ÐçÙ­Ý ÜìÔ|õ—9¨ßCðË0åº;E9­š‡[˜Ô€»ˆ%ÁÕë¿Žà“wëx- ½³’À±:AÕ¡†—2ô@eì‚Æ0öG>u! b jŸÉ°øœÒ‹].õ eŠí¼ª¦azцB­‰ý­4«)1™"—Û͆Ñ÷¹*š¤ÈhB+ÎL½MX<»‹ñwÁ¨--\—̆=3?†>¶jܹ㠕”$Šw:¸÷$ Ñ:@y¬»‹i<üä
->H±”ôu€;ŠON«@bî„×yæ­ƒ˜åà`~Ƥ`ë'š‹7Ià‹iŒ»ŽöyzÞñX‡4
-†}Ó(OënˆÝ"½ì'BMmMˆ©ìn-àaï8E¡s“x
+xÚ3T0
endobj
-1053 0 obj <<
+1338 0 obj <<
/Type /Page
-/Contents 1054 0 R
-/Resources 1052 0 R
+/Contents 1339 0 R
+/Resources 1337 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1068 0 R
-/Annots [ 1058 0 R 1059 0 R ]
+/Parent 1328 0 R
>> endobj
-1051 0 obj <<
+1340 0 obj <<
+/D [1338 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+1337 0 obj <<
+/ProcSet [ /PDF ]
+>> endobj
+1344 0 obj <<
+/Length 2407
+/Filter /FlateDecode
+>>
+stream
+xÚ¥YKÛ8¾÷¯ðme RÄ·¸{ÚÍ ™:Øtïa03Z’»…±%Ç’“éüú­b‘²d«Ó ÄY,Ö‹U_±Ù*‡lU¨,V®Œ•™Ê™Z•û›|õ
+ «©E¦
+nVé”Éîo^¿çlÅóLk®V÷Ûñ,mT¦ )V÷կɛGwêã:å*Oäú÷ûŸh›ÌLanËá›å’I¿áßÕW×–uE;ÞÞÞÑà}í†Ó±îGLfBj8h“å $C2cë”åyžÜvC³}
+[øÊfVsv‘I%éLŠ:¹ýtÿñý/4nzü5‰£Ï}]>º¶é÷ô9<º!¬ïvÝ·>¹Þ+‹ã¾>~­aa舸%‰‹º‰´;÷µ¾Úf’nK“xôC}ÁË¡b¨
+c™UŠ{U¾wmý äB%•\´¹J>¶4u\³"©ûC×ö5Í 7üu£eÏfb\g‚™AÞÁ:×æ”,ÓR˜@¶õ‡tûÈ×ÿDËà˜T\™¼Â‰-VÈ8üÖìv4*ëò¹°}¥÷nÀQ3­ÑzMô¢‘Rb5H0ó’Ò¹]h5¡×ñw\*OG2Z;ÐÄ™?|¸¶z6né<gÚfhÜø¸Ë“†£kû-Ù!‹®ä,c… ¨|ßatä&Ùw$}5í¶;îÝàeÀ ·éN 1ܨ@g.ÍKn69ÌÙ+béMoTu_›ÃY
+W6©BpÂ
+¢I[ÃäÚ91Àáh‰(ü3Ò§Ó ×6¹æ;sªœc®D*°Z̺rM yIˆ N(‚ϱEr¿þPé´1ò/¤P#sÈ”B‡®ìv¤™ÏKàÂþP—ÍoyΡBúÌ&´«z^šŸ>¿Cf­Î.Í2Fã™Ö Ê_n~ý=_U`ŸŸnòLØB­¾ÁGž¾Úß ­µJÆ™ÝÍÝÍGŽÂ
+‘éœéçyѾx…!íP¬Ò(]*8à1÷Ȩìve1¿Àª°6“¹¥;{;±±ÒÒ# –gJðèŠOëT³äþçÉ»KË
+SDôçÃÃ@x´»'¡w˜+ "1f¼ù¤È,Üì£ù™0Ž–ïé3€>5áwâ„K¤`Á.ä›&‘¿——0*«í* {ÿvÖœ¦º3±ž¶X“N'ÒqåZ±ÐïðÐï¼}W6%eüÿ*Ÿ/7?ã&mã&?ö%~ýìëá±C
+ƒ·¡Å/øx#}o›žž‹$ͳ"·± z_?ǘ«ŒÉoˆazèvM¹„0Ò(SØ@]î|›‹=Ój(íjØåQï5k€cy!£~ý€rP• Œâv^RöÐ÷]8ƒ
+×j ¤‡
+΄£Màõ¿|ŒÜHÖôA-08×I@t98ÔÌÁˆÏùMã혽B†·Ã³å `æp„²Þ"°q—o—^ÇãsÇM´^„ |UÀ1øXžÆÛŒØ<âr“ü–«üû¦GŒ—¼{÷Ö-m»ðhŽ|€Jä¹ùç_4’ÏŸï>~xEë·°•z…)AÃK,¹pÝ׶½ÿ¬&TdÍ9³à¤Õ‚w:|d…êäÛ£dZK&œÈªVŸ±*Œ£_KSÐ=5m8#<ÌÁ,–JÍ#D±”îI—€-`ñcóÝÓ|Ä—×Ç:—üK³›”Œ üs
+ý1àÖº@TÿyÀp.ª…aGØ…~æII¨L>óznvFš¥Â¦ˆBE D¨3SÏ>º^÷µµ^endstream
+endobj
+1343 0 obj <<
+/Type /Page
+/Contents 1344 0 R
+/Resources 1342 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1328 0 R
+/Annots [ 1348 0 R 1349 0 R 1357 0 R ]
+>> endobj
+1341 0 obj <<
/Type /XObject
/Subtype /Form
/FormType 1
/PTEX.FileName (/usr/local/share/db2latex/xsl/figures/note.pdf)
/PTEX.PageNumber 1
-/PTEX.InfoDict 1069 0 R
+/PTEX.InfoDict 1358 0 R
/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000]
/BBox [0.00000000 0.00000000 27.00000000 27.00000000]
/Resources <<
/ProcSet [ /PDF ]
/ExtGState <<
-/R4 1070 0 R
+/R4 1359 0 R
>>>>
-/Length 1071 0 R
+/Length 1360 0 R
/Filter /FlateDecode
>>
stream
@@ -4193,12 +5045,12 @@ qª„Ñ«ò^ÿï>‹«>÷— .13×…Óƒ!¶3¢SËAÕ”ih¥Å¨Š^…(€<Îm䦽ªšÛÆlLÊâ³ò7Ù
n*Œ1½÷¨¾x¥Æˆpîâ‹&XîÃœ§³±è\íD¤ßä0}#XŒûž˜‹¸À>#^V°¡|2Îi‰9ÊÎr)`˜¢Xh¡Ò& „hb—H°Œe"Ãê
þrÓGçX5¾ûû8‡´ÕªOª«t–Ô³$Ây°‰—BÒ›ÀÄ5©/¨vp÷o`kA“ôr ±ñœÓ4N.4Žæ
endobj
-1069 0 obj
+1358 0 obj
<<
/Producer (AFPL Ghostscript 6.50)
>>
endobj
-1070 0 obj
+1359 0 obj
<<
/Type /ExtGState
/Name /R4
@@ -4208,679 +5060,1180 @@ endobj
/SA true
>>
endobj
-1071 0 obj
+1360 0 obj
1049
endobj
-1058 0 obj <<
+1348 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [470.3398 477.3512 539.579 489.4108]
+/Rect [470.3398 467.2776 539.579 479.3373]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1059 0 obj <<
+1349 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [316.7164 465.396 385.3363 477.4557]
+/Rect [316.7164 455.3224 385.3363 467.3821]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1055 0 obj <<
-/D [1053 0 R /XYZ 85.0394 794.5015 null]
+1357 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [304.6433 163.6578 373.3153 175.7175]
+/Subtype /Link
+/A << /S /GoTo /D (dynamic_update_policies) >>
+>> endobj
+1345 0 obj <<
+/D [1343 0 R /XYZ 85.0394 794.5015 null]
>> endobj
130 0 obj <<
-/D [1053 0 R /XYZ 85.0394 769.5949 null]
+/D [1343 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1056 0 obj <<
-/D [1053 0 R /XYZ 85.0394 580.0302 null]
+1346 0 obj <<
+/D [1343 0 R /XYZ 85.0394 576.3463 null]
>> endobj
134 0 obj <<
-/D [1053 0 R /XYZ 85.0394 580.0302 null]
+/D [1343 0 R /XYZ 85.0394 576.3463 null]
>> endobj
-1057 0 obj <<
-/D [1053 0 R /XYZ 85.0394 539.9341 null]
+1347 0 obj <<
+/D [1343 0 R /XYZ 85.0394 533.5444 null]
>> endobj
138 0 obj <<
-/D [1053 0 R /XYZ 85.0394 315.9171 null]
+/D [1343 0 R /XYZ 85.0394 299.6823 null]
>> endobj
-1066 0 obj <<
-/D [1053 0 R /XYZ 85.0394 282.0038 null]
->> endobj
-142 0 obj <<
-/D [1053 0 R /XYZ 85.0394 146.7217 null]
->> endobj
-1067 0 obj <<
-/D [1053 0 R /XYZ 85.0394 117.3479 null]
+1356 0 obj <<
+/D [1343 0 R /XYZ 85.0394 263.0631 null]
>> endobj
-1052 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R /F62 1062 0 R /F63 1065 0 R /F41 939 0 R >>
-/XObject << /Im2 1051 0 R >>
+1342 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R /F62 1352 0 R /F63 1355 0 R /F48 1228 0 R /F41 1208 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1076 0 obj <<
-/Length 3492
-/Filter /FlateDecode
->>
-stream
-xÚ¥Év¤Fò®¯ÐÍè½.H’„™“Ü’ÆígË=’fy^(n
-Ê@©ºúë'¶d©Böa^È%2222ö,ÿÒƒŸ©#7J‚äÒ$¡«=__fÛ ïòæþqá ÌÊ­¦Pß>]¼¿Sæ2q“(ˆ.ŸÖ\±ëűù”ÿâ„®r¯
-Öë›_ù¾ï\߸½á©›{Áqw{{=ýëáöñê·§ï/nŸ†CMî{
-OôÇÅ/¿y—9œÿû ÏUI¬/Ðñ\?I‚ËíE¨•«C¥ìHuñxñÏád––.2Ò÷Ü@EÁ'ƒ`‰“:q#(âäÓ¦€cEÆéŠöµh¹}(«Š[iÕ5Üj²,íʦN«ê(PmÙËbäë¯Aæûí¿Ì_œé-þ¬Ùzu_Ô}'¸×'Àû]žöEίMMÃ±Ó -¥]HSpÀˆ•ï»‰ÖêWÏ ª.3TŽX"x8ö[7=7rFSÛm‘—°).ñtÝ;`®H³Àët[fÜa"ßyó\dé¾dý&• ;Êá³lntUs¨MQs+]:M•¶W~ì¼ ‚ ±ü€¾#» ³&àâ=ðƒbì2ë®/Ò(T(Ìb/mŽ//ªôhñ=í&ü¥K€¯¯ù»-ë}_t„UÀÀ©Êú…çÒ</{šù¹X‹™ìŽ©`´ðM?]ÆÙUiVéʹٷ‚4¶„›ðØÙÑ™›¬è˜àr›Ö] ,`
-4•Îæþ^h¦ƒ+ 5»à´Îú‰kŒŠ„ÏŸÊMÐÒ0Ðß[¾röuβë; ,/ë´=²ˆe% eûmקuF7‡Ò§´ò+ J‚Ah™?Û敤b"²¾p•ƒ¯c¢gVçe<&§5ɨ§Åpè7hO0´]ºfm„vùRóIŠÜD)v/Ñ´æ?LN Aƒàæ †X¬µNÝŠ²D¤åpå­ô®Ûìû¼9ÂF&³6í6$]@NÏsV’"Á "{ä‘íüÞì[”ê°ò
-x ®Îšv×´i_ØžŠÉ‚=
-‚‰Á€aòOzjþ¶ãqgv)0 rº©E`| ËŽylÃú §Î†áNdñäØJ|Œ¾ìSàN_0:…r´ #è`SbHY5ζ¡kN¬¼fl ¡?ñlà‡ †ð熇ûMÃ"š¦f§iœ³ GéGLƒWáùlõ”'Õ€0¶{Ùháˆ1·b<JРiÐæëäbr‹ÓegUÉꎀ³bN ìL{ƒ©£<µÜ]ùÖt·u.»u}³[0âaà*å%ÖÒ³m¸^˜¹¨~ijÄÆ96{nlÒW$/
-#[ö ñô¡c§S†¹!-®÷$¾¨,醴 kÖÍèÝvðºù~‡xˆ±Õ´Ÿÿ¶?ÖÎMÙ¥ÏÕâ=”
-•sÜAÂp«:Ä fçáz–Àº§
-ÙX-¨×56ð„Ž¾U*tvE‹ÀvCq–Ãë=…**´F¦&¦ÆÑH^‹‘”‰ Å—ˆKDÄè@0,VÖ‚“Œ NíHÎÝ¥
-c×x¡0Ê/œ=­Öm³]å€:@T û‚CHP´ ËNÔ*ŒÜ0ð‚9OºbÈ%‰g±+D:LÇÅÝ|ã&`Cçñ*äòq¨ƒEÆÊ–Õa¬­u2ƺV`nfYÔF†•Ð
-¡û¾ØîzîPhˆE8Ò€ÅÆ¡7Ù¡ìy¶”~ñeW•Y‰…1êç–æ ±î‰$Ç·ÍÛyÇL—°és³ï¹ÉøXÌÄڼ㙮(¸Á²€°E—µånÄCN *°õ^œØ›i±Â×õ+’”ó+ÒÚÕ:±W”U’_þå.ÚÀåy6º”*Ê9zå¹¾¯­´v=Ø 9c"p> /Q˜œÆF¡ÄFp'ýXeÿ“p'f·Uô"K`%0]Ãï¨#tq˜×âðkY¨Âr%‡Çºò¹„=‡,G _”]¨Alt;ª()Úà,XÁ‰­²–
-ƒŠâKå;ÃŒ±5‘¦âȈ–Êwß±M\0^G‘’Ú¹PÂ]å°ý ¹VüþN%NEèÀ&3–±
-ý0#ä#›|7ótR °©ùŸ–y~"oÖ%·D™ÒÏsìl`¢³R†£D¡¨»ü„@Gð][*Œ’0Ùˆƒ0Šh0BÈ…|%±B„mž¼êÄÆÀÌPL[zí€õXšq)ÉOUò vËš›,ߟpIJ»ŠŒžÞ8Ζ²²k¶2’ÏF±àFÌ°¡rp¿¡ø7“/•¬š93Å
-Þ@"ìmOì.… GE‹´¨d¤Oâ)¨ŠôsÇM2Æ Äß-•I±#@è×_Ë”;„$²ÃÒ PU´ ‰âKŠ¥ly7„VyDN%5luéëëñ­ûç•fŸ³\N¨
- ¹VEè´­@c~Bž92|Mµ?ã*5á?Ìo ˆ`ðV•q¾k¨­6@ŽK2Ù£‚€•Àª4ÏÅZu§Ñ ƒG¬&¶{“¬/´%9¶òȽA©c«¥°
-5\$û¡è¿¡,
-Ÿ»@Eº:«µÚ[(ü*WùÆöâjÜŒý):í­ôˆÏg’7©=› ΰ3yYD ®äÒzbµ‰W’ä%dÿ¸
-›è$ŒNÓžá2Í ›Ü‘§r3<±ŠÊàˆS6±Ÿæ%6ÃŽøã'©Amu›l©Á߉S1˜?m1ˆOÛò«ÝL²xÚ›æ´ýé(íâ_kªZÞ ›ÿ÷?xÆÿ9…ÆUq,—Ç»a H„(丞QnÿêsNúÿ
+1365 0 obj <<
+/Length 3579
+/Filter /FlateDecode
+>>
+stream
+xÚ¥ZIw㸾ûWèú½‡.ÉÉÓmg:/ñLlgy³ ’²8M‘.V{~}ªP”ÙÓ‡<ˆµ
+6ÏÐ÷׫Çlí ­;êÛ§«oîd²Éü,ñæiïÐJý MÃÍSñ“ùÒ¿
+÷ñþýÃí?n“È»ùûõV¨Àûñûû[*==ÜÜ?ÞÝ><Rõç@ÿ{÷
+ì´ †wÐn Ð—ÝKÙQù|(›‹n\¼ëª®C/§úÄœ¡?®BñTë!²”¥0“Kíþb™ ¼`ÍpÚÅɾömw4lj2:¨>ʦ IA3‘†Bùy(›¾jÒ(t4$MSIŒªŠdý_›zED ÊIdÔdZ
+ÞÔ¡k.7-÷î˜hYT¤dP>êf4ûF˜ò'&~&EjvM›Œ“Yý |®Œ‘BI×}K¥6Ï5ÊUGuÕÀ“1"*Æã ¿„œØ3Xúy{<Õå0ÕЇ¡gÚû‹Á¤ÏUXNqJB‡–ÊN4]+š9p$•5àLxöK<ƒBA¤±ëª\Á¢ætYèéý`Ø}¥Î<~¨Ð&ß°ÜÏõØ3±á y3
+îlgÛR¡¯Û3"s‡’^ƒ’š`í ˆIo¡dÎß™]PÙ“®ÿ6'É›=~lú¡ÔìXȈ™-R…¶¤W”µ~µôŒe›Eèk„
+ÒÝÐ#XXDË+Ó”Ç~ÐMn$‡Ú§´úË ÊĤ´ÄŸ#`\±TÙ¹ƒÆAâpìÌÚ<¯@ø…íº!$¤§pè…ZX ëõž¬ò¹±ÎüÆ3ç?´¡ †Šx†3h"µV|8uÇÆ+‘w\£qýaŠöÌ[îÌ;ÝŒvÁv곚3mPÙWêaq ¨Là/8ÐÁÝ5àŸNmGÜ4PE*+vcc"ôÌŸÙ” Âðƒ¥¶ýD%cL<‰‘ÍŒä¶Z÷<e&Žò\õïçÈÍ]ŒÙ;Ö\' jÖÇ6pgj¬R`¢Ö5ÎKëÝ—¯á„uuI³_­­·»p£}u¬:Må¬W`â8A%§0JÊ…ÛS;è3»a¯Ða“Tl?Ð:;eÁ¡’ôìÏ]ç¡L4Æ“cKëç…÷<jàÎP9‰z´¢#è`µaHf#Þ,ñŽ­sfõ5'€Ì܆͡9ô€?O¨y8´„n  •¶!§™xoœµ?sÂêb.âùböÙOƦ
+ˆG—2È,Ò6ü  ]ØÞG<Kšx¯íH…ƒ~Áí¥ìA¡åH4uåÛ­iôÌ…t
+±Ìd'b|çJæìÛÙ»ÃØÉëã¤é=b©í>ý°?UÞ‡ª×»zΦ
+j=§’úq’IÇ¥kn5 . '·JíË4¶°AmÞò\y0SS•:5×R*ô5ãOÀ!O ´ .–d¬‡Ò, üÔïÖ ¡¢ ¥hÆcD<Ž#Ô”-r–QjÎð
+´Úl8 <ëfXžŒ (Ñq–zxûȦÐOžüö^þ‡9žï Ä'“’G³¡ÄÝ?õ‘³ŽÞj¶š %&êÀ*½ñâ Wð]Gjä]$’cä„D"é€ FoŸH¬a™ú™®¼Àè™2i+ê‚ó1/=Ó’ Ü|ꊞW°Òâ“I¿| À)%í6N”+qì­xfß¹¥(wF$Œà ÃpbrÁÃÁÄ'¸M¾
+Gg\ªà 8"À`xbílgC‹›d¬.â)h¨Ký©§¢cDߣɑb ÃЯ¿Tš*%„$¼Âî`ªˆ ™qÄgylþ;
endobj
-1075 0 obj <<
+1364 0 obj <<
/Type /Page
-/Contents 1076 0 R
-/Resources 1074 0 R
+/Contents 1365 0 R
+/Resources 1363 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1068 0 R
-/Annots [ 1079 0 R 1080 0 R ]
+/Parent 1328 0 R
+/Annots [ 1369 0 R 1370 0 R ]
>> endobj
-1079 0 obj <<
+1369 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [464.1993 469.2511 511.2325 481.3107]
+/Rect [464.1993 393.2115 511.2325 405.2711]
/Subtype /Link
/A << /S /GoTo /D (proposed_standards) >>
>> endobj
-1080 0 obj <<
+1370 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [55.6967 458.3121 105.4 469.3555]
+/Rect [55.6967 382.2725 105.4 393.3159]
/Subtype /Link
/A << /S /GoTo /D (proposed_standards) >>
>> endobj
-1077 0 obj <<
-/D [1075 0 R /XYZ 56.6929 794.5015 null]
+1366 0 obj <<
+/D [1364 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-146 0 obj <<
-/D [1075 0 R /XYZ 56.6929 535.4755 null]
+142 0 obj <<
+/D [1364 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1078 0 obj <<
-/D [1075 0 R /XYZ 56.6929 501.7295 null]
+1367 0 obj <<
+/D [1364 0 R /XYZ 56.6929 749.4437 null]
>> endobj
-150 0 obj <<
-/D [1075 0 R /XYZ 56.6929 345.0948 null]
+146 0 obj <<
+/D [1364 0 R /XYZ 56.6929 458.7525 null]
>> endobj
-1081 0 obj <<
-/D [1075 0 R /XYZ 56.6929 309.1395 null]
+1368 0 obj <<
+/D [1364 0 R /XYZ 56.6929 425.4132 null]
>> endobj
-154 0 obj <<
-/D [1075 0 R /XYZ 56.6929 120.0167 null]
+150 0 obj <<
+/D [1364 0 R /XYZ 56.6929 270.5184 null]
>> endobj
-1082 0 obj <<
-/D [1075 0 R /XYZ 56.6929 92.4013 null]
+1371 0 obj <<
+/D [1364 0 R /XYZ 56.6929 234.9696 null]
>> endobj
-1074 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F41 939 0 R /F21 714 0 R /F55 1037 0 R /F48 953 0 R /F39 899 0 R >>
+1363 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F55 1311 0 R /F48 1228 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1086 0 obj <<
-/Length 3046
+1375 0 obj <<
+/Length 3172
/Filter /FlateDecode
>>
stream
-xÚå]“Û¶ñý~…Þ¢ËD>LžÜøÒ8»I|m3M2SJ¢-Ö:Ry'_;ýïÝÅ HQÒ]3}êxÎÅb±ß»”˜qø'fF3®òd–å Ó\èÙêîŠÏÞÃÚ¯„ƒYx E õ‡Û«Ï¿VÙ,gy*ÓÙí»—aÜ1»]ÿ<ÿê›ßßÞüx½šÏv½Ð)Ÿ¿xù—k!ÄüÅ›¯n^ÒÒË7oiðõÍ‹ë,™ßþùǘ&Ñöùo¿ÿîÕm¿ã×Ûo¯nn¥ñmWHæoW?ÿÊgk¸Ô·Wœ©ÜèÙ^8y.gwW‰VL'Jù™íÕÛ«ÂhÕnâŽV†i#³ öH9ųTIeÙÓìé2¿H™4÷][­KÒd[®ºª©é¥yGÏ‚uÙšý‡Ïè­ÛªÖ=Õ¶XnKÐx@7±»_n«C‚óˆN>[ˆŒåY"-…7‹»Ý¶„ƒTbæ¯j¿gp·T°4K4ìÅ-‡¢î€ %óyE3¯ê®Ü×Å–¦WÛª 0H>—%ÕñÊþZ˜yÙ6ÛR~Œ±mš¶«‹»Òá+êu¼¡W›¢~ïÞcð
-³…§z!˵¦ûªn€i6ß•ÍÎRc”>-ÿì Ô2MåüÖO¯š»]Q?ÒK±myŽÀ°
-ƒž#ð]qï
-Fâ²Vp4 b]‚E(î„Ópgàé¶j7n~Sµ¨ŒR;aÀ\ÏuØp¨BœnËŽ¦îwnïÁ!…•–¦pœAýñ»ö(lbòùŸêr„Ìá‡ÑÒ-5îHϤŸL`¼dùü®yUÓ1Nˆ5½úžVÚ]±*a W«æ¸¶60Ú;X¤‰ZœZz¨šV–Eë¼ L¢ ![¥eÝT«;#h†!µ³ÍÇGë¥&.klU8'ÖÛC‡´lÐܬ·&µCmª<ª¡·«ê‘²½|ý·‘j1d–z`kðæ$Œ/Æ‹¦—xÕÔ¿p.ßßÓå×4kõžïšýز&…ßÿÛ}¹¯J«œ&A§SîºÁJ@@ô¿÷ `ÊL¥©w¡mÕ•‚²=®Q,5©tàŸM`\$Z0®10‘€DÀ,按L¨¥%E –8Rpð´Âäç"ÉH‘KÃ@Ùb>È'a!Gq%2%IÀY¡ã,jP´šöŽE21z¨Ö I-€Š<öløÐâ éŽÈgãÈz¯²+=xç`QÇ (Ä]A¦ˆÓúËaÒßÃõc¬˜¯(9ÉkÇ ÈZt³!7Nœ–áöìq¹)Î3‘ÂÏ´Ò$L©sž¡âîªR$,•`%CrË9š>OçÎùu–Ñ„sø#bRHWÓ4{ò5S–©;MßOÀPè'_ÏbôÜX7ñÔ3¹™iìá͇¿4rŽðrwߺ«.KÇ%1£¹:•c—)]þ…ÏuÕ‚“lôF  ‚W °ÊÒ‡†f·áôòŽxçp`°ÇAŸJ—Ú(¦Üoµ½_Wõ{‡ßÆ
-8 {~ÙÐ1J5çŽÍ†C¤´I«”øbxvI8_<•Eq ÑGšÊÚóGÈm\¶é<•8‡DâÚW#N(/¸_a‚3µÊ;¡aJ²4É%M3.žåÈÁrà
-n‹ÍU1 ãPnlac$ðç~»¦ˆKµƒiï)ó¢í/k—ù4Eü]¹´ÓítÎw†…'Ð¥GzNl&E
-†‚/˜ÊM¹•’{K<8ãYi~‰¯BçÞ;ëvpCª<<æÖB—@ñ¶"²£¾R’JØK½þÉeœŠOpìôÍ…Ö,ƒÒÙ_…Ý}t~6‘à}µN†Zyþ)$I".ñÒ+à¼ÀlÍÒ$(1^“yÙ+8Nš¡G°uŠ•Z¯+4f´`ÌÐWÔS„qÅôlJ1n¤<{GÉOŸkRrelRtvC†„¤»
-gwåª"gÇ篢É#¹ã¤Íî)$@­•Q㡶u©U5psëUÈšÑ=£ÚüýÓO¼r%SÊ•Ìw „)òá°‡bDâ}yùrXu¾¢•öîÀÃT—åÚÆ%ÜV®Š{e
-KùzIÅ1"F²ølTnyb|Âkë8·æ©öiÀTï©›¦ÊÓà ÏAŸ)ÝhPxQuèªÅzxΰõp:ÄãÈüÄ·ÌgQ“m·‘"k2|yöÅ„ñâñ9ËD–Úã?µ43̱U)X–¨„Í›ëEÊ 3>§§×ÔAÞ?Õ[x¤ƒë¾ASJ»ºœFå#°³´s³$^ÙŒÅ̦ؾssî šnC.½UuÀè'BÚo}ý®tÚõi¼¸Î]Vd7–ë)´ùÏçj{+ž“ý„Æ7½ýऻSXÎùoH‰IÉÑc[gØÂÔ t †¸¨¥ƒ#W"ìÊýöZÌm—ÛfÞIß­·ú|‰ç§:HGÓŽÍÏòiØXq
-<‘šGPÖÁž0ÓQ ÏVÔ–ö‰Y娮w4OZÞ!ó7Êa07fTÜÔÅEßÇR®…®¶=DŽWé’½!Æ>w—¹oŸÁt_†¸üÏÎFaÁ³˜’Œ§pÒFËó}Y¬>„öé ¾NÝÔ—¼h{²½*!DÚŒ¯tQ¡]9&R§ÖvÔÐÓu*a´»¶Y@•°˜£rÍ–RÅlØÐÛ·(ˆ)B{ Ð[6á†c PÚŠçqâ3$L™PÛ÷Dþ“3“*ŸïDTüRFÊ1ßḴhŸ¤ðN5]êa-*Û4oGfYbÛï»òªñPþ¸-~øypÈ›-ë2† M˜î®»¬Õůnà¶U˜¢õù
-½ór>æ¿Ðƒ
-Ögµýg"Äpâ3Ô~ødÔÇÝ¡ŸéÕgèà(=êÛúâÔ‡@Ë2ìÙÏš1”ýnEAT&ÀШU "Š¹vž&ÙùSÔñ±£ÌÆI:<ö;ÈéÒ”6rŸpò¿õÈ'J¥™N¹º\æ«Ìè'”]É3k¸]:,óOHPæ’%ôY ÆP§% .Jð쩽Ž”ààØÿ¥/ô!ñ4Ϩ ŸÒf”ù°ÍxZT¢2M.2‚:#HuYçN9>vZñ±Oä‘¿~eyZv§y¥SfÐQžçUu†Wê2¯Îñj|ì4¯âcoú¶Ò¨|ôÿúÏ€Ãh@Yšæq>†Ê~š÷{ Œ§é0íù¦Ï’OòÿTÞö¤Ð"%‡c!$ž—QuFF게ÎÉh|ì´ŒâcÿC —,—yvA‚Ô z¨Ë<wj$Áñ±ÓŒ½le Ѧ.Ÿ$E-dxÙ“¤˜>;ªü—R„œ NÌyžOwrð‡ µü²„ú9Yõsà%XѸ¯®8Oi}曋6
-o!ô˜òðÃÎcÒÿ’
+xÚå]sãÆíÝ¿Bo¡3'v¿¹LŸ®9§¹Lr¹äÜ6Ó$3¥%Þ™=™TDÚ:ç×Xì’KŠ’ìfúÔуö°
+ú[5w—<Ùµ_®‹»rMeaäøÎr ¨£çìÅå„‘¼®Wé N¯÷üÂ4# X€d*yЖ„6E®fðé4ÓR ø8ñ|[„Õå®ØÐdÕì¶Í®èJj«®ô`ÝmÑ…'JZ+j$b":Wz±ì´ªº+w5b™Nê²Û7»4ÙWÝ-v—Ü&e[î@‚nåµ{¬D­e&yë
+–³/êÕ+ò¤¢´†Ë«MUö0Èþß”JLÇ;^›ÍæÁƒ
+ÀíÛ¦íð®x|N]Ã㽺-êéÈ…ì+p=RÙ4Y²-wáqŒJÀ'>·@ºÏgŒH®Ã2\aRlÚ†FA"0¬úÁ ˜EGÜy€Î?ì/"\­ÊÖíÚ~wUªçl+PX6õæ‘´Ž†ÙNM¦ âÞ®šnÖ€zàÍÆÛ#I`lœ½yE·t0Ö´çr°¯×(YÎð"
+ ¶z[­n=Þ0,y¨-¹ÍOÎGÍÖ!šÚתð.¬+6Çîè¦q}©SP}]UOl üëœeÑ¥Ô£›3¯`œØ MX¾ñÀ«¦þ…1ñážÎ¾¦UgŽðÿ¾ÙíI*kBP„ç»/wUélÓ*t9å¶íôæ¯ÉRiLp yÚ³}èo­„„ÂþbãRiž2™O¬Ä,þæ,å—#NO§
+œŸå6ïq.UFö{ˆ\Øl-–ƒxö rT—†LD¯è•Ž«h@Ñ® üŠH%ä€Aj<XR  <ýÎz´8![Âyl9çUve
+ °®‚ê¯÷ȃrP1¡N^~8¢¸ƒP‰Áp_„5WÔÈdÓ4éP°ˆ•©ÃáÂ# :}]nª‡€Ãómwp^O4.´Å n’\jPG èújIŒÕ1"&ºx1)¶3!ßuUœß \‡,`®ï4¨MSÝé „²sT/Þ–~4ª»¨6ôµb=¦3î;ð_{.? Ý2¦Œ»¼“ŽÛÄŽ5Ýü‹ì‹™»‹M`ÁÂ’ÿܱ¾0ÇN8O3%5ù™7—KÃ3þsFÿÁPGYÿ\'nŽÜ×´/)uh·ºQùH#ì*mý*iG.aq÷å¶Ø¼÷kþ ÝE\šUu1,ôY“ÔQñ.µ€†¬&¾m€CŸ¹ËõÜ téË“µ;Ëéúô]#f‡ëƒ‹þLýv>Ê~û4p©¬!?=q7
+3ƒ¾ý4ÆEýùa[î6—<yt/Q\Þ­†VÕ´ÍÚG,?Ö>:¸/íôö99»*Þ€góÊù×#·tÒ¾sõu¤CÞC—rò¤?Þ=ò<¹x¤½ú¼ßJÁŽ¼˜•qC7CKú&zÚvùÜy¤ÿ>×cRw‘‡Þ,EˆOÿÜj<3Ë9Íg]aä°‚ÜoŠÕǾuzDîÑÛ¤HÐM}Ή¶ÇZ«AdÌ8¥srík1n¼U»QCÿ¾K £í¥Ë2(ƒy‚¶Ý¶2–2Àöm}‡‚dÂu0н“>ph =”vÚyœyAéF*m_»îöLö“§ÖÈ’èxTùR>Ê0ÛSöP³O²wo?)5€}âá.Õ)®_ÞNne‰=<ï*XÆCUr|åóà!Q6`×ç 3†pª±î£¾‡ îÚ™KÑ~Bt¥v1º„Á…5ϼ~ÔY
+åk~ðú1yAä! Qwìeë»7ÊùÅ/µ¾8ö–Y
+CEÕ0´2ÂE¥ϦD1ÑÎÊNSí¡ÉNÒv+3&û-¤thÊYÈ6ÙÈ[NÚã3õˆÔ©6Lž¯ñefõj.õÌ‚NgÆ5þ1 J“f"³g4AÐ`€:¯ÁST# NÉÎk0&û¿Ôà™~ ÏŒ}Fùü”# ÌÇ-Æ㊧Q÷œ"#¨Š PçyŠj¤È)ÙyEÆdŸ®Èw>B8*+µ<øIYÅPÇeÕC•ÕIªƒ¬ÈÎÊjDöjè)MjÇðÞox8Ž”£igc¡ÜKùдΘ1ãóë!G>*ÿcYÛ“B 7?¿1gtAÐQ€:¯£ST#MÉÎë(&ûÿZ¸Â¯¡Ä™êb¨ Pç5xŠj¤Á)Ùy ÆdÏß2Ð(}’t^‹Z¤áeOÒ¢yvTù/µ¸XJ ˜³<Ÿ\ö²ÿD!SÔïË”ÿNKEݘôµ4þ+®SVŸ…Îb¦ü—|n¸÷Kÿv¯Âp´.ÛÕ®º¡¯3€ÔMó€_A=’¼iº2 *º0
+L…ÿ1NÌÑlyÙó¨G¯‰ÿ<©EFoc§wòæPdNŠ-Z|lîwçAQÙQ†Î_[–S“V «¤]púÒô1'mî>,hðcdÜ=ü2~àиñ¢ ÞÅ_ÁÉ”pã>3sp¿Ð9¦¸¢WÄÒ²Tkk¦oâð4©ßÇ‚?QÀqâw¬3|³þÕ?ü¹ìàØÔoÖŠy HfR+ò,0…g<tjýwµ‡¬ÿíp~endstream
endobj
-1085 0 obj <<
+1374 0 obj <<
/Type /Page
-/Contents 1086 0 R
-/Resources 1084 0 R
+/Contents 1375 0 R
+/Resources 1373 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1068 0 R
-/Annots [ 1088 0 R ]
+/Parent 1328 0 R
+/Annots [ 1378 0 R ]
>> endobj
-1088 0 obj <<
+1378 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [417.8476 169.1947 466.5943 181.2543]
+/Rect [417.8476 110.3446 466.5943 122.4042]
/Subtype /Link
/A << /S /GoTo /D (sample_configuration) >>
>> endobj
-1087 0 obj <<
-/D [1085 0 R /XYZ 85.0394 794.5015 null]
+1376 0 obj <<
+/D [1374 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1084 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F39 899 0 R /F41 939 0 R /F14 740 0 R >>
+154 0 obj <<
+/D [1374 0 R /XYZ 85.0394 769.5949 null]
+>> endobj
+1377 0 obj <<
+/D [1374 0 R /XYZ 85.0394 749.3028 null]
+>> endobj
+1373 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F39 1151 0 R /F41 1208 0 R /F14 956 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1091 0 obj <<
-/Length 826
+1381 0 obj <<
+/Length 735
/Filter /FlateDecode
>>
stream
-xÚÕW[OÛ0~ϯˆxjâø–Ûxê lCb4Û ð¥*¥I‰ÃmÓþûì¸IêJ'¤©Rë8Çß9þÎwÜcdCñA¶ç?‘Dxyv:· }-Þ}²ÐÒÆiŒÝêcl¹G$°#ùØ·ã+ +0 ‘OÏP0p09ýú%:؃ƒÃ“ÉÐA!õÂÁÁçÑi<>SóéèðÇ!4Œµ%rp4 :ˆ¿Ÿ'ÃËøØÇm¤ún$2Ì[ëüÚS±©c …žý  @Q„í¹E=<JH3“Yë[ ¨½­—ÙA`âc=iô„øP@^|‚IM
+xÚÅWMs›0½ó+˜œà Y€a|r§m¦“IcÚKšÅrÊ Gïɯ@ ܤNÓÉL‚–§ÝÕ{om›Hü`Óõ ÀtvÍ83y!Þ}4ð´QBctHÇf
+:=øncŒ­éñþì µ¥z8œMí±c…ßNgsû<<2faÓiû4ѪÍKãì™ q¨#Aø®y#â ff8.…®C©Š¤ÆÜøÚ$l½­·jÙÁê =ÖÑãУ„ÖôDqj!+Y•Œ¯¢´Ëù Ŀш8“M0¨‚>Äíàã¤"Ct…FN7=»Õ¥ÿe’¯@².ÀE~1ÎÒÉnóuorTU ` ×%5B¨¶Ë0Ö‡%z™ó›ˆ/dÖ|•ÞMt¨ÑH:è2ïO®
+Ư/t-lvWo{‡ Ý‚Zr*4ÐÂ'ºzªë"ÊÖ)“ÏQšæ7 äѪX2.c?‹V¹¢€‰%Ö‘ ÛºÑr%¶õÄÓÈYQò$.åêòŠñ»M_qÌ
+-k²l úðÌ´“g.û‹F8‹¯x!>÷d[z!¼§Â@ëcýè4Í„Y” ÷B ]­:^#öŠ¤d²Û:Œól¯mGµ©s€ònÝ©¥¥v™¨†ö²Q¿ÈV9¹2ÏÔ$‰ <*“kÖ(–§We£@åÚ§meg@ûšÀ-Vy[ãm™ž­úÏZ-Š4RÜõ]u® /uy抺ԟLQŒú5´ã"=6ôeD·Òü_Æo¤ð¶Áï °Êù^7½M…É»ÍÒî³óêÑéÍÀKˆÅ» À¯d÷ÿ MÞMÝ5šº°ºûj.½¨cç+öÓÎRß'Íí™Ö홌}èø"ɦ©ªsì÷:Wwñ~ë¿ÈUendstream
endobj
-1090 0 obj <<
+1380 0 obj <<
/Type /Page
-/Contents 1091 0 R
-/Resources 1089 0 R
+/Contents 1381 0 R
+/Resources 1379 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1068 0 R
+/Parent 1383 0 R
>> endobj
-1092 0 obj <<
-/D [1090 0 R /XYZ 56.6929 794.5015 null]
+1382 0 obj <<
+/D [1380 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1089 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R >>
+1379 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1095 0 obj <<
-/Length 1945
+1386 0 obj <<
+/Length 1364
/Filter /FlateDecode
>>
stream
-xÚ­ksÛ6ò»~…&Ÿ¤™&
-žÉI}hõPíØ—û—èËЉ˜ù<¦’Ø2È>«~U´4‡ªnôWû.K5aÛÊžê¶ÍÊ=mº#­›5<…˜*±Q
-u1<3ME¨­¦µkô®Ëé”ÂÈô},K,Å1U­ÆH¸ruM8Šû‰6CPÇ,Ôœâ>\xåPuyj•«Ê–RÞªñôÄg*?Œlå‡ñ™=bIQ:@²DC*x¢Ôµ„¾{ç؈á+ÈœL´Àì±kÙt¦À±¡$Ô7¸"ˆ!½I 0 >Ûj_«ãT™7¢u!'îËýºtJ˜í‰VŠBFHª­yÝQ×YeÒݨuúfô|sÉd„ô<5ÖI_>-žÏ"Ï(Z­À¨bhK{ªÚC¦˜8°ãHX¶Îo3’¹ÏB)zÉX–3cˆËÏØœfØ80zÀGSt1xc?šaž•¶ËVÇÖV&n옒•gŒõO=mÃí¬£aa‚»¾Õñœ¥ Ü0°4ì<ôú‚Üq´B†ÌRö“ãv6x£K]›LGuîªÖÖ¼‡ö¿ëMºQ‰mçïTVO-¹…«ybÊ€˜DÜ3²¡æ¥ô fÕùĽ¶Ö–ô)I¿·êY2S³°bÃA²K6[Ý>j]’2ÇF)Ý>è8òm…Çb7¾Ìž)'ü¢#1ÇÒ'Œâ!:Ž@Ã+IMUo3xd°çáãk
+xÚ¥WÝÓ8ï_ñÔJ$µóÛ§…]¸åqл@È›8mtiRâd—ºÿýf<N7-î‡*Õ“ñx>~3öØÜaðãNy,ÈB'ÉB/b<ròíŒ9k˜{9ãFÆ…Ü©Ô³Õlù"HœÌËb?vVåDWê±4åΪx?þûå›ÕõÛ…ëGlz 7ŠÙüòê¯ç|~ùúùõM]½~GÄ‹ëËEÎW¾½F÷3\™•«w7/W¯f׫ƒÓ8 йϳ÷™S@(¯fÌ ²4rîáƒy<Ë|g; £À‹Â 9õìÝìƒÂɬ^jÃ$
+R/JýÄŠïÛ@‰2/ü@ƒrý¥—]#jŠø‹Ø­P}Õ6ÄØ´ª&?AFÉîNvDçmó1ý‚±|ò‰Iæ¸ï± ü@c";1cóª!«Š>¿ÒÀßã±ÿl釆™!3õø”ùïCõ~àeˆô‘zùŦÞæV;å®[w#;yF]¨Õµ;?è@ ν,Š|Ç%‚êÊó¼qù8ÿ{¹$…Jlwµ$ZÔu{ïöhT‰°"SÑ´D·ÔI8RGÆmKM¼ ,û&@›+…,ÅP÷ôñyÝÞ¸•çR)ÛJ²:5&E³?c‘Yì¤ê»*7&s‘oäO˜t' ¾žÔÅIü
+¼¼Ý>y¤üÉÑ~¿3«·°Ádg ²¬Fžl—d¤l[màâ'ËúQv­ÎÚŽ
+غ–›ÅØ‹cQRtù†p9³e±•cg<îgþω¶’8/À¸ÃC/cߤú|4ºƒ…Ë{¸·XRÖxB[bµ© úü8ž£ AmÚ®G2š¯‡ªÄí[3+û¾jÖô1ìh\-àâ„õ'r“`‚è‡nÁÓ¹4&0+èžÉ$˜€Äɘ8Õ ð®ú½qÓpŸÝ¼¾òˆ¼ém°Rå]u‹6ÍóhÖㆡG,=k.7C'È02‘SaVÞ˺>álDo1!(bú *˜ˆ‚¸%Ö6EU"·-N7F_)€{j+•ªÉë¡ <L·ÁN/ju‹¥Rš;iýÚ#´ñ·Ü›E¢)ˆÔyqU­Ó ¼ûªßEIOb¸ùÂíG>H$¸ZmEWÕ{úTÃnu‡Š’˜JXó5TZ`¼‘&”ECނωC.·Û¡©rI(‘ Æ2Obƒ™vTPGÐÊƃ^O•úp±ê«r¯Ÿ O­'®(e&½úª€=Yæ΄$lg% .À•ñù[}
+ÑKL æ—Ä£´ïéãÓ©
+ñ¦lÌ.Ù´C]çÚ¦§‚7nœ¿\ê}Ÿ¤fß'Ùƒzä’£4>U¹„J9$iè‰}óÆ5 ÃÆž9ò'+eÆF z{ãq’W°»Š8ƒê&' €n¿ëÛu'vre‚íÙD¾-Dv¸ºüò“ôá &^¦¾ýµ°ØKý,B˜yvêùáíú­ëÿ¨6Eendstream
endobj
-1094 0 obj <<
+1385 0 obj <<
/Type /Page
-/Contents 1095 0 R
-/Resources 1093 0 R
+/Contents 1386 0 R
+/Resources 1384 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1068 0 R
+/Parent 1383 0 R
>> endobj
-1096 0 obj <<
-/D [1094 0 R /XYZ 85.0394 794.5015 null]
+1387 0 obj <<
+/D [1385 0 R /XYZ 85.0394 794.5015 null]
>> endobj
158 0 obj <<
-/D [1094 0 R /XYZ 85.0394 418.0047 null]
+/D [1385 0 R /XYZ 85.0394 223.4026 null]
>> endobj
-1097 0 obj <<
-/D [1094 0 R /XYZ 85.0394 382.2497 null]
->> endobj
-162 0 obj <<
-/D [1094 0 R /XYZ 85.0394 223.9723 null]
->> endobj
-1098 0 obj <<
-/D [1094 0 R /XYZ 85.0394 195.8278 null]
->> endobj
-166 0 obj <<
-/D [1094 0 R /XYZ 85.0394 149.2124 null]
->> endobj
-1099 0 obj <<
-/D [1094 0 R /XYZ 85.0394 126.0612 null]
+1388 0 obj <<
+/D [1385 0 R /XYZ 85.0394 185.2496 null]
>> endobj
-1093 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R /F21 714 0 R /F39 899 0 R /F48 953 0 R >>
+1384 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F41 1208 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1102 0 obj <<
-/Length 2252
+1391 0 obj <<
+/Length 2265
/Filter /FlateDecode
>>
stream
-xÚ¥ÛvÛ6òÝ_¡Ó—P'!‚ ÁKsúà:Nêî&›­Õ}iú@I”Ä”"‘²ëÝÓß
-÷õì·ßùd GùùŒ3•¥zr ÎD–ÉÉö,ÒŠéH)©Î®Ïþé öVÍÖQΤŠåˆR¤SŠÎX¬¤2J™m
-8èáâŽe‹_”5Í;‡ñ™sYxä×ï"Ñ#œ)&E„ò Å¿mš¶!þ/ÙK«—ÿ±Ý¾¼É;» ˜H5S\;`ƒH‰àcÓmÊzM¼—å~*Ò Xt•óЭЉL¾š†Šó`~èŽ
-Á2­¥a7ÏÛ"Œ#2nQ/še±¤IÛíI
-ˆ…àC^òŠÈ½/êbŸweSëLjŒÖžÊT2IÅ=‘hÝÂËíÎ ÀrúìÁEŒ ™m_àñ–h³"è¼ìZˆ!õÃà&!
-Á îÛJA—ŸÄ‰~ŽýC<,ñú©ê¦o›=¦%b+Q¾ÌçÔ»+iªbõ Žñ „/å]sd­{#ÝÛ€h:`¨ ÁµÐÄuPTB@íÕÁÓžßh‡}ãQíÀõ+I| QepXàQbom(MY“e]Ë¡­rpà°œ×uùo“æäh›æ5–¨„é {Wb©º„€cK°
-B#w
-èjó~¬ÇL%"{ªÇL'©Ã²­UyÚ]}ò³N|l–îsN!ñ(Ùïnä“ÝSàx§ej´¶«H°XëlXý±îºíÔvႧuHtoþ¯ÕòÙµúÃñ˜d–¥LÀKó;ÍíÒÎjµ LŒMµyj‚%{„Y¶£í÷­]7Šƒ¯uV•Å.-æIiC¼eSØuÓ8\—›«8@óÚ²;–}suÇƽÆ€ðy–®™wÃ{gY^‰Lµ ‡…òøÖ4z½ó®ŒE*UO·Î*’®Õ½.Í¡©È |‘I|ÅJì#,ç4%a¿ŠÖjÊDó`G/"Œ–¢£™<n˪¢ÑÜ.ûÒfVMû¸
-  vW,l!/TÐÿ¤\?ZŠ’à‰Ò?>ï’aÅ4… @çž
-é=ÉÝo.÷Eÿ/~¶ÕAendstream
+xÚ¥Y[wÛ6~÷¯ÐéK©“%
+@aQÔyµ£iïŠ8yÈ‹‚F»Ïx=M‹\$>hœ&W]sN³ë7‹Kÿöz!”}mԆݽMÖ®çÜkòU¶±Võ}fô‚íò[]í2 ±D¨¥‘Å+M
+Nƽ“š2:Š`
+„®ìNgx8»u+–ª‹8¶3й=¨©¶Õ;w"ßU„¨Ø~ŠŽRâ×êçSîˆ(•AHÅ
+€u¾}¤1¡
+/ ‚3ÉÝýsÑÿdiÙendstream
endobj
-1101 0 obj <<
+1390 0 obj <<
/Type /Page
-/Contents 1102 0 R
-/Resources 1100 0 R
+/Contents 1391 0 R
+/Resources 1389 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1068 0 R
+/Parent 1383 0 R
>> endobj
-1103 0 obj <<
-/D [1101 0 R /XYZ 56.6929 794.5015 null]
+1392 0 obj <<
+/D [1390 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+162 0 obj <<
+/D [1390 0 R /XYZ 56.6929 726.8027 null]
+>> endobj
+1393 0 obj <<
+/D [1390 0 R /XYZ 56.6929 697.6944 null]
+>> endobj
+166 0 obj <<
+/D [1390 0 R /XYZ 56.6929 648.8841 null]
+>> endobj
+1394 0 obj <<
+/D [1390 0 R /XYZ 56.6929 624.769 null]
>> endobj
170 0 obj <<
-/D [1101 0 R /XYZ 56.6929 691.7741 null]
+/D [1390 0 R /XYZ 56.6929 472.4047 null]
>> endobj
-1104 0 obj <<
-/D [1101 0 R /XYZ 56.6929 668.7722 null]
+1395 0 obj <<
+/D [1390 0 R /XYZ 56.6929 448.2896 null]
>> endobj
174 0 obj <<
-/D [1101 0 R /XYZ 56.6929 579.8329 null]
+/D [1390 0 R /XYZ 56.6929 356.0575 null]
>> endobj
-1105 0 obj <<
-/D [1101 0 R /XYZ 56.6929 549.1878 null]
+1396 0 obj <<
+/D [1390 0 R /XYZ 56.6929 324.2991 null]
>> endobj
178 0 obj <<
-/D [1101 0 R /XYZ 56.6929 502.9124 null]
->> endobj
-1106 0 obj <<
-/D [1101 0 R /XYZ 56.6929 474.9173 null]
+/D [1390 0 R /XYZ 56.6929 275.4888 null]
>> endobj
-182 0 obj <<
-/D [1101 0 R /XYZ 56.6929 277.7919 null]
->> endobj
-1107 0 obj <<
-/D [1101 0 R /XYZ 56.6929 249.7968 null]
+1397 0 obj <<
+/D [1390 0 R /XYZ 56.6929 246.3805 null]
>> endobj
-1100 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F41 939 0 R /F21 714 0 R /F39 899 0 R >>
+1389 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R /F39 1151 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1110 0 obj <<
-/Length 3204
-/Filter /FlateDecode
->>
-stream
-xÚ¥Ùrã6òÝ_¡·•«" ;OžO29&Y²[©$´[ÌH¤BRöx·öß·/ð©8U[®2€Ðh4ú¦ôBÁŸ^¤6P&‹IVi»Øì/Ôâ澺вfå­Æ«^¯/¾|g’Edq/Öw#\i ÒT/ÖÅ/Ë7__ý¸¾¾¹\…V-£àrecµ¼zûÏK­õòêÛë·<õöÃGî¼»¾ºL¢åú§›k„¨ ÖEA,;×ß^ÿ|ùÛú›‹ëuOßøZ$î‹_~S‹®òÍ…
-L–ÚÅ# T ³,\ì/"kã!»‹ÿèŽfiëO¬I›†É SB½Ð:Ȭ '\±Y›ÐW`G`/WZ)¸ÒÇ÷_ñÕ¿uOÜy·®àîÕfãÚ–ûoêªkêÞN G¬W‹UY¤#Bÿúýdkª—ùnW?âö4\¾ÿQ`EÑ\êt x]+ ªàN“W÷NÖw5Ãn·íÁmÊ_•
-‰6XPV<qõæ;²+ëJ f¦Wè5‘”MR é%*W¼®0¬ Ó It&Ëîf0%A’F2ÿÇÑ5OsX²À$¡?ì÷,ð‰LwÀ‚öÎ53xàÉCE‚gYÛl±êE
-WÕ+f9£ƒ$Ó‰g [‡O^â·uÛéþƒyùÖIxDÜvUñ.÷9ßvŽõ·y5s|Šªœ$y¿Êä´8 Ré9®óþæнug Ñä¶:2A¨t
-z™išdÏÏ]Å üÿá†ø€ ò꿯Î(ü±ÞÞ+<ô‹§*ß—ð©2C’
-lㄤg>³_õ!Ï°!!AÏç‘w]EJYÚÅ
-liEiï_cñ¯×MS7íËN“mN–zäýnYÝ3ŒŒ‹Ž½½H/øÐßÃÒœý&Œ6yÅ‹ÅËwO¿Ä­îÁ5ùŽ®áã4èa–.ßßñD~öÁÖò)-‹
-@H‡U]‘O%ë9òFr‡¬úcÞ 4 [×
-ã/]²Ú㪊…â£gÞqlzÉ4±Ã}Ü&ž`xæ GKæ2!´(`:q76,-09–œðwƾ°Üa\2Ú=’XÚ!c}­«¸=VŸªú±â]è90?
-xLÙ’WOÜ!N'º/$»hÁ5/ÿ·vD 1kF Ñïk™µâø0VóA±; -?ü°F{{õÓúk‰ƒû5´ÓG ¨êÊ ¨bØF¡N!YJ¸b xÉ|„ãã_9 A1ºIƒ8ɸâ0Zž¤Æ6ò 6»Æˆöl¶yU¶{†ÞÕ ÃÞü?ÐËos÷®rè%)^Â%âзùÈÇ`ÌFBtœ¬Âd÷X3Jo•Æ¨l¢ŒâÓÇQûû›Lsƒ=<QKy¬ÉP6fòÿ(PJûôã ¯Œ
-´ê‹ "Í€‘üëݶ˜Yå… œA‡¸ ­ðŠx‚5¼!oIÛ/5Å,ȵ”q`M&0ÛÅÔ å-’±!’ʯ·X¥X Y™°Ãë¬#®Ú‡Þd«å[Hü€½¤\«¯Ýn·'mô—À%î3ÊĽó$Öh”øâ­'kx$€ûÔ±ì¸SË®üAÎÎ0O.GùóhC´”´+ßuÛúxÔ´Á%0¶åÁÜzhY)ÍÝ8MtŽ6°=ˆIà¶QŒo(þÁæßð0¬ÑäìÖ[7—ýBøe}x^U-VxÑ(Iá“$쎭7
-„Ð)í°v*>q¡ÐÖ %ÄçÜ ‡´'ö},ˆZf
-möùå«
-òO£½ƒ†œ’Ÿ€º(õ—è7“ò3áE€4qw”„Á k¢MÇ'ž*?ÈõMIÕA0
-hòZŽ.Œ¤÷†Ó{lˆ¦,\®Æ!/U†ôneµf…ÍP¿eÀ,B4ƒžÀDTøÃÙ²“X¶á²!!àXLûp5Á„¶ËÑò1y³ÁȤqV 4ô…Ϭ´Jå;ä
-ê!ä”o8‹µlª¦ÄË«»Ž¬˜Â4’ ô¼û‚+(·ìÄ`ã!o ¬)9¹X\Ê
-ç\%î eÅ%,ŒùèƒH–¹ O+@C›}é]tLôǽ¾¾Â„Ì +Ýç|#ÑÆÔðöHvëã
-0ÿþ†Mhb&C¼_—#ügWœBëÆJ·“gçP»× %àû¹Ÿ9—ò·ùÞIÈ«Šìºùv!ú/'í+ï—ˇrçúˆ£|HpÒõŸpTeÿUfø˜ìËøýÉ'šÙj (½áj$Xý)óq¢av¨C©´šh\x¡ê/†Û/‘*/,’\ÆHÙ Cž/èî¸eêM$Ô’"Q[ EðtéÒW#ûÓ€eî‰ÈG¾:áS_ßµ¾JCLëø®sûÃIο«Yºø›dñ¥_t›y
-®!μ Óå»áѧÏ=ÄÚ%¤ˆ«I9xýæGÙÓÉ'®};­Wôc€–ÀG|'Ÿ]מÖáKaW×;|–‡ƒ´!.–zÙi êÃK!bþŽ'îð™4Ê$A˜j³UíÙ¼àh”ísŽàÜJŒ ðW 3Ÿ²Tÿ êÿþ±Éðëš( Lšžù&Ùc†Yâ‰BÂuvJyÿ«”ç¤ÿWuJpendstream
+1400 0 obj <<
+/Length 2935
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Z[sÛÆ~ׯà[©ÙnÍ“l˱’ÚI%º34‰ˆI@!@Ëj§ÿ½ç¶à‚„¬Étø°÷³g¿sö\Ô3?=ËâHÙÜÍÒÜE±Òñlµ=S³{ûáLËœ…Ÿ´g½^ž}÷Φ³<Ê“Ì–w­,RY¦gËò×ù›÷¿,/¯Ï&Vs/âDÍ/Þþã\k=¿øøæò-½ýxÕw—ç©›/?]_bÊaž‹Y¹üéòŸç¿-<»\ü…gÐÊ"sœýú›š•p”ÏTdó,ž=BCE:ÏÍl{æbÅÎZß³9»9ûû@0¥¥S˜Ä6‹â̤ =Ó:ÊãØŒP‰ó(±Æ*°"rç ­”š_5]¿Û¯úº¹gúuÅ•›j÷¥ÚIgË姮:šõSõ„ˆÀ¾&†šÁ`ät–Ò†7u³‚ùVeóÏÕSǵbw®³9uçón-Í’o«þ±ªnô-WÖm×Ëê¶Ù<‘_AÛXf:aëÛ}×3ý[íÛìð¸öäŸa©o=+\=pY<_Âfph<æ€5ó®ÝlÚÇɺã²(K<VˆcϾ{çt€šÖ„”€ä‰\SlaÇUÛÜM œ˜È$I,Sÿ¥”ÙˆDîÚÏ·y0ßêȦ:—ù¤ž jt§™ŸõJÎqw$ó«_†ƒ1`œ´½›Ø9Ë£Ôš,ØÙLíì"•äþ<: 7$2‘ýëZ ët”Äq5 [àR/ÿD–së?$3/°‘äXxЂ˜¸çûÿ~OëGØÐðàé-`Îršóa¿éëSšË–&--ž¸ëV†ÕªéQ p·ûž‡Hí©ÆÒ€å(û]'㔢¬6O@YkÙ¨¬™0Üö/²UÙV²¢i{ž
+×uýE#ÛuÕŠ÷ñ”Ì»v|ˆºgÉñ¡ r+JCQi¸xlw›rÁ$‹²¸õÚËš ¤³ÈÄ)[‘«)íÊ#g3û’Z»È:èQ¢!MI‡N‰”
+n2³ì«N¢Û<ZÜBÉÄ4Úã±Þl¸v+Ã]}ß• Ñ~-;¬eA÷P­jÄæZ¥™ŠOÔ˜lb4”wblò2RÁ56A,ÕW`@DË:9êCÛtU76pÃqPøäG3¼^„3åà¡­éÀrmt¸ÙÂLs«½Š$Äð_—®ÞÖ›b'¾è«-Ü%n²O KUq\7î
+ï~¿+úºm¸s0ÚT~bc ÇÎrû}}„4wN;ˆ$Fcª_6ÓàÕý6$KÂû¾©^â8ëåøæL©ÄÄÅVplÿÔ±EïÇ!p~Â*°Ø6€+uCK´¼¹úáÎPåuÑy­¼X­÷Œã®Ý¼ò¼¾úˆ±e¦ç$Þûr!°«)¹²+Fæ3ÀZTUÌ
+oþÆ•²Âá¦F5"HÙãà=`'З ž§]ˆp¥‡Àán‚R
+–ÈÉ8Èx÷4E%‡ðc~Ÿ ÒH½ZÝ]µ› q¯Ñ¹û…‹pŒaAè—ö%˜)Š¶§Þ,ÞO6=°6r¡zØØz›ÄóuAÃèkÕ×ü É &@¡—àæ.Q>蔀†»–ˆ;Š5¹ï¶%¯ K>“–Bßc»ß”~G++ðäU9‰ŒŽÒ\§§>ƒT{òLêwèŒ/ïŠíƒwÞí÷Ûg˜Ï¤éHßB©‡·™rz
+u?ðÉÉ“L†‡ÚÙÈ(ÃÃѾaÄG8|3ô{.ºc¢xzá¡^>A_¯¸Á»{Ê=˜oj$¼›
+ºOlècÑzÐÛ§Q”5—r ‰°ŒqSö G{0\­´!Ƭ3ö’Ü2\äÄ%cm¹©ªã¼Y+Ì•‹áJÛH¥Î`˃»ûW®ƒ”w˜¿pÊrvJ—X‰ãÈ À¬¹–’,Ê3ðBá'¹÷0ë%FR¹1‚Î7”PYw«}× ¼µÇr߶>)•ðØV_k —OE¨c°ÕÆx[Íê¶xh7õj*IOÐäZ!‡0iÚ‰ZÈ¥RK·éȉ&âD/w»v×½ìÙ éTâ®+çÌÐGÇ׉7ŠÐ3h7Ôƒ°Z«¢áÉâJ!½ârŠ¸´‚L°Øp£Úñv;´Ú&Ï0 âÙ}„ZÇ»H|=tu+›¶YL¥Br¦ûqxYÀ¦¤¨©£ ÛäDúßý|ýáòúš‚²l)µ€öÀ¿rÐ%á¹ã¥¤hûEhwüö‚£¬SŽˆp•=ø+È(9"‘uÏb“Y?)ÛTÆ›AÏ}Y„¬‰ ›$ å.À8:FÆ­:0{Æã€ñ!7ÈC I
+¨zÝ“ 5aÔퟖˆXëi5eÀ¡8â‰sNä2c.WyÎÄÜÄ|”Î&>]XCÙ%¬-Ö¤¡¶àÀð u¼Âà#Xh,­†±Žæ5\î›ÏMûØð*ŸRáš“lûÃÄŽ—±–ÁÊ’m&ã<ÎZ-$¡"dz*ˆ°Pkn®Ú²âi]Õ ‰–Ë×oñù•S@ê!¡,x…ßB„æ€ Ô´ŠWë
+»¾›m1½U*ÿVy‚3,œU*ÏŽÉgêÆhC!"dž®
+öÒ÷rÜò0F ;Ráû“Œ43€-Ȩ£ìæäÃÇ€q–ï"¥´O2žÁ
+Ò*­†'Qg Höî‰kÌŸ­òZ–ç’ìäò¥`E˜ C;^PttÝÏ5-[k`N.0§Å`¸ã%’—!‘¦
+7[døÙ/ÏŽl©\˜G¨Ð½7Þf«ù[Hï4?ÝW‹÷Õf³¥ëèSª¯¨÷•g±¥§Q:xçÙ: ú}‚XÒäfàªâ‹ì]pÇ4 8A„òípc´Œ®W±é×íþ¹³h„k
+ò-?ÎCño _iòvËõT‚du¹|Hyž¿ª1¾ð¤ Ká$î´ô‘…»‚H½R”hcð|æB±­=„” Wào8¦Í9}‚Aìie:l5œÑJ"eò£Ðú™›g 1O•Ñ/žÝ©tôÎç'ù‘‘ÉŽŒLîo*ÔØ»ù¤eø{”Ljeñðflðe]åÉø
+Ÿˆ_–œœž/Ëâ÷âñÌCysI/6ÝÑW‰}wüɶ¬6Uï?J„@>Žù콟㿇­ ™+Šü¥n÷ì UôÜ¿ ,$ÐÖN½G¨!Mÿ¿ÿypø«…K#›eÏ<lÀýŠ2“§ž)„Òèc·¿(œ²þ?G°±endstream
endobj
-1109 0 obj <<
+1399 0 obj <<
/Type /Page
-/Contents 1110 0 R
-/Resources 1108 0 R
+/Contents 1400 0 R
+/Resources 1398 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1117 0 R
-/Annots [ 1113 0 R ]
+/Parent 1383 0 R
+/Annots [ 1404 0 R ]
>> endobj
-1113 0 obj <<
+1404 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [418.3461 611.3335 487.0181 623.3932]
+/Rect [101.3082 379.428 169.9802 391.3282]
/Subtype /Link
/A << /S /GoTo /D (dynamic_update_policies) >>
>> endobj
-1111 0 obj <<
-/D [1109 0 R /XYZ 85.0394 794.5015 null]
+1401 0 obj <<
+/D [1399 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+182 0 obj <<
+/D [1399 0 R /XYZ 85.0394 769.5949 null]
+>> endobj
+1402 0 obj <<
+/D [1399 0 R /XYZ 85.0394 749.2913 null]
>> endobj
186 0 obj <<
-/D [1109 0 R /XYZ 85.0394 769.5949 null]
+/D [1399 0 R /XYZ 85.0394 546.785 null]
>> endobj
-1112 0 obj <<
-/D [1109 0 R /XYZ 85.0394 749.4437 null]
+1403 0 obj <<
+/D [1399 0 R /XYZ 85.0394 519.0032 null]
>> endobj
190 0 obj <<
-/D [1109 0 R /XYZ 85.0394 597.4103 null]
+/D [1399 0 R /XYZ 85.0394 364.477 null]
>> endobj
-1114 0 obj <<
-/D [1109 0 R /XYZ 85.0394 573.0707 null]
+1405 0 obj <<
+/D [1399 0 R /XYZ 85.0394 339.5007 null]
>> endobj
194 0 obj <<
-/D [1109 0 R /XYZ 85.0394 410.9267 null]
+/D [1399 0 R /XYZ 85.0394 175.6792 null]
>> endobj
-1115 0 obj <<
-/D [1109 0 R /XYZ 85.0394 378.8211 null]
->> endobj
-198 0 obj <<
-/D [1109 0 R /XYZ 85.0394 204.765 null]
->> endobj
-1116 0 obj <<
-/D [1109 0 R /XYZ 85.0394 171.4256 null]
+1406 0 obj <<
+/D [1399 0 R /XYZ 85.0394 143.0963 null]
>> endobj
-1108 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F14 740 0 R /F41 939 0 R >>
+1398 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F39 1151 0 R /F14 956 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1121 0 obj <<
-/Length 3252
+1409 0 obj <<
+/Length 3227
/Filter /FlateDecode
>>
stream
-xÚ­M—ã¶í>¿Â‡¾·ž×µBŠ¢H¥§ÉÎl²I»ig&=äã [ôX/¶äXòîN~}¤%[“M_û|‚$€ø -g~r¦ó$/ÒbfŠ,ÑBêÙjw%fOÐ÷õ•dšE Z ©¾z¼úâ­2³")ò4Ÿ=®sÙDX+gÕOó,±É5Ì æ·ïîÞ\/d¡µš¿ùææŸw÷׋T "’›Û_K)ç7ïßÜÝRŒ"àíÝ͵Éæ?Üß=\ÿòøíÕÝcäp¸ )²÷ÛÕO¿ˆY›ùöJ$ª°zö"‘E‘ÎvW™V‰Î”
-˜íÕÃտ℃^?tR*R$©ÊÓ ±¤r&³DeÐ9”‹.`R­ƒ\@BD¹À–``:§˜-Ò"‘R~Ä›Ãó¾oŸå~S¯@&E>/ýÆ5}½*ûºm×®ñ«Yp€¨›u{Ø (ꎾû¶ëêåÖQ«¿–óÍáZÚy{|Ú0nÃq²·:êþ™Z? -ˆqU WEž(e ì
- Ð>MMŠC’ã†6<æÂM¥…¬Ç“+IuÎÎ k*·]K¸%÷Áº»csŠd@–qÇU»ºc=” ´Ž:½É‰öå=ïä¿h¼Ì¦ÞVD†.G2/0mÓíê~Ê¡µâAÎ KÁà—ùñ¯|(UäN9,fà
-ËþÈ=¼gÀú¦n*ܦwòˆ~&4ÇZ5fŸ×¡žµß JjÇc¨U¹/9–+>x]»ýàxlqÂçô‡k;g¥ˆyíý
-™åÃPûÖ»,·>,(1ú\;Â{¿„ß(J$A Þû)ÀpÈLµä@Ÿ©›ã$t»:¬”Η“9ѦÀl¶Ûgj¯ÚÕGñŠ¦á‰üŒÖ{ÕMÙôïQ•¿"C=EMѵ5,”1]¹l?D V{ëæl˜à÷´—°¦!‡¼ú\XåÛg&V’óç¯]Ù@ï}?ÎóœÔ²i(cƒgŠË
-ÒíÜlPUÓÁ¹^À¾Ÿ\31cš!uåLòóÝøÀPúáwØÒ÷‰8>É•½çÂÚ$—fìCÑÛ@Z2LØ°Íòˆ=LŠ¾»ô£¡Fì÷*Eºvz<{6ˆ,^*½}¬}ºRŽJPPÁ
-£‡!tìF9ø™EIßȹG.é {cS{‹÷ЈËdÚÉD}]€(1B«ò”~ôAVÄzÃw¬òÅ|Ù—WÇ•«¾œžÌER@-ÆâønÌ×_…Е©Êt‚Ú˜È[Lž%‚ìQé €j/i ®´%¦c<­5ß´œ „=Éütí">Ê~°?
-«ðF­|¼§v°ôå? KjzóC /Ÿð2'AÅY²ùS?ГÐòì1xao?¤÷[öJ>Tevp56s™ÈtÚʧìǪ$·y:¸ÂLÍŒ<–n¸š¢…)Í2¡Þ¼&Œ$uX4òÜjžG_ôáàNׯ’áš¾>Ì KÈYz¥ËbØÊ,Gdx
-¾!'D ^6°zq_΃Åxrr%€Åéhù‚7‘Ö$& î,O‹D¤ú$a´ëGœv´4çL¸^Kß„ÅŽïþÖ$åzšö¶s\n!–Pv¯€Å\çeyɸÇ=f®M‡Zÿ…“æI&äÔæ&Âè£Gû!”þ*"Äb¿ £­ó 'ñ;”’) ºaÛA,—Õ†oÅù  ØóíÝ¡÷7|Ø‹¢Y!Zö甄¨ê5ŽZ»Aá:\‘}OJ­ÐÞ•<sacá
-°~\új“{ƒ- ¶e!÷e=]¹ä]lÅ‚_†„å”Uĸè/Š.·»ÀD5K³±õ¼Ÿ~oLñúK¨XB^N¶`Up8‹š’]š+ÿ0·›1:«÷÷ï¾~i"‘O^ïùÛÕ@ nOE¼]\b@7
-êÖ©ª‰5ê¬.xy©SÊÎ_|,ù:ú >ˆ·|qw‡¨›¨:i†á=Œ§ø“¨pAw~à—¡â­ªÐÑÿèo@ñ?áÒ–ØŸˆ&E>¬°±+llàqê¤Q˜`<(ٲ뎻8KmÅOçHè딂ÞCý;8\8tÕd0ÉÀ•ª|PC'Ÿ+»¡–Nt‘ŸbèÂ@ðGü ªˆ r¬çÊ­Ëã¶gu•áat‘ËRç·Nù–‹Ë<ÿýPB>‚N¥Áð–aôˆô¹›ÎqÖžL\ œeuçÑ„®Ú‰Ë
+xÚ¥]sܶñ]¿Bo¡&>ŒŸ[NœLÝÔRÛi>x$¤ã„GÒGžeå×w»À‘'ÚéLG3°X
+Y\æEk‘èËj!.`îû‹„q6i3Çúîîâ›7*¿,â"“ÙåÝýl/ c’Ë»ú×(óø
+vÑíÛïZø—\m¤ÈU½úáúç»›÷0ÔP ñúõ¿®’$‰®ß½ºyMS¯ßÝRçÍÍõUžFwÿ|s{õûÝ7wÎ9/‰PH䇋_—5°ôã…ˆUaôå# Dœ…¼Ü_¤ZÅ:UÊCÚ‹Û‹„ g³néªlK•ÉáH¹&]Ä™’Ê çng‘ @Mf¨vÔ:‡ýÎO7ÿa¤ù~JĹЊ‘†ÃUb¢¾²ãxµQºˆßvÍÔ”“­i¸}‚D\Ò°jÛMÔïÔŽöðÑ–製J¢®nº‡Åò±yè`çò,.„ÈþRFúp´‡'ÚͤéªöÈ'¨ìžp‡K˜Xgùå&IâBkéÖ– `8 ³°$É#8t$[ÃÑÔS[RãH*d´)K·”1÷`bhŒ`„¨¢ùŒëÓŠqè;Ëh_
+îšöttº(
+vDw’§Eá£ÐÕ&â,
+=pÖ˜ç áwoß½F‚²¨ Æ\¶­#ïô
+¶<wÁ†]0ûÈ/8_ºð¯OÃÔÃvME ÉÌõ4­3Ò`¡¹F(²E~A€‘Ú¡ÇfÛZMàˆväš(5AØŽ'Ãf·¶:šé‰F(f"\sùpl|ÊN n¶AÖ‹B@A‘{ ú0²ÒöKm–NÏ~šl7'£»ü8'¼Öì3¤ó™Øº˜ •ŠR¡£2L",e_m¹˜Ôà·•€ªŠr<Øb5‹0j;V‡fë,†ìBÀµó•8a†Ý!¤(gÅQø(ynªö×îÏ[ ep>ëòp¡)"xt9
+!šs
+9ÅZ˜oàwu¾€ˆZb¹óŒA.ÁÑ9'úè‚â6GlxÉ,föñùrûih¡0¡­²°Õ¾Ÿ#Az^6LØÖŸXU9N k v§¿bÄVgÖYqJ¹ÓEN›Æ2-|M³Ù­\'p<ºH}FÛlŒ™ÆàO…HFñšû£ ?ÐkÔ’ÌRrˆ^ ŒC­YŒÒ:z×»8“iïx3>³“e9 é»$™ÇÆ‹O‹03±¼ÞâÖŽt÷¡¦5©:KõqKCf$Y•Òp‚ €ÇþðÈ
+Þƒv‹è—•ýXªÐãgÛ9üø½.ôV©\çæòK¡7= Ü£áÌ(3"”S¿üýÝÍúƒ·’…w†/h;
+ü&„!èmù¤ãÈñÂøÀbÔYA‰ñN@ÞÊ+9ô»ßÛ®¶|
+/\øŽó8«úÁjÜ(,ÿñÃ=½•8 «þXÒЙv¦òsð \}6 óiÁ@È»Ÿ¾û¥ü%Èã;VÅ —A.T¥föµ4ó$N井¯™QqfÂWCd
+<Å^Ÿ"ßX=³°ŸDáS¢“+(}€¦þº7ILç©ð¯¿`yZÐ÷+/a´~¨EJG:š3&<¯§væa´üP„ÁNr9M|zvÜÎî!}Ì3-%Üeàñ³3×>e~æfC‚™Šd¹Õt0øè?ü¶ÏŸ,|(þ̯;”Žñ'+¿Å!}þ¿ùqúÉKšÇʹþ£™›85° å>µÉg”ûŸˆ<'ý¿w€=endstream
endobj
-1120 0 obj <<
+1408 0 obj <<
/Type /Page
-/Contents 1121 0 R
-/Resources 1119 0 R
+/Contents 1409 0 R
+/Resources 1407 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1117 0 R
+/Parent 1383 0 R
>> endobj
-1122 0 obj <<
-/D [1120 0 R /XYZ 56.6929 794.5015 null]
+1410 0 obj <<
+/D [1408 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+198 0 obj <<
+/D [1408 0 R /XYZ 56.6929 678.9507 null]
+>> endobj
+1411 0 obj <<
+/D [1408 0 R /XYZ 56.6929 644.5195 null]
>> endobj
202 0 obj <<
-/D [1120 0 R /XYZ 56.6929 769.5949 null]
+/D [1408 0 R /XYZ 56.6929 514.5361 null]
>> endobj
-1123 0 obj <<
-/D [1120 0 R /XYZ 56.6929 748.4014 null]
+1412 0 obj <<
+/D [1408 0 R /XYZ 56.6929 481.3387 null]
>> endobj
206 0 obj <<
-/D [1120 0 R /XYZ 56.6929 549.4516 null]
+/D [1408 0 R /XYZ 56.6929 279.5586 null]
>> endobj
-1124 0 obj <<
-/D [1120 0 R /XYZ 56.6929 521.7105 null]
+1413 0 obj <<
+/D [1408 0 R /XYZ 56.6929 251.1623 null]
+>> endobj
+1407 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F39 1151 0 R /F41 1208 0 R /F48 1228 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1416 0 obj <<
+/Length 3255
+/Filter /FlateDecode
+>>
+stream
+xÚ¥]sã¶ñݿ“éLèö„
+)·‡ù±éòR–UOÏC_4ZznÊ9=øúi°Ï«ŽFk¶›¬[uO{‡c›ÛÅ#=K^ØðQËCU»S·åñdð):ÍÇ1bÌOR†uÙƒÎk%ƒCO¦qèóMIÊA}µ«ê¼£ h†Àñ4Öá?Aíf8™$@h<­L%èp
+¤ž‹o¡3ì˺ZÑ÷8RA¿mxq„.yeÕô ¤eáÞ…¸vp¨~kxû“Û°ªEÕlŽ»ì ¢ñ…ÁÄ„–±vW`^ŸÜ3LEb€ïrÌp:åÐã 県p˜Þò‡¯ÿúíû›Ü‹HJaR™Mí ÀÈw`i½ðØýüCÇ°M‘‡@Ÿ‚”RwÕ¦±·¶RÞ²üyu~:à c¡•Ñ/™JR3UŠŽùmiš‚ÜgÍk¤Œl^¤‰¬ž›†F9==+•I„Ž„‰N½mžfD†PB§”¨b`¶çD‚CÎbcÎd*ø¦ŽŒ³ß·MQ_´J3Vá 88ûÕÀóþ°Dby¿WfÉÊ °=c‰‚¥F‰b‹€)VcI@oŽÐǪ®iÄ.ȘÓàEê…ÑÔ)|äÀwªÈZŒyté73è@2í|#bÑs¼ Eš)^„¾ëè Ä0‡èööîÃWÏ!’ΰˆEÀ}ë!QOŒ Ö-:,Ãfä×bM΋KdŽ
+•±,PMt|˜;a¡Y
+Žzâ4ž?*’j|dlvÇ#ßx§Á†øžó¬Û[0"ÞH¬û–±5à»cU|dXžü’×çEᦠüòº~²Û>“?NLÔÔuûH^^!­ØÙ`Š/hN= )f˜Ô)r6ïûÃÎï¬~ö´°jè=§‡0xPX³Ñ$‚
+ü¸ÕsXGëCîµø¿ÊÞf
+>é|Ê™ ½Ÿjµ†œÏIÞºFxçOF»Ž ';0ÞíÀ#¬¨–¤MûF‡=£m ¥|y¨rÜ~yMƒX*5%‚ nEtŸ|Yƒ*¼fU¾Ä•WÛ» ýß>ýl ãÔù„O{mŸ;JÈûUW-nTܼڵÓEC^±šÕÀ¼nºxðù~Ñ®;Û…§ˆ%"îuâÛ¦®~ædö݇øѼtÆù´ƒèÀÐDÑ–œ‘“k„çjýÄéð¤%F0Jž!L·yÁh{Nø¹‰“lA˜é·œÙƒˆ+ˆiÕ¯rV˜-Z!3ŸVŸoÀŽZÀ§ls-]Ÿ¸˜æû>Ó¯µôafM“QU˜à÷ÓžFPCB¡Qõ[ê9keÛ*!8å+<íÑFè}¼ýœ
+=º§u|ü¤ 3ìt¹§v½g¸”Óþ=!ãö"È‘ÞæK<‹Ã—xöôÃÐS_hŒ•HÙäMõóÅN·ô\–s7ôîSmìÃÄ»êDºvZl\Û8Ájô:笉oùìP ³2ñ
+dlVÕïóU9†ãÂ3ê
+¢èêuÏ$º¾Zrôô“‹‘ÛÚ–GÁbB„½žþ0séÄaeø¨(üTŽ=þ(W>€²Úí”hKæ½ý·VvU_º… /Ú21NÅÝP¶fèi²‘æŶ‹U O~šœXŠ0;탆þ[Œ˜É±•%…ŠŽÁ8zjÛtÿ¯=&JEÊ“¨ò…ÂFXŠiºH#M¬?Ú '›ÑÄ­-ºí7üdžض³ôÌvÆ;‚á{¨©<- >Ÿ⪩†*¯öÂ8¥ž<>{÷ñ‡è±û×ßTs½þúO×ß²ûîû§vírHû››õ7zUß.¿Êïïžû‘Žþ÷gæO?Ò· ÿï¿ÿUBÐYÎÿ{Hc54©#
+™êSÊý‘ÎIÿݳÊZendstream
+endobj
+1415 0 obj <<
+/Type /Page
+/Contents 1416 0 R
+/Resources 1414 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1383 0 R
+>> endobj
+1417 0 obj <<
+/D [1415 0 R /XYZ 85.0394 794.5015 null]
>> endobj
210 0 obj <<
-/D [1120 0 R /XYZ 56.6929 231.5025 null]
+/D [1415 0 R /XYZ 85.0394 671.4386 null]
>> endobj
-1125 0 obj <<
-/D [1120 0 R /XYZ 56.6929 201.1114 null]
+1418 0 obj <<
+/D [1415 0 R /XYZ 85.0394 641.1061 null]
>> endobj
-1119 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F39 899 0 R /F41 939 0 R /F48 953 0 R >>
+214 0 obj <<
+/D [1415 0 R /XYZ 85.0394 444.8166 null]
+>> endobj
+1419 0 obj <<
+/D [1415 0 R /XYZ 85.0394 417.1342 null]
+>> endobj
+1414 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1128 0 obj <<
-/Length 3056
+1422 0 obj <<
+/Length 1913
/Filter /FlateDecode
>>
stream
-xÚµYI“«8¾×¯¨è˸¦º0’X£cÞž÷¯Ý}À€›Å¼NÌ-@Ùõ˜yýbbÂD*•ÊåËT
-ƒWÿÀ«"r<R…WY8‘â«á¿ð¯6žk¾€”ç#cúxäªj/åoH~U9U‚Ò«¶}¥p¼¢€WÍü½TkUFZcòöE¾$po¢Ä—*õù
-PEáuJº³Mµ·?µÎKCË5|´ðˆ¨w|ùýOþÕÄÆt^x©ŠøzÁ/<T¾ú/‚ˆ8Q@(£x/Ó—q.ða–.-òŠˆNT \àŠÜ"ªœ„ ¢n1ƒ8¶ŒØµƒ{XÄ ¼ >,“eNUïEø/®çaÿ(rI÷âÑPJ¡y2¬tŠ=öÖ-¶’”˜d ”Ì8§ýÁóгâ'¹7 tÏ»= 3½ó—…8%ͱâl_ªˆÅ6:Å–IÌÁnI-ø
-ˆ$?2&‹&O3Æ[ƒlc=ažDªÌ!QQŸ]ùévœ6Ô}d€auzœÀ~Œnlx]âTÊ~YF¼Ì¥º‚×|›-Vò‰âe–Ï$ÎKžçKµ0 °Oq3µ¢³ùËØnˆ}Läho*,% Â*êÏÊ7ˆ âp1©£ÝgÐú"! ¤\I*ô!P„
-8¨Bðý.áä…bÆMŠc‘HNP}–˜êKhTrŠ,dÅ%<|°´ð ‚ñ­|©X)nO,܃nÒ2‡i$ð„BR
-ê¹(q²$¡GPsXÏm‘p•“å\®@Ù¨âÆB’¤çìú±Ò2òŠT{ìà’¸gÈ–ÑØÇÆ“IÌ[rœ.RèS=`èèI&=Á)/VºØÏ–¤L$NQœ0>Ï öŒL@õÄgD·CÚ‘~p\ƒÁ>3ç õ†£“µPÔòÌpD„JÚa:õy.qgÁ{>AEù‹ØÀIêC Àš#,üûƒŸ’©/ÙM^?ÏübZ–ŸéF‹~ZW—B^M3‰Zà“ˆúòø ƒÂ—S>¯×¹±xœº€&uËC±ð= Ym5¿œ
-÷¸än0’‹:
-q;œ°òØ*ƒ½fõIJ¨fûãËœÖ4A)¥íÙ‰è•óîG}ê~ˆ§$¦W¦'©L[Ü{æ!RƒC6»±ŠNß¼(n©Ìv)/(x”Þ4EûƒÂN"}"Ƹž2¤†â3sâË[’Òh—r0©ô쌺a=Ò ã÷ÚKz 3Ý‹S³+§ôY
-‚HÚC²†vG¹ŧ'zz¹úzYÇ`?na}ös$„D¤ëû'Ú ,ÕÍýôÖá»±•1)““*“=[ñ7&âF¦pÊL/xnr˧iErøúýåðx¼Kg·¼˜+èrÈí ¿ ¸3ù®lHø®÷Oº ãö˜ÇWzˆ°Ÿx2—é”H®Ï¤¢r²€ØÄßéDº‡‰IH*&ÛµØá'Ò›*XžÊ} —3‹ENÄýÔ3¬á~a’¡(³zzüR¬„K´èƒ ¶í¼×–&Í—·•n9n4¶]dx“MS×.ÓÎ5jî¯E¸>ImytïœØÖ²ÌÉ<==\ÝPí«0«{³Òò–]³!ÜWíÃÄÑ«ÝàlÔàLõ×ÎÞœL0Ãr«bî–Òóû^p_¡" ßopyöÞbX©k£ûô¬Zº¿Sæ@µš»jOŸ'«ó¾ìâºrØ­lgû.m^ä÷ö¦~/ÊùþkA¥6Q€\ÿ&T«º<›”7V½u;ˆîB[.¦®´ôÃNoÓT§ÆÑ=™ïÖÞy9Aý"ËÞl6Ÿlö– Ú£ÎÔ5ý.ZßjžçËiw³³Ê‚8힌–\fâÎÚö“£$ÙÝÐïÞ %º*ÛÙÜ’Oªº¸k=ì£w­;×Õx ùocUž¾÷º3í06ŽPžÈ •ç¢3_§F»ÈêÁñbÜ…Ý긮ÃíØ´¯£®Õ¼_›TM×µn½þà¾l¢_~Ë¿[±ðþ4Èá#L ´)ähq$ƒð” ¢Ïj÷·8çºè‘É^²o‚¯©ä‹æO%”Ç$?{ÁºêþÛéÛ
-3DL3¤riT*úuÔ7&ðÊ·6ã¹°°ÖU)lÔ—ï?îKbwãh»hÖzeâœÆzÍÔp"/}¹Ñ¢•êníÆé(Ÿ×å{s=3ÍÁâöÞYßO1ïÍÉÅÞ5/Îl
-DQim„Nw¶Ùc¨}åpYz;¾á.QXÿ6÷w­¡ vo_2fÝÙ¶ì×äÖy{YµÊU ÂfP+B†¹A·s
-S—|K¢_ü6ŸGïnÏijÁ y@­p1îÍÚ÷nÔ™¯ÑݶohqhÒ~J_ð$¾¯Ž›äl8¾=®)µ{7ÜõË ¹R¿Y¶ôԧ͊]}hNù¢0߆m©jâËûjmÞ½U_owš[¡/˜·°Ûvîæú6†›Õ8ÚÝÆEJ½*ïÕd}ÄýÛªÛj­¬É™í<ºîÚã¥oía§y|?ã°ÉK…Öâ\íUÇQ£Z{ø In_{£&</µzyô–ïu¤¡Y¯È¹ÕYµ:Ne]{¢:?念xÝiYõÚì¶XEçÑÚŠ×õöäìÔëEû‹pÚ=oËÒ:3_j8ûû- àt JãÉ^ٕݶânrØFó_¿e’Y2 ô“]úU.o…Šþ~BÍýYÄçùò?ÿ5õùonÆ¢ÀÏžZTò7¾dJÑ$_5ÏÿÃú^õ<šv0endstream
+xÚ­W[“ªH~ï_aÌËê:B](.qbPlñ.
+^˜AQQؘÿ>¥h»³—8Ñ•·/³2³²` Ð?X"<ÃKH* Ç
+5kó}p‡Ö¡š¤ølV…×Âh,:ž7Úëp[·Úq¯½Q %s½†ÂŽÃÞ¼ª`=Aí,ÔŽ'›
+)ì Dš&›ÉèhvTGiél'#Ó9šEÌJ{œxŠBФ›,=ÇÑ;ÆŽozÛÂ>˜ž4H¼6ÞŠÖo‹þòYbc"ò¥ß~½Úò‹ö·«åßÝj¹4Ã0…÷lx<:«šZËàQp©süV„øÁšXoßï³/ìµB»9ê¢Qò½¼8þ¿šE!b$‰pų(*P¥@­+—T×cù”ø¬êû$/
+ 8îcbE裋ё•G”
+iÇ!€D.÷upsõÎ)1„§#.e¤#0l)ð;ÇÆ –uú•›_Cu T„b ¹3¥mj€“$œ3½¬ï®~Á}ƒmïPI‰¨C¥ŸžŠk¯šïNñèe §ÊEíC‘†FÌG§Ám>©!A*GëÛ¯X>ym²sûw›ªn¤À¿Y9ÕŸìþ1ßq*”óÙ$'YñCSRA¤|Ë+Úƒ1GÊí0ßß[ôFà@ùä¯Î]ÓGί_@ÄQtÊ·^à<<P…”£ õ_Œ~9Ž—$Jbé%~.«nùK$ž¦Õ÷çÒÏåüK¢òôò#Òk¢þøâäéý„€tw|æ9·ø"ñãÁy[¿Öõíû=ú›·;ÿ°Âû‚žL\"m>NTà=àts…ÿ
endobj
-1127 0 obj <<
+1421 0 obj <<
/Type /Page
-/Contents 1128 0 R
-/Resources 1126 0 R
+/Contents 1422 0 R
+/Resources 1420 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1117 0 R
+/Parent 1424 0 R
>> endobj
-1129 0 obj <<
-/D [1127 0 R /XYZ 85.0394 794.5015 null]
+1423 0 obj <<
+/D [1421 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-214 0 obj <<
-/D [1127 0 R /XYZ 85.0394 717.5894 null]
+1420 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F62 1352 0 R >>
+/XObject << /Im2 1341 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-1130 0 obj <<
-/D [1127 0 R /XYZ 85.0394 690.1986 null]
+1427 0 obj <<
+/Length 2465
+/Filter /FlateDecode
+>>
+stream
+xÚ¥kÛ6òûþ
+¡Àò¡VDQÔ£p7›t›ë¦Íº=¤M?heÚÖU–\KÞ­s¸ÿÞÎP¢¥w@°Àj8g†ó"-¼þ„—© ”yì¥y¨P(¯Ü]…Þæ^] ¦™[¢¹KõõòêÙK™zy'Qâ-ׯ,³LxËÕ/þõ7‹ï—7ogóH…~Ìæ* ýÅ‹ŸfBqw}ó‚¦^ÜÝðòf1KcùãÛ›û™LR«r^D÷7×_òŠww‹ïn¯iðó›»›{žXÜ1ÏÅË™Èü7ßGK{ûêîöîÕì×å·W7ËAM×"”¨ãïW¿üz+°È·Wa óLyO0‘ç‘·»Š• T,¥ÅÔW÷W? Y³tÊ´JfÊ¢t¶Q4e[•‰Œ¤±mWm½b­;]¨®¦ñ‡¶ÑO۪ܸ.ªš ¾¥ïcQW«¢×̦hV¼¨ª™’¸öÇCÃöƒãTÊÿé%ZuqûÏs~ý–(ëJ7}€f]ç" D–§Fð·ºÛ·MgäËbWœ`é2EÜ
+„YT»ã•ôAžçST¬Ç”ekÖ²}_¨zöÀQVë­ÛöX³§m‹Gv™­›Ko>§
+–Ë¢t&BÿØ™Qâ—mó> #”§ ÅSÕoiÖh‰(âd‘³¦GQ‘à G($NUM+«¶)êúDóµ^3ƒc3Ÿ
+JÒJ¥”‰‹j«!á( ê÷0‹BÿD0Í«õ‰³"ÔÚǪ ŠÁ¸JÙê Üó³swPšŸá?Ic8Ïö°êP«/'³&Mš±W
+ë‹ï£(¶Å×DXbO?´¦u±þ
+^!õ™l¹a°iY+×j£6χؙlN(…)¬^U%„+f˜0£Äh[‰F“ãmƒ{C6‰eä¿Uø=ª
+>!­W"Êš°‰=æ:à>Ø Mgs&Š„6gIiÌÀ˜ØÚCèÛ‹bŠCÇäŽþSnDh*.«jœ§Ðt'Òs+úgv Ø‘¨<ɽùx;ø¼.æ¼ñP"kt$<2N"÷.'9ô‚, —,8Þ0¼¼dšbW•|ÉÂ+Åå=aqì[ha-Í=T ìÇ6ƦD8Ú6T EÑ¢£B…a åàF€7
+BB'TÅÄû÷‡ZÓ¬ñ@À–Û¢Ù0® ÔÊʃTcavlr ׳¶ØåhkÂFSœ|(ÊßµZ„wÒôŸòÛ©Ëߊ
+îpc4ô ú@0–O‚Z#yé+`À¦n/ ÛK膓<·‡>Î붫Q?ôæÜ?aw>¦§ggÜôù©@ŠŒÊæ5¸JIMUdõ„sòò³¬¸Ä“}
+cT‘öí/.v“;8¢[#‰'¤Ñum:ùÄ_4SÞ5ö¦É¸|~ààu“®˜;¹Þ­/½jª¾*˜Mǽ!-¢¡ÔÝ_¶4éÐÐD¶?u[Òág
+&‚©~þïfirÜØ Y-ÜdÅ*òkHè´æSÙd2(þFq×t,ì„›ýƒHú¾&@¿O=€‚yð×…‰ŸÂÁŸý#Æx«
+endobj
+1426 0 obj <<
+/Type /Page
+/Contents 1427 0 R
+/Resources 1425 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1424 0 R
>> endobj
-1126 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+1428 0 obj <<
+/D [1426 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+218 0 obj <<
+/D [1426 0 R /XYZ 85.0394 486.5796 null]
+>> endobj
+1432 0 obj <<
+/D [1426 0 R /XYZ 85.0394 454.3582 null]
+>> endobj
+222 0 obj <<
+/D [1426 0 R /XYZ 85.0394 412.0822 null]
+>> endobj
+1433 0 obj <<
+/D [1426 0 R /XYZ 85.0394 381.7503 null]
+>> endobj
+226 0 obj <<
+/D [1426 0 R /XYZ 85.0394 150.1125 null]
+>> endobj
+1434 0 obj <<
+/D [1426 0 R /XYZ 85.0394 122.4306 null]
+>> endobj
+1425 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F62 1352 0 R /F65 1431 0 R /F21 930 0 R /F41 1208 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1133 0 obj <<
-/Length 2753
+1437 0 obj <<
+/Length 3008
/Filter /FlateDecode
>>
stream
-xÚµ]sÛ¸ñÝ¿BÔŒÅàƒÉÉ“/¶{¾i×ö¥—{ EÈbC‘
-IY§Ìô¿w LgÚÉ]2c,‹Å~cñƒÿ|«Pe"›%YƌdzåæŒÍžaîogÜÒ,ѧúéñìݵLfY˜)¡f+W²4å³Çâ·
-³pXps÷IÍ"fÁïwwïç2  qsKãO7·—eóçŠÉàÃÏwW÷„,«‹ËOsÎypqûáÊ.¸¼} àúêbžDÁã¯÷Wóß9»z4ñµåL¢_Ï~ûÍ
-Pú—3Ê,g{ø`!Ï21ÛœE± ãHJ‡©ÎÎþ90ôfÍÒIëq
-©Ä„ù"î™3˜åRÍ’8 •ÒØ/ CÔXAÂ,Ž…Au×éåB×ùS¥ç ÅXpÐÝûï¾äUYä}ÙÔ'ä‹( SÁ·ŠüöŸ÷oO%iÈWÿ“õ¸³,Ž¦­‚&À4bâm^´Ž/ ºǬÆUŒ‡±àÑ`d!fƒ9V3%B™€ðJAdJNF¾E] eÆ
-¼bÜÆR€ä†â#c¸*\Zx²D$0²0ÉW³¯3²(Ë$y°Ñu´A¼»ÙˆÙeÍ<¥ã…ÏÙ(¥„9o@ûKT`m£SSC`ˆ$ šŽiЯ-âË\°@ãŸCGSUÙõº Ù²väeG=—,ø#ßl+MSyk9½ÌE``AbÊ(njÂoóv¾ˆXЗË]0äåù‰mÓô„òıX©j 8
-h
-MoÓGD* Eš¥3?~,®0‚ãLA`)þcQª\
-sE½*·&3BGàŠúh­òS×صP˜õ¶×VíEÊÈCÝ:
-šŸh{ŒnÓ¯ºxp­'´•+;ö4‚ÂptÙI+‹7=&
-~å]·ÛØÖ5w”N%jhGÑ‘_Cã“[Cƒõé3*@‡÷SUö.°§êNÀßÇuuØÂ7ÏCѨ۶1úOFˣ㠟uá/±êä.? ¹ƒ×¤W°aMüÊ VhztÔG²e†Á³k÷}«Ú¼g1eª>,ÕE¹„\ÅòÂRªj€v§0Âhrœ£mpo(%4³ŸYÌîP臚–ˆÐO¸ˆž‚³bBº¨D”3.°&BôXèà÷yua¡Ðt[Q$´8kwÉiµ1°uNè› eSÇ^Þ
-ASþæåÈ?Í°Cø+oG(¦ˆùx> >ãQ(#%üë‘Pq˜%‘r¯Mà^ÆðµéŽ6í¶Û¦ímW¿~iûWôÀp•æ1(†\-1Æ «9ÌSAGÜ;šÈÍM
-'-@È£i7ñ09(+3@unj @&sQØN×.¢äz=3.™TMóe·í&_’núÓ[R^u¶ëÝu¶­éíæ.e®GÞä_,ù×nËñÎæZávžÂ‘_ÍuS»›Úé.Ë|K[¦ƒ>t½Þ]¿ŒäצT ‰¦ÜS[^Âê{N·Pë>Àg4XŸÁå·#DS'tÿ"-Ý… Ã¼e<¸¿þ@ÓКH‚
-½N–Üv€¶7giˆ»¬ìjr‡ó)ï—Ufï ‹®,4!º!¬áƒ®“
-¾É¼é`rNBV€®T·S˜šøŒlÞ:¤}­ ÅcÃYw‚õ´ç¸ç9ºUBó2>eؤia»•Ù3 ä§tGÚÁ÷…òŸ2¼ðœxœ ;–M,å–¡¡5My©¢äàdó
-óv›OÔh¡ë]‹fF:·ïÙÐæÀIŸd’9oE°×&²9`ì*‚¦*¼pN1³ý´~--8tÐqæI ÷ aÞ‡‹/I‹Y”$ÁG³©ÙÝ6íH<ꬄó @MXŸP»à‰–*ë¼=]•?éʸØ…',L’T‡)öD¶à«8øR7ûš@ªÊrí»¾…ÄÓ[rð9U…§]OX¯0ŤŒƒ\À_Q4»Ýg‘†ÞL
-m,MµÏöêÞû•p ^Œä¯8剺?ÀAVºVê"„¾õUçÏX•kdýêWÊæ»ûŸr2¿P¾õ¬ :’rr;6<þðO°ã…!JB™¦rZr¨ç(¹¤BÑ…x%»û±vBøÿS½Íendstream
+xÚÝ]sÛ8î=¿Â/7µg׊HêƒÜ»Û7M³Ù¶iš8mÚÝ}-&ÖU–œHNšüúR–l¥íL÷á榓ŠA
+ˆÆ> RÔÙyˆÙ°. rŸäŸíœ‘V@J
+»îZú–4×Æ<˜³…yvA„†¤àyižiD
+d…§°GûCÄIVú ¬¶a4ssijt
+Ã<©jØðD•'vE½Hj7ÒÄ ½f•%E–U„ û_$Yá5f£Œ=¾™!j>”k0`³ZA2Bu•×4DÚ‚æ³¢ª5ÂË+žP¬o‘‰å:OiÞx8“b³@œŽNÎ&ohn[ëm®PÃ=n˜YµEjãKÍ _ÂcŽ¤± 8 Ñ7æ +&ÂŒ jŽž‹äNo-x{Ji ²—yŸe5aTÚ0dŸ
+c驆¬#ò§ï‹äÚz¼p§]aéðPÙÖ(6'ÞV"ºJôÈ#;É¥76ýƒâYQY%>òê:·aþû›üÿDšbÿiêû¤ s"SÂwÖ}ø–ÆEF±Tþß•'×àkè.z… rAËaÜMrá5í ð&5¸•ÿIEy¯ï ¢‚[6Ûuvh…|ܤ,žYZÌî[öùƒy1ð|Îd;1
+? Äˆƒ„†Š¹¦±‰…𜭳<Ý'†—å›]ØMäún„Y°nè`J
+6«Vå­( 0Ò¶ÙÛbÍ Ö§ s”­\gÚ¥)¿|XÕ– Aé¤=W®0ËgeAð?ýЯ´EžéÏÑ®€²-K—.ñ-Õu’å¬b˜œXDU®p +‘«¾PŸ¥´ŠoØ-vz,ßbÕ›y]ñ§\üV~+{)*
+¶ÎMQ‰E˺.—Àïœ^mQn$ßu ÌZ$é4ÅT‡ÉXò¡.’™Q¨Ê0e顇+[z Ø–[îÊ¢¯ZÊ:"’§EUéy?pi $wÕl¹²ÊGâ%±Bg
+î)ÚË{[²66CÇkÌéz’V¿ôÉÈ¥Ìñ•£ûöî*âæÆ
+cKðˆ:qjíÐrÙ¦¥*°(¸¨3_±-ÿ…!”h‹ur¼Œ³¨ÇB(¦<!ˆäÔnóŸ{‡žôcÕ>óþDÁ ßZ¬¹) a×J“ÂçX¾³ØÆ(˜ø¬hf6ìÖåí!Qœ$¤Š@à7óÕù
+ês‹þ¯Š±ÒYŠã\"‚ËI×!Ñz¶ÁHè7îøk©˜î’
+¶\‡?í:$š¹‘–IjŒbw_óÃo‰'[â=!˜L Âï—
+ `WëbŽ?ɳºi¶€j  « Ú%.ËA¬IN‰É„f2ýϺª·6B½=«¬ska×¹Ü-#ÛåjE@LFø¬æ ®10v›;4ã戀Îfž M<úg–-¼%PP1$à}xÅòë\ëíVjÀ¸ÆÁ@ÀéI'1_Ú¹Ûë ÎZMP‡>nã›h7voSÝäª1° Õ²#±¸ÛaHJO©(êp´ÓŒm°¾ÅˆžˆTÔå$¡ûM_K™+‰N¦¾¡‡¦ÏÞÆßÝ~‡jK•®±ö¤"˜€TÇÀãÚ[ì(¢Áú' Š<… ¼ÃŠÉ)XØljo¬z²&–¦<õ kã
+—s]U„NŸû‚|- K
+›>RÛØ-N ƒÆAzKè‘ê«d״̆wI¾¶CÇj†"@ßõúz/(\Ä!ðþâ„w
+æáp`Û 1ž`>)˜“» ÇAéæñOl (‹GŠJ%ÁÃ0g#ºS.@ÐèÛ@Ëym>x跰˧¸é‘÷~‘Í6¶s›¯B]æÂv› ^Ìþ]=š زmzƒœ‡î\
endobj
-1132 0 obj <<
+1436 0 obj <<
/Type /Page
-/Contents 1133 0 R
-/Resources 1131 0 R
+/Contents 1437 0 R
+/Resources 1435 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1117 0 R
-/Annots [ 1139 0 R ]
+/Parent 1424 0 R
+/Annots [ 1443 0 R 1444 0 R ]
>> endobj
-1139 0 obj <<
+1443 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [349.4919 62.7905 408.4801 73.5749]
+/Rect [411.5778 307.0154 489.9929 319.075]
/Subtype /Link
-/A << /S /GoTo /D (ipv6addresses) >>
+/A << /S /GoTo /D (man.dnssec-keygen) >>
>> endobj
-1134 0 obj <<
-/D [1132 0 R /XYZ 56.6929 794.5015 null]
+1444 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [55.6967 295.0602 134.1116 307.1199]
+/Subtype /Link
+/A << /S /GoTo /D (man.dnssec-settime) >>
>> endobj
-218 0 obj <<
-/D [1132 0 R /XYZ 56.6929 285.3652 null]
+1438 0 obj <<
+/D [1436 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1138 0 obj <<
-/D [1132 0 R /XYZ 56.6929 250.4165 null]
+230 0 obj <<
+/D [1436 0 R /XYZ 56.6929 439.2963 null]
>> endobj
-1131 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R /F62 1062 0 R /F65 1137 0 R /F21 714 0 R /F39 899 0 R >>
-/XObject << /Im2 1051 0 R >>
+1439 0 obj <<
+/D [1436 0 R /XYZ 56.6929 409.315 null]
+>> endobj
+234 0 obj <<
+/D [1436 0 R /XYZ 56.6929 215.0565 null]
+>> endobj
+1445 0 obj <<
+/D [1436 0 R /XYZ 56.6929 187.7252 null]
+>> endobj
+1435 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R /F11 1442 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1143 0 obj <<
-/Length 1018
+1450 0 obj <<
+/Length 2621
/Filter /FlateDecode
>>
stream
-xÚ¥VK“ÓH ¾ûWø°»
-÷öÓÜØP[!›ñ°àà;Äà×ÆÉ üûU·ÚÆ™1Ãû ~I-}ú¤jæRø™+BE"Ý(‘DQ¦Ü»Ú¡îgØ{ã0{&ÓS/SçÏ×"r’„<tÓýÄVLh37Í?x¯þZnÓÕθ¢ž$~ Bê-¯ÞûŒ1o¹yµºÂ­«Í5^¯–~$½ôf·‚ÆB*@/±šëíûÏ]ßl·ïv¾ˆ¼Ö”/×k3ñ?¥oU:F2–Q¡ÃøÏùð‰º9ýÖ¡D$±r`B KîÖŽT‚()Ä°R9×Î?£ÁÉ®QCO‰˜¨˜G3ðqæ2F¥ø~*!¡àÂà§Cg€¥
-žœµð|c
-‰”ŠÌ˜ x(`hÿ¼RrùÇä–ä ™™qr‘ÊÇ´`„>÷CùÅp“R÷ßpÚ~·éN§€"Jäq3Ÿ{@uë'ÅÌ[‚Žýà·_.?u2""ŽùGÉ{ACó$œ2Ù=Ÿ8O]ÿŽ|ƒKendstream
+xÚ¥Y[—Û6~Ÿ_á·•÷Ä*EêÚ7wâ¤iš™ìŒÓžlÛMÛ:‘%Ç’çÒ_¿
+Ò‹†Ú¿µW[îH´;;fÛœfÓº>²ù` ÜÖÇ¢Ýíé³:íï0&IœWjvõ©\“ˆJß[†üpÐ9÷‹êl¡óÁÛÅÇшíÙÌÖLÉ·[¹uú¬H‹`u±W4IJÚåÕÖ~·ž ¸‚œ¤cQ1_N‚éÃ(‚dÄ-›¨ÁÀQ©·ì+cÜ
+0®±5*¾Ÿf¢7ówcaŠ¨@"8JçÇõ¥FϘ¸Ôeicи{õAó¶¨y94¶@ÝÔÇ=ÇiÞh–áøÆV»+ÚƧ4ÐKv—³Pú
+ê‹Ù®xeë÷ËkÈ÷=“Ì“
+â¹¼YÌ—‹1³‰Çynï®ûdž«k4(§ªÀiÖå*Ô2õcɹ
++X4B³ä‚º,!-›‘¬‹ËDD‘1›Y
+ç¾Ýa/ƒjôêD^œµõ¬û"Nˆ Ni°0ŠŒ<KÕ–X¨ž’8(&¼„ɆHºcIëºÒvM¢@y!ÂCþÔüÒÓÐ;5NnNƒ6WŽØÒ•{“B5WnˆEÖ¸gø"ñ³0ƒrj$ä'Øóºj`Û#Ö‹b?ˆ2fýÛèOqŠAê{.ĺŸ*(3±Çœ'Ñu±uÍý=ÀB; þ^·»zýmo.ñ(Ö”êÜ!ÁSÒ]uáaH\ƒ’ó”tTIà=Õ'›?5gÒ–—É×–`Û;]J$¾ˆ£MöÖ8-ò³$‰Á4~*Òüß#›ËüP…áäŒ 3F©YïM}ìVfíÜv™©©-ä”羇ì'ý0IÂ~ô˜¹•òÓ Ix3& eªŒZv0\A™=$½’ÞGãÑ3•
+$Ó1‰(fHq§ú77 G!Å9Êœã(ds*Œý0RV÷û6Å
+™­Çj°~<$ÁŸˆü‘™2X±a,aD¹#C¹9rÐY•(Æø$* †ï®äžÑZ¨dÅæ‰äYi¥¦ƒˆÞ´€¹#oO]€xŽ5kw•õnU]ÄhŒŠqÄÑÅÈÈ…ˆoqT¥ñYnlUˆ9MFý"8éÇÞ‡÷/é½aáÓˆ)öù'MÃ+w/À1ʾ‘×ôŠŒ“Æ63ªõ‘³`K#܆U$‰ý,•ÙwT€
+ƒ*k+\~:("õ©¤žž›8½lu…›ÜîžÙ¦¶·ƒsŒ¸M«®sDekF3
+ÚÄs°–0X›>ÜÃd5Xð`nªkJEæ¾ áèLS6 òÕ΀ ˜Ã§€†U‹eÍ܉p€¶„=¼;çÌnÎ>vÀTÏ]*’ÊÌB»3X|K ~"€;²®­#é'Aö‚m±×#c)•Zv¼F#ÐŒà>»!µÇ‘:øDÄá9PçÀÂ!’~h}Ä+PV
endobj
-1142 0 obj <<
+1449 0 obj <<
/Type /Page
-/Contents 1143 0 R
-/Resources 1141 0 R
+/Contents 1450 0 R
+/Resources 1448 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1117 0 R
+/Parent 1424 0 R
>> endobj
-1144 0 obj <<
-/D [1142 0 R /XYZ 85.0394 794.5015 null]
+1451 0 obj <<
+/D [1449 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-222 0 obj <<
-/D [1142 0 R /XYZ 85.0394 769.5949 null]
+238 0 obj <<
+/D [1449 0 R /XYZ 85.0394 544.6974 null]
>> endobj
-1145 0 obj <<
-/D [1142 0 R /XYZ 85.0394 749.4437 null]
+1452 0 obj <<
+/D [1449 0 R /XYZ 85.0394 516.8643 null]
>> endobj
-226 0 obj <<
-/D [1142 0 R /XYZ 85.0394 622.33 null]
+242 0 obj <<
+/D [1449 0 R /XYZ 85.0394 467.6389 null]
>> endobj
-1146 0 obj <<
-/D [1142 0 R /XYZ 85.0394 593.7503 null]
+1453 0 obj <<
+/D [1449 0 R /XYZ 85.0394 439.6503 null]
>> endobj
-1141 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+246 0 obj <<
+/D [1449 0 R /XYZ 85.0394 266.4633 null]
+>> endobj
+1454 0 obj <<
+/D [1449 0 R /XYZ 85.0394 238.4748 null]
+>> endobj
+250 0 obj <<
+/D [1449 0 R /XYZ 85.0394 132.4384 null]
+>> endobj
+1455 0 obj <<
+/D [1449 0 R /XYZ 85.0394 107.4147 null]
+>> endobj
+1448 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1149 0 obj <<
+1458 0 obj <<
+/Length 2222
+/Filter /FlateDecode
+>>
+stream
+xÚ¥YKsã6¾ûWèHUEX<ø<*¶&™lÙãÈò¦RI4 IÜ‘HE¤ìq~}ºÑ
+"¸wóëÝüöãõt&î­–+Îï®ü´¤ñíünþÃâvqk"’‘wýãü~µ°«¾•4¿ùßT;7´ts÷@ƒ‹ù4ò½Õãrñ0ýcõÓÕbÕÞ¤[Á^ãÏ«ßþà“.ýÓg*‰ƒÉ L8I"'û+?P,ð•r”ÝÕÃÕÏ­ÀÞªÙ:j=0€T¡1Ÿ!Xr`¿ a¡’ÊÚ ¶àœ{×Uù¬MQnèªëcµ§ÑÝÃÂÚµ©:ŠÂûÃ)²÷H|2“1‹’$2âWÓDzfKàåö·Ùõw8 ½×êD´ÿŸê†F¥Ö¹å³üin¾—–D0gߣäùr~K´ãTÄžÎ*ó›Ã;*x¿luéÎÔ4ÈÌ뢲 EíèûÃN7Ú*Öò››Ã5ñb­-ábÙ6-@„RÜ{)v;mÓgM£'­Íª°Ší«g¼.¥¥˜3pp~¤ ïóöA)ò—6Œç\¥›v,õ- [Й¢{¿îb¢1|c:GOš~7ºÔÇ´¡Bòš´ËÖj}¼ôÄ‘©¹—ëº!m_5èE Tò‹“P´ü] U—(ý M")üZ*žx§Z·Jv2ˆEQ‚,QÖ§C†9ÌÒ16V~ š§ÆÔ0¸
+àwMo¾ì³z„­ô ¿`l”V³K\p­üwàZ2Ha1¾@:›%•1RÚœHgãI¾ x:\°Yt É ƒ8… ’@MëºÊ
+ÂY»ÁºÇ2ô-‘Ïmc œ
+çö)`ô²-²­e:Õ±©iÖÆnœ#c¤òyDp´Û©>ƒÑÁjkˆ¡ô¬@„å|§îŸ;RŒQ'ýÐ++4¬ÙÊI=‘&r)­í/ñÚ qÚ5D®Öô[W{MmPÂMº£¢‡Šäír"튵nŠ½¶‡Ù§6ºYI9ÖóN©º¢Õ´ËH.¢Ô:ª›Ë!aW9@½‹²ÅÞ±§°³½©Ý“:4¦ŸU™éwWÊ‚°W˘…ƒO÷«O«÷:ƒ!áä­Êg¾Ï]yX•0þ
+
+h!jˆQÈØpCkÙÙ®§ Eô·6
+ŒÁÒ¡â®äùÌ€çÒ aÌ ÌwQ¾ílÓù±$í{ïœ>ØQãÃÌU:®3[W'W¢P?ÒÿP­bHQ‘/'aÀ „'øŘ֎› –½OÌ-û¬ÇO_˜Þw.¯ó ³NõIh‚εñȈ¡5êI¿øÌÝ2}]‡ Ym8ö¡^ ¿®œÇ[ïù×ñ»ÿoøЇƱ×\F1ócb•BÅe|¡¹ûÚ©úßúQyrendstream
+endobj
+1457 0 obj <<
+/Type /Page
+/Contents 1458 0 R
+/Resources 1456 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1424 0 R
+/Annots [ 1467 0 R ]
+>> endobj
+1467 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [379.778 61.5153 440.978 73.5749]
+/Subtype /Link
+/A << /S /GoTo /D (managed-keys) >>
+>> endobj
+1459 0 obj <<
+/D [1457 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+254 0 obj <<
+/D [1457 0 R /XYZ 56.6929 769.5949 null]
+>> endobj
+1460 0 obj <<
+/D [1457 0 R /XYZ 56.6929 748.2119 null]
+>> endobj
+258 0 obj <<
+/D [1457 0 R /XYZ 56.6929 682.7685 null]
+>> endobj
+1461 0 obj <<
+/D [1457 0 R /XYZ 56.6929 651.6058 null]
+>> endobj
+262 0 obj <<
+/D [1457 0 R /XYZ 56.6929 598.1176 null]
+>> endobj
+1462 0 obj <<
+/D [1457 0 R /XYZ 56.6929 566.9549 null]
+>> endobj
+266 0 obj <<
+/D [1457 0 R /XYZ 56.6929 448.4378 null]
+>> endobj
+1463 0 obj <<
+/D [1457 0 R /XYZ 56.6929 417.2751 null]
+>> endobj
+270 0 obj <<
+/D [1457 0 R /XYZ 56.6929 351.8318 null]
+>> endobj
+1464 0 obj <<
+/D [1457 0 R /XYZ 56.6929 323.6339 null]
+>> endobj
+274 0 obj <<
+/D [1457 0 R /XYZ 56.6929 230.1472 null]
+>> endobj
+1465 0 obj <<
+/D [1457 0 R /XYZ 56.6929 190.6255 null]
+>> endobj
+278 0 obj <<
+/D [1457 0 R /XYZ 56.6929 125.8181 null]
+>> endobj
+1466 0 obj <<
+/D [1457 0 R /XYZ 56.6929 94.6554 null]
+>> endobj
+1456 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F48 1228 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1471 0 obj <<
+/Length 3064
+/Filter /FlateDecode
+>>
+stream
+xÚ¥koÛÈñ»…€ÕD,—ä’Ëë'_ì\rn×òÝáp¹4I[D(R©(ê¯ï¼–™F-x‡³»³3³ó\E-<ø§F»^„‹8 ]í)½È¶Þâ æ~¸P²fe­Æ«¾¿¿øë» ^$nùÑâþqD˸ž1jqŸÿæ¼}y{}·\ùÚsBw¹Ò‘ç\^ý¼TJ9—ß^_ñÔÕÇ5ï®/—qèÜÿtw ˜8Ñ>lSJvÞÞ¼•uRŠÏžöÞÞ-ƒØùõö~©ŒóéæàdvýÓíí'š½_þ~ÿãÅõ}/×Xvå(Ô¿.~ûÝ[ä ‚/<7HŒ^áÃsU’ø‹íE¨W‡A`1ÕÅúâŸ=ÁÑ,mÓ¥Œ«Ï(ÓW 3ÑÚŸhS'nøiuýåJyhñÐmš}Ù¥]ùµi‹ý×b‚9t7Þbå×6ѹ_&¾Ó,WA;mÑ1pØñ˜Ö2Né#êßM-Ðc³gàîÝ[@ÅP·_çÐv–\¶±‹·iYwE ¨â `’Èy*êbŸvBµ;
+Sx©ý&
+Ÿ¸z
+(sáÀecàI ö„&rÓ*†Jü‚BÁ‘;/ÂPFQTù3XÊ:É[¸²”©t·+Ò=Î ¥Ý„I‰á3¯.¸¶ MzJ9±†|шJ)Àr”Э´­l) mÎKeK”NŒ“xqÖöÅ!•:tÞ7ÇB0ýLß/6ÂSÆ ];;.³‚ùÒp0Þý©mm8<xŒ‚öF½ñ&•ð#ÑðYIùp:ë”Ïú$¥…ÝZŠ‰Sksb²Cɼ áÍ©ëBŽá¾
+ W»¯=O¿Æ7o&º« vC†“¢ŽíöÚö¡ÚwéSÃÜ¡ ²?v¨$” ¨Öc{÷¨\7Š_×|c«DmRò$€>\½ð‘uÔˆº4Ʀ;ˆÔ¨V#m!"9¿©½:·clënl–
+S™åš0¶TÌÏ%ôhÚЭfÛ‰-J!•™ïú¾2óo…·¶­ºü¶$U!, G y×ëoÔš,pM–ö —ʺ—²:JYËRã÷F¤·/»Žì@)éŸÕÐ6·éVÖå¥48]³—cYˆ™¬·iªÜ†câä(M÷6®¹?‘ûõqÀåkßIgãæ§*'Š!äÊbßB&kù‹
+¿ÿðñŠ¡„‡œjÊÝFœ,Ô¶j m,À¬1;Êóïõ7~öÊÊV6È<”räAb+€l¡î¯o¶‘ź_ÔΧVßDαèoË oò9Rü6=Ë_ËæÐò #*öœ
+AÕ‘/=4TE‘1ýoXJ~Ázé×¼ýi×AÏ3üŠ×v»fÿrƒ%ÿ°%C_(€o銿oØe|‡y‚dC˜ÀYc=—Ú·¡"\ÀG^`ûV“)ÂgÊîJ;ˆ(Û–u^ì
+øC—·à°
+¹¹»²½ÎFX:N:!ÈG«'[;懪¯7@ä÷ë´ƒûv|!³A~ÒÍHÏR€~-³b¾œ”¨¹(áeSÓ—º9Öòô!9÷Øì¿0ƾÊ}ˆB6¿ÃWÅPr·>Ô¼jýö’1V_„:g“)ö,i3ÀÑ¥2MÑ¢gÏ$¨5Iʲ‚ò™ÊÜÄùf"ÜJׇó|k0w¹TÎõ-Ã`L;K .:u•vòXÁþð/=é“Ð`ÝÒže&DE°þªx(©]ìßËúðm¶ð¸†®Ï®û—¥ÆX’7Çvò 1Á¾çîK¿ŠCÅ?eÏü†íõ?Sÿß¿˜ÿµ ŒÝÀø1|ìä¹êË
+î'çœ÷?­?gý?û”ƒendstream
+endobj
+1470 0 obj <<
+/Type /Page
+/Contents 1471 0 R
+/Resources 1469 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1424 0 R
+>> endobj
+1472 0 obj <<
+/D [1470 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+282 0 obj <<
+/D [1470 0 R /XYZ 85.0394 769.5949 null]
+>> endobj
+1473 0 obj <<
+/D [1470 0 R /XYZ 85.0394 750.8067 null]
+>> endobj
+286 0 obj <<
+/D [1470 0 R /XYZ 85.0394 180.7476 null]
+>> endobj
+1474 0 obj <<
+/D [1470 0 R /XYZ 85.0394 140.0669 null]
+>> endobj
+1469 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1477 0 obj <<
+/Length 2492
+/Filter /FlateDecode
+>>
+stream
+xÚ¥]sÛ¸ñÝ¿B3×™P3Mð›™¾ø_ãK›¸±Ò™Îå ’ØP$CRV”_ß]삤dÚÍ4£.‹Å~c‰™?1 B;LÜd%¾8"˜¥» g¶¹¿]¦Y¢Å˜ê×åÅÕo^4Kì$tÃÙr=âÛN‹Ù2ûÃòm!ì9°p¬ûw7ó…8Ö/BðÙ œ›s/²þ}¿œ‹Øúðîp<ûðéþþƒž]ÎaïÀµnÞ^ß/o?Ò´Ï|¯ßük.„°®ßßܾ¡©7ïy§ßn¯ç‘o-?}¼}˜ÿ¹üýâvÙë5Ö]8*õõâ?Y&øý±½$f8¶Hw¶»ðÏ|Ï3˜ââáâŸ=ÃѬ^:iKáØ®ºÆtÅ l•{bÍ ±CÏõk‚u„ã€=Õ¨¯û¼Í;Õ¢rÀÂùÙ-ÜÐvƒˆ<ñ Ô|á‹Èê¶ ¼}øªÌªáØʪt¿Se'»¼*izMs‘•—
+S€ Ì>_Ô‘HA… ňÿZÑ·LÕYtR/uøƉUË.Ý‚‰ô`+d
+FYKÌ4ü‚óÝ
+¦ëúB€¤:ŠÌÕ$'ù.”ÍmÎlÌWÒ§ÝJ3#¶E¾jdsä-WègL‚8Ï…Õ3§$z9e€¸€˜-0ªM¤{ŽËq
+¨¼ìT³–©"¼v )î
+‰×t‚Y¹gÏß%ɽ׆îO¿€4±g‡Qè?Ï‹Ö9À‹AZá±2¸&ڮ랜)£'–Ð…ÖE„3/ ì0ŒéPy?zI B_ ¡pìÀsArMña¾>I…®u{nàéDn4ó8±<_o=û:¶ã£4ÑÖº6Ј«»;{SF³‘R†ñbÌY+ŽÊ$¶
+ö@fdžàõô1C¾Ex¸Áàq7jÕ´úÈC„dªÎ,ÅV™ ·“)¾›ÔpÔê¾¥Á×±;.ôcÇ×~Àr¨ qX7Õ\ßâ=ÊdüîëLê6ÉsùöÌó-}¡€¹ÐPÒ`¤Ok©ÝÑU[¯mx›:ð l೘’´åþ ¶Ê9\ ö»•.B0ÎO9aú¡E¡U;Ð5:Â2h*P-¯lÇ3p¤ÆyUôMá…Öø<ÉJ?Ll¸ÀdzqÜÿ\*aÒ ô[‹áMóç}œ>ÔWߟîø ™çø6&©~Úã \x÷ya%L">!wIO_U“¾ï¾ä—‰Ž°:*5áŠ÷0]Б†Ú 8[j8Nöìèb
+Ö‰Êùª i.˜Ã3@Éáîôüêk5pÞ>ÿ:°8Bø¡× ó„ÝÃäÛÁ‡U'äƒî0 DM*çÉS´çØQì‘ÿµÓcoðµ¡m×Õ¯¯®‡ƒ §Ù¶…]5›«¶Ú7©ºbÔ‚ I'{ó}úÁ›v¡ªwû­k¤¹Ä÷vÕ+è:^”2K øþmMÀÿ)Ïu]S'}ê@ÓŠ<ótÄQPTθ;øqSó>.jÁ@6¥á> Ï×¾‡Û^ä‰Ófñ¯D³ÊËl¡Û–+
+endobj
+1476 0 obj <<
+/Type /Page
+/Contents 1477 0 R
+/Resources 1475 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1480 0 R
+>> endobj
+1478 0 obj <<
+/D [1476 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+290 0 obj <<
+/D [1476 0 R /XYZ 56.6929 769.5949 null]
+>> endobj
+1479 0 obj <<
+/D [1476 0 R /XYZ 56.6929 749.1192 null]
+>> endobj
+1475 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F14 956 0 R /F62 1352 0 R /F41 1208 0 R >>
+/XObject << /Im2 1341 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1483 0 obj <<
+/Length 2317
+/Filter /FlateDecode
+>>
+stream
+xÚ½koÛ8ò{~…; 21|è¹À~È&i/ÛÝ$׸·XlY–c¡²¤JrRÿû›á²ä(Û^‹;†Ãáp8oÒbÆáOÌ"Ÿq{³0ö˜Ï…?K·'|ö
+ßïs9·o¯gfïßßÝÝêÙÅüÏÅÏ'W‹þ\ó ®ðPŸNþø“ÏV ‚ŸO8SqäÏž`À™ˆc9Ûžx¾b¾§”Å'÷'ÿìfõÒ)]ö4 S æWm+$‹cߛޖƒaBÁ_Öqàe@»bÌê`ê ÌW\ô¦–rVˆ}_¢­cÎB&}ì­oPÚ2f~à $ØH\SÜÎÝ@€%Ü@:WÇö
+_Fˆíé>deÖä)ꑤQ ¡T >åiæÐ@…JŒmîºõG!\ÐQ™l³¿)cŽGâfë“ß}Vüâ¢&[çŸ÷žJמ`˜Î׶´çp³SÂ5óÈÙ•ë~þy 8Ü<"?4×¥mò1›Øº›˜¾!¢«2…¶ï%î
+dæž2×ëº <êù6žb*RÃm0ðˆRÁˇ
+ꂤ¯Ž
+]n¯Ëã›QßYjR2¼{ËcЃÏQ0žµg<ÿõ20ú°÷Èÿ[)kIBèV@¼Ã'M¿¡lÙZxß\®¦Lô¿¬[˜Ÿ^[ŸùBÕ_–1q¡¾@Y&ukkš¼3Y¹û‡¢ã6ÊÖÏÑÛÔOÝ0éú9U594Ø}¥z©j†ûCaˆPÄ N1S~èKúÿ‹¥ËƒÜeÈ)‚ðQ‚AzÆg»-S}“)¡#°I
+Üxx3‘m”Œ^lŸÉHÙ–!©ëöÌÄ
+¸¿×úJ«ÚMµ+V„_f„«JK¸&DgW^  ¬~~R¾·QPܪŸªŒ4f©È®W–b5í²Õ/ýÌ€}RS?
+ðþeý»‚8<ezàîQ$§»ÅÉ8´BáÔ³Ç[_EÌd8!ú
+endobj
+1482 0 obj <<
+/Type /Page
+/Contents 1483 0 R
+/Resources 1481 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1480 0 R
+>> endobj
+1484 0 obj <<
+/D [1482 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+294 0 obj <<
+/D [1482 0 R /XYZ 85.0394 629.0401 null]
+>> endobj
+1485 0 obj <<
+/D [1482 0 R /XYZ 85.0394 603.8306 null]
+>> endobj
+298 0 obj <<
+/D [1482 0 R /XYZ 85.0394 304.8197 null]
+>> endobj
+1486 0 obj <<
+/D [1482 0 R /XYZ 85.0394 279.6102 null]
+>> endobj
+1481 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F62 1352 0 R /F21 930 0 R /F41 1208 0 R >>
+/XObject << /Im2 1341 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1489 0 obj <<
+/Length 1904
+/Filter /FlateDecode
+>>
+stream
+xÚÝX[sã¶~ׯФy fL^;³^­·Ùl²v×J;™Í>Pm±æEáÅ^å×÷€¦$:M“¶‡ÀpnøÎ@bÎáOÌý€±Œçaì1Ÿ ž–3>¿‡±¿Ì„™ãÚIîxÖëõlùV…ó˜Å æ뻑®ˆñ(óõö“ã1!ØTpçæýêváJŸ;‚?qŸ¯>.Tèüx³^ˆÈ¹~ÿdfôö‡››k=º^€m_:«o.oÖWiØ3z/ßüm!„p.?¬®ÞÐЛÆÒÛ«ËEè9ë>^Ý.>¯¿]­‡¸Æ± ®0¨ŸgŸ>óùRðíŒ3Gþü :œ‰8–óræùŠùžRVRÌngŽFõÒÉ\
+Τ
+äD2=1J¦à0*T0½aHÙÄ|íÒVÊRÀmZ±¥ÓŠ¬ºÏ«ŒÚm¿ß×MG\ßæ÷õêª8h=˜å[)Gæ]°IÎ]Å™'Á_4Ýü™æ¹:9õ?áiÚö]Mý$M³"k’®nþ-—?d_º ÀB9Í"rú
+Û ^JÏè‡âÃæÈ0€­ÂµÉ~ß.ë}VµmAˬ»Ø¦è¨ívÁî1ıц&±³Þå--|Ê £:麬ÜwÔÁ¨ñ›Wy—'Eþ‹±ÙíLÃÔRdk)èÛBÀŠLλ;£Ãè“àãÜQÀü8ô¡%Xìû„¬dSdT2Ú6|·æÛÚo[жw}Qt½]\ë÷‡P Õ`%g´—ºÊ¥T¸aÈüH„&?ŸÌF?&yAÞ`÷óDba]È£à(¯:4éûLÆPÊ$óLÍ`TàSî°Q÷ݾï°íaR´,­ò:E´¨ØЂ£/ E(ÉÂ0ôŒ#eò`,äUÛ%s×ý)ðïÙsZð´ËÓiê4jߌ–cïËz›ÿĹ̶Կ|ÞÞ~G¶Ï»ŒVÃ6ž§\*`(Øz²Øî–”9O*ø¾gAAÅC_öm3J Áû‘Ñņü
+ $íðˆÅ€™ç#A.\Áa_÷y±Íº)¯ß}0 [Pu;j!âëçŽpÜx*Iêÿ¾Ë`ÛD¬œÍ {¤[1"—›œ¢ ¨Ó¤Ëk³¬¾£¯öœ´o»ºtQ]GCCÒõê|Ó$Í:%Ì5ÖòvŸ¥ÃŽ¡à1OŒÞºBù}OÐcƒØ”©ƒÓä9uL˜ä­/gð®n¨ñ]^õ_þuúÖ‹X:¦ä‹¼z8Ý¢ ò8ßë@êÇ|›5xì^Ø%`²mI@IÂÖÆ(Ë*,ù­a”êÄÔYPzg©èùQ±¯õáYï„2ÞhØ'”RZ@ÚÙ—W74ô>;ì33ªydioø¡êŠ áéI-KY@¿FWÒš/­VÒÝhšÑ&¯Ð $P jGDÔ0ëÉ.&KfºÅ°uTžX%|´¢DàYAÑ®n5‘)©Õâ0%1v°fGË­“(ÒVI¼9˜Y[*%”!q¹¥’†À` é ;cpµ¢1`¨­–„ÖçÎÎB'…`éö9^ÚÜ´.ˤÚØ´ãVÌèüÿšŽ‘tK_Æ–°[x‰ñ©œšùl >Ýåà‘9‡V«W_ݧ)u0ö¯LÓ%èº
+¼)Xݾ­'§€·& }.´¹6;Y—V
+ѤR“¢éÊ$Fß÷ìà„þ5•ÈNÅ
+Ë}‘äÈDŽádSã-G†ã;Um¤Ouó
+vɣќÐGÉ¥å`-5nÕ,íFžÀ%!oˤKwlj ®|‡±Z«¡°VC¼ên­…>ºm €}¢ë E5}ŸÃ¸WÚsT²«û¬ßd'zÚ¤4-}ʇ`k‚½áppá i¦<Ü÷p¢¿;†Ò|vÏ3’Qï‹©óÿò®Ë ÞÒ1‡]Ø—‰yú/>÷W^4¾ÔŸÃ óÀ]ä/~]+Ì÷Ž
+:Ö¬z9zŠy*ˆŽž º„ìá÷‚%X$xpfæWÞ#~,NŸRgyÀ"¼¬ÄÔM^™3c‚´×úšS×Åo8 «X±ŠÞE¿ÍZ&$,áE\&ÉÚ¬#)ÞØQÐiS¦i†öø£Af„Z ýæöû ‘sÁ:M'ÇìØ]#ös²Ã=<0Îã bÅÊÎ&û±s"Š"vªì‰ž]
+ÒʽðäÙ&sàÐKrsëCÏ.”R ÔQL`Mø, ý.òI¨AP#¯Ñ„ž¬mÔ›
+endobj
+1488 0 obj <<
+/Type /Page
+/Contents 1489 0 R
+/Resources 1487 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1480 0 R
+>> endobj
+1490 0 obj <<
+/D [1488 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+302 0 obj <<
+/D [1488 0 R /XYZ 56.6929 596.0056 null]
+>> endobj
+1491 0 obj <<
+/D [1488 0 R /XYZ 56.6929 566.6651 null]
+>> endobj
+306 0 obj <<
+/D [1488 0 R /XYZ 56.6929 532.1171 null]
+>> endobj
+1492 0 obj <<
+/D [1488 0 R /XYZ 56.6929 506.5445 null]
+>> endobj
+310 0 obj <<
+/D [1488 0 R /XYZ 56.6929 353.6477 null]
+>> endobj
+1493 0 obj <<
+/D [1488 0 R /XYZ 56.6929 325.2657 null]
+>> endobj
+314 0 obj <<
+/D [1488 0 R /XYZ 56.6929 132.6175 null]
+>> endobj
+1494 0 obj <<
+/D [1488 0 R /XYZ 56.6929 107.4872 null]
+>> endobj
+1487 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1497 0 obj <<
+/Length 2294
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Y_oÛ8ϧ0° ¬|ˆ‰Ôß
+ìŒê¥}¾ d챈zœ)DŸ3ƒÄ ¥Ú™%ÆÖû«‹Ÿ¼ËËõêO×y‘ÕÇЉ¤ÕÜ«Z¿©ª¢&2]¡kÔv~CdU¤+ŸçÕÅÕ9Q 59‹˜Uå'×wk•÷)oîy·{E’> j¶gÙˇY­O
+øղɫÒÁs
+IÅL/ëñtŸÏîû
+‘ÚÁqñše6Dzºõ}Kð­k³¯¯›¼ÈL:á[Y¥¯J!µ±XIOç:r®Ã ÉuŸsù锾ºa{ŽV2O#(r(Í…ß“©43­÷–Â
+}s´B[x`}w¥¾hÑN©š—@ßý÷­Ä'þœ+¨ÛKSVµ[?«N[ÂÐârx]Po]þÍ!SaXƒ"À\®òGT˜Äñ@ƒõ‘ Ô‡á)‹g¹8B‘«9FŒ]8zÈ5ë}Yä¼E‰¥ya¶§–·=îýš ¯Z[ý¦IõmiÕ0{¹žùŒh‚{d³°C D–6)æ“í—$à¶Vc‡o›ýíøS’0_‚D´³ïáÒZëÚhÕgÔ¾ðFÅÍ龦 ¾EÇ è0–‹Ö'Ç'½
+¶ÿ©ø‘#ãXôñ”nèÄ"‰ŒRèV)÷5oÿS8Tý/Þn­™endstream
+endobj
+1496 0 obj <<
+/Type /Page
+/Contents 1497 0 R
+/Resources 1495 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1480 0 R
+>> endobj
+1498 0 obj <<
+/D [1496 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+318 0 obj <<
+/D [1496 0 R /XYZ 85.0394 704.2027 null]
+>> endobj
+1499 0 obj <<
+/D [1496 0 R /XYZ 85.0394 675.9152 null]
+>> endobj
+1495 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1503 0 obj <<
+/Length 2284
+/Filter /FlateDecode
+>>
+stream
+xÚ¥koãÆñ»…€×\¾i¤ŸÜ»8‘]K ÐÜJZYÄQ¤Â‡\å×wfgø’ØË…?h8;;¯Ýy­åÄ‚?9ñ|áGv4 "Wx–ô&ëý•5yµ\I¦1"³OõýòêúÞ &‘ˆ|ÛŸ,·=^¡°ÂPN–›†+¤S`aOw‹©i{–ñ) øhyÖÝóÔ Œ=-§24ÞŽW??==êÕåd{¶q÷îöi9{¦e—ùÞ¾ýe*¥4nçw³·´ôvÎ’îg·ÓÀ5–??ÏÓOË®fËÖ®¾íÒrШ߯>|²&pÁW–p¢Ð›¼Â‡%dÙ“ý•ë9Âs§Á¤W‹«¶ {«zë¨/¥%lÇ·GœéÊ1gºðƒ€œùשé[–±ÉÊR­ÍÏêô¢2B©ÇûCªD¦*4óúÞ¶{̬‰éX“ž£Ù,wI95'2:=?&5•#SU2Rê"©NøÕ.ÎO¿¡ñnñ!@}oàNdUWÌ ÉÖª¥e®ëfûJ1Uš¿&/˜¤Þ¯TQæ{¦¨rZ¯KFlìDËà~EžgkË:…íÈ7´q*.ó¬DŬÀH*ZÙÇL‚*Ø‘gìs"&¬ÚâÇG˲׉ÊxêÐq-Uqä½Ú ¸^( Bõ4 F Ɉ¸Ú1‚¼¬‰‰ãïu+
+™eò’%ÙËÐJºùAq•ä™@wÃíÖ<ýÐø#ÏT»Qcð`4 nûY :ù4Uúîy
+‰vs( oæx•”ô€,ÇÍà‚è<©†N””Šæy¥nèóý–H³¼" .É©°‹·[†ÉY&?t:ƒ(
+äˆÀu<½ðm¡‡xš—Û¾p-ÉL1ô @ZÕÕ>ÓÐ>.+U4µ÷4~Ùv×™žÝ(t¹4Í”mÝÐ †ùr˜vÛSÓH¼# øüNÏ2­'R>½ŸßŒEõ/ªH¶'­%’ikèdñ¬n!„óק/9Èn_ÞŒ©1_ÌîœçÅíâÝ­c¿¶ÂZ—átª08F¿mdÞq_£~]<” Ê7ôûÐC±îë*9*^¶è§PÇü³Ú ‘egsu3 wM€ôÖ„cK¦ ¢ ·ØwÝ®Iñ¦¦´€ûâ ÖÍA ®Ê^’æâåÙEí÷ }¤ÉhPƒTÛ¡ßTa¬eÐÔ<B®\,~ħ‚ T(Ð…KT ï9&m\€y™ldè ÙÅRï['ôµq°ýp›£uG–1æ†i
+ajûvD +±“i«<OK6ïDø~÷„ÚÆGÛvÍq“ƒXu<0À3çÿÝX2…ä,—|ÉÐŽ„´dÿ3>¨V=·wôGG¯ÑT°º„•@jj("zìÄðsU'iEà+Ä-Òíóm>¯KÝ<·°6„X“êàp_[€j£¶qBn×Áõ„øg>Ó 6 ´I$
+ Ïð¹Îºf‰ªG«
+û>HuÀÕ‰~i¼æŠ@ÜGr
+ˆh¦¸‹ìãxX¦bm/›wœÄ’óþ*^åG5Èp0—©ÃƸ즫¹†H¸¦È¸®Ëâd^÷e_^$lž˜ÚAÄãFÙt%\Þ ð†•foz¾|sÕu$%}§Ñß9·(Z‹fDuxžÃíGUÉf£ü‰~! sâwdÇûñi6Ç*vö¾åD0R=±]pŠ÷U\¶ˆ ŽÆŸ·Ì–¡Ù㨟®†±EÂõýV,ºéîq~Oʪì˜P5ËöT‡Á”c\$&Ϭ®- K”ÃËÔU¤óÑŽÒêYÂ}XèksqÇ*Œ¡m¼ç7˜–·TeþF?Í´Zc#ɇK*ø4:¿è¢Zøî7¨9ú‚ÄÚ‡QÂÿ.¥)=!„2°ãŒpLH/ô$|÷ôãíݬ‚ x7{žõÚæèp²
+¦ã(N˼ôC"‚Ü9‡Ý<Bh:äMM¾ìï¢<©Å4E>(£º,š7(ˆ
+O§¬e³™4"’E=y5iŽ놕+Hÿù­ÿE…¢ëay½Ì}o›„»7£²ºx>jûXæfØÓµ½4h¹oŸNÆ^ÒOàó÷È»·Õö ÿ÷+{÷ï¸"NÚãY.ܘ°RèfǽмyŽ¿Tý?,{Cendstream
+endobj
+1502 0 obj <<
+/Type /Page
+/Contents 1503 0 R
+/Resources 1501 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1480 0 R
+>> endobj
+1504 0 obj <<
+/D [1502 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+322 0 obj <<
+/D [1502 0 R /XYZ 56.6929 519.9229 null]
+>> endobj
+1505 0 obj <<
+/D [1502 0 R /XYZ 56.6929 488.8874 null]
+>> endobj
+326 0 obj <<
+/D [1502 0 R /XYZ 56.6929 326.6298 null]
+>> endobj
+1506 0 obj <<
+/D [1502 0 R /XYZ 56.6929 298.4037 null]
+>> endobj
+1501 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R /F11 1442 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1509 0 obj <<
+/Length 2429
+/Filter /FlateDecode
+>>
+stream
+xÚ¥YKsã6¾ûW誥ª,/‚¤ošgœJ<^[“29Ð"d1C‘‘´âüúíFƒ%ÑÎV]e4€F£Ñ ZL8üŠI2®=‰ÍB.ÂÉrsÁ'0÷ñBxžYÇ4r½Y\üøAE“„%FšÉb53Çb²ÈþÞþ4¿]¼¿›ÎdÈͦ³Ðð`þî·©"˜ß¼}ÿŽ¦ÞÝÜñáý|é`ñùî=Œ
+Û0h›Ã½®¬Ä*Qª#m1‹¢(øä6uû£[À¦5©çàF½O€JhÂûÄt¨>Zþ!/ÓÝ3ñéƒ-œ;œYD…lËc€ù–ò˜oÂàkYíK" +Œ—ÚÔÍb;°B 9ø’Pá¡mht
+3¡“w„ßnˆLƒTB !6R„ØDSáæÑdHp;±Ô¨!åß#÷Ý)ÜõæÚ™·~¥T*»§Üî}oåAwm{¼%÷¸%¨!ıFY6-Ùùxí UÐ¥_kíiÉ­¢˜Åx3£á€PÌÒäîÑ¿ÚîÏåž6\Ð=HÀw&-p×YÞÕTs&™8{
+ÿCñçöŽë_´8—†Z0}bø€ž©'á RLnúz´¤Š}6¥Ôÿ…î$ê|®wg@ÝáÍúxõ®Y¢…v›,¨
+ ;÷5øñU^xrÒ˜{T᳑¬îÒ$¯Ëmp%/¶ÙxåIŒJuå…‹3Oµe‘µGBôéeCªšWäÕ[»Ì1“l=†}¬CÙ˜z4H¾
+AËwuø±
+ˆ­‚ÒÎþ"b_’C´8qHÂâ8JœZ?|º»þˆ ï—1ÀûÑçɺª!I# ¬
+øa/Íé{v»xÀ1`WÙC|u%^ŠŸ±øQJ»ÜVŠ8ËË™g6pY >yõàûl ì` 3Ïfcá¦ÈÜG;\¯¼jè8¸ÎÝyn¦¤–B§»!:‡!= ÌÁ/Þ Ã¿Ðýuð(Zì²{ò5ëw aàÝÞ—*WW+ø¹‚76&fÚãʉ}q7:ö‹ÒúngG©$Óa$FBŽ!D÷꼡çÃ+˜qãŠRÿ‰•Pÿ_Aãw÷hpsÕ1}ÿ‚N»¥6õ“G郹Ÿ(ýžH÷5’‘ÿ€5¶+¸ËÆ÷Ó.c±Sç%ÏD
+øÌI5Á_­ +®á½"c}ˆ1¯Þyç¾×PR‹DÔÞlÄ`!„B,:ÆNgH ~Ò]„£ý™ýÛ¢ñÕ®–€TÑ‘‡dë¡äØb«ª(ª}ï‹}Õ~#‚Íê _ÆTèrÍ bÔqeqüòÁÜèc‡Þ@ã/1ÊÙ>aÎps$ƒüÚ­#oבɄ,
+U÷Üa#âð]°öË8ÊÙñoÌX­p=ÉŽ\y‚ñ×~!ý…ÖÀ"ö
+endobj
+1508 0 obj <<
+/Type /Page
+/Contents 1509 0 R
+/Resources 1507 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1480 0 R
+/Annots [ 1512 0 R ]
+>> endobj
+1500 0 obj <<
+/Type /XObject
+/Subtype /Form
+/FormType 1
+/PTEX.FileName (/usr/local/share/db2latex/xsl/figures/warning.pdf)
+/PTEX.PageNumber 1
+/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000]
+/BBox [0.00000000 0.00000000 31.00000000 31.00000000]
+/Resources <<
+/ProcSet [ /PDF ]
+>>
+/Length 557
+/Filter [/FlateDecode]
+>>
+stream
+xÚm”In1 EOPw¨u€$ÅIg0²Êľÿ6¤¤êV5 oʯÅésÀóή¯ƒÖ×O²Î Ž¢‘ÿ¨#h8Çùø:„5?ùÆ [ÄIÚL’~”F Ø PÈùYÌÀ¹dˆÐzZ8å±Ýƒ²ÙËò‘–Œ€f¾Å(ÌÀE#@x˜oL Û¹[ƒ±ñðù
+6\>RgÈbÏWÖ¹j[†›
+WŒÏ¢®{6;»²þFÃÇñ÷ø]š¨)Õ/Ô¬Mu;pk;Ì©Ëdh<åE–ñ¬AÏw³ð¬±±Nê¦ó¡Ä½t•‹ùD„™Â²]°Ä(‡;„ ·åŽ°Š­r²ÂÙÄLûˆ T¥Í¡誋ŠŽt’¹w_ =Î]ˆ‹=¦uSä÷—ä"ï±yl±‡µÃ-ËkHsŠöreOÚ³êvg›<7ºt,‡Ýe—;ãÒèЭ/I…B÷&ê(ýê³ö󻉨YÙ¹Ç,çkRÔšÚ'^ m" ^˜h±ÎW9AVªy­Â©/fýÆ"•œãûFy-Sng \Çdª¼˜©Æ¥†Í}B©•µŒÎ$âw1.¶&Øíþ²C¶O–ÃVç X×9g¹E{îÇ< •ãóP)!ÍZÜÅŸLÞª~ÑÔ'¯UâXLµüc“ÅXsЖõÚ¯½˜Ó’~òBL–§èªÆ¹O¦ºNZ_[Èü.øšŠû*]3QôçÇñ!Ö-žendstream
+endobj
+1512 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [377.8384 431.1147 436.8266 441.8991]
+/Subtype /Link
+/A << /S /GoTo /D (ipv6addresses) >>
+>> endobj
+1510 0 obj <<
+/D [1508 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+330 0 obj <<
+/D [1508 0 R /XYZ 85.0394 640.7425 null]
+>> endobj
+1511 0 obj <<
+/D [1508 0 R /XYZ 85.0394 609.2714 null]
+>> endobj
+334 0 obj <<
+/D [1508 0 R /XYZ 85.0394 416.9256 null]
+>> endobj
+1513 0 obj <<
+/D [1508 0 R /XYZ 85.0394 388.3459 null]
+>> endobj
+338 0 obj <<
+/D [1508 0 R /XYZ 85.0394 261.2322 null]
+>> endobj
+1514 0 obj <<
+/D [1508 0 R /XYZ 85.0394 232.6525 null]
+>> endobj
+1507 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F62 1352 0 R /F21 930 0 R /F39 1151 0 R /F41 1208 0 R >>
+/XObject << /Im3 1500 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1518 0 obj <<
/Length 69
/Filter /FlateDecode
>>
stream
xÚ3T0
endobj
-1148 0 obj <<
+1517 0 obj <<
/Type /Page
-/Contents 1149 0 R
-/Resources 1147 0 R
+/Contents 1518 0 R
+/Resources 1516 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1117 0 R
+/Parent 1520 0 R
>> endobj
-1150 0 obj <<
-/D [1148 0 R /XYZ 56.6929 794.5015 null]
+1519 0 obj <<
+/D [1517 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1147 0 obj <<
+1516 0 obj <<
/ProcSet [ /PDF ]
>> endobj
-1153 0 obj <<
+1523 0 obj <<
/Length 1913
/Filter /FlateDecode
>>
stream
-xÚX_Û8ï§È£h\KòßÇöfoÑÅ]±èÎ>]ïA±•‰P[ÊFöäæÛ)JNœqºE€˜¦(Š"©)³M?¶©‹4M¾©š<-2VlÚá]¶y†±_ß± “"-r!àeet[ˆ:-j^m¶×J>=½ûðOÎ6<KË’›§ý¼VYÕi#òfóÔý'ùÇAGuzØò"KŠ‡ÿ>ýFÓò´ª+†Ó2X¢H«&«ý„§ƒ"áOŸ¿<ÕÐã_úù0žþã«r¶åQ+ËS‘—<h-EZ•™Q¤ìa˲,»è¿¯. ïNòôtóM“6%/ƒj^§eÕ2ø¡É’“ìô¨­‘}ÿ
- 5e"Ç^·™Ž8ù¢ª’R†x½6ßUGôY—Äpã´#êôÀêd6&’y^~<È1LQ¦s×sÚéä4­[&_þ  MꤕÃÍávK›¢à~;£¥ýKzô¶•=‘­lÚ<Ó‹‘Cð£S'´ªÊ“tÖWA@Æ ¾Ï¿¿”[«[Ó*¤ªD›Ñ[g»©ÅÝã¨QglípìÕÿôøJ lid<(bÍî˜Ð½Ä;’ÆV9÷þa 霸©=ÐDéHfoûÞžýý1Ö¤6.ˆšnÍ+_>þûØ/¯£_­v¸Üσá*qz˜úQe'Gzk¿OGµ{âWr¢æ‰ä(Ï꺰C§\
-veÒÖNϬ—ê¼g¸rÞÊ.ÎèŒÈ¢h¡Á¾¨îý<æBh%ÒËÞ:z³á˜èáhÓ»>HÅôÑhÇ L8[Ú,²j¼œ—D>Õ/…T¿—T„ ¬ñØ€0š&îm´Ù­4DÈÞY¢Bž¼è.ÈÜ&ò0§5¤RP¦†³à÷öÆ'çSʯ†í°ÓF^b ®Æû+ìY‰Óò¸ó†_Ž;oDHàJz+ÞI©!úê`Dñ:™Œ¡£ Q’â™ÞR-ÅãT!pº
-M&PÄqíèÙi7jÓŽ4¾§YyŸ"A¦͠ì‚d,"û©ì±‰kkÒ;¥)ÏR^Š:”&JÓ×9*—“²,Jן©IW؃È!6Š‚O
-q¿–D"mX• ‘¹ÈjmËúÿ@CH®2#¶¦È²&RØš8"u£
-:åô³¡&Ä«»Û†ý5é˜âB€û}Ye¡ødÉ °]B楖x¬†Í@”üizT(þ¶Úxe訳vTn3o-òÁa^¨ª1ü8Háã=ô6³¶µ{Ó‘¡š»hW”P·Šj‰v¢æwЮ„Z[Š´»ƒhM 5ƒ© º¡s?‡+ì
-ïp,'èñ+)jä‘jåQúk ©ï¯‘ÙYºÝÕ¡Eâ¦Á§âÛð´â·I-§Ñ;ÀÍÍ$b®»Ö¬Ý‰ÜQµ㩺›{JýÐà4;,ÿ‰f`¨º ‡W$‚7€Úù«1[Ë/¥nÆÏX «Eš Q S£»»·ž;šWïP{“øÄDN)ój=u”ö¬ÊùßC;»òÕ]Û Ñ_;Œ`ÝÄF
-q…7ÉGb†N0bèKNôJ… $ȳÈBÏ"g¥O Øêåýµ G’^—=Ys{}ñJE½Ó6l`‘“TÈ‹«Ã}%­JüŠÆ‹ŸêIÙmS:_Óß Р*çóýÃì(š´ªŠúºWy÷ËÓü-1~!EŠß×¾6F‘íE†>5.NF¸áb¼¸]mþpùv¹ÿ`)iendstream
+xÚXQÛ8~ï¯È£h\K²-û±½Ù[tqW,º³O×{Ple"Ô¶²‘=¹ù÷GŠ’gœn ¦)Š¢Hê#e¶ÉàÇ6U‘f¢Î7²ÎÓ"cŦéße›gûõ 2y!Ò"^VF·…¨Ò¢âr³½Vòéé݇r¶áYZ–¼Ø<íçµJY¥µÈëÍSûŸäuõéaË‹,)þûôMËSYI†Ó2X¢HeU~ÂÓA“ð§Ï_‰ªéñ/ó|Ïÿ‰ñU;Û½€ò¨•å©ÈK´–"•eFf){ز,Ë.úï« Ã»“:½Ý|S§uÉË šWi)kA?ÔYrR­T×½ÂBu™¨ã±3B¦#ÎA½h¤d²Óz ^g†ïº%úlÆ+b¸qÚuz`U2›GÉ</?Ô¦è¡u×sšéä ­[&_þ  Múd´ÃÍávKë¢à~;£¥ý+zt¶Q‘jfx¦—AõÁNŸÐ*™'é¬OB@Æ ¾Ï¿¿”[«Û¡ÑHÉÄ £·Î¶Sƒ»ÇÑAŸi°±ý±Óÿ3ã+ €°¥‘ñ ‰5»cB÷ïHíÜû‡-¤sâ¦æ@•#™½í:{ö{@öÇ`XsPfpAth×¼òøåã¿ýò*úÕúg‹‹qÁý<–‰3ýÔjÐvr4¡³öût¤Q»'x%'jžHŽò¬¶ ;tÚ¥`WÆ!míô| ñÞºq©Î{‰+ç­ì⌎À˜ü@-ÔÛݾŸÇ\­¢Qz9Ð[Ko6Ó­sfש˜>íèõΖY5^ÎKH"ŸêƒBªßK*ÂV{lÀM÷6ÚŒìF D¨ÎY¢Bž¼˜6ÈÜ&ò0§ ¤RP¦†³àwöÆ'çSʯ†m¿3ƒº(Ä@]wWس§åqç5¿w^‹2ÀUôþV¼UÒ諃Å«d:Ê )‰@ žyà ÕR<NÓØ^? ˆnšÄ‚¼qË 1¿!çÓ39Kþ|ü}»SNû=ÔѼÑ6¶ƒ LDCêäçùµ«üüån‘s­§ÐdE7Žž­q£š‘Æ÷4«§1ïS$ÈÔ t « ‹È~êB{lEâÚšôNiʳ”—¢
+¥‰‡ÒôuŽÊå¤,‹Ò#ÅõgjÄö rˆ&‚à€qéR¹q)p
+q¿–D"­Y• ‘¹ÈjmËêÿ@CH®FlM‘e‡Hakâˆ4A~ŒJ
+í,7 >ßš§’ß&µšF;Ønn 1ûpݵÃÚÈuc0žº½¹§T?
+¯“Ä `ÄЖœè•
+Hg‘…žEÎJŸ°ÕËûkŽ½.{²úöúâ-Tšz§mØÀ"'©3V‡+úJZ•ø?Õ“²Û¦t¾¦¿  ,çóýÃì(êTÊ¢ºîUÞýò4KŒ_E‘â÷Ƶ¯Qd{‘¡O‹“‘ä
endobj
-1152 0 obj <<
+1522 0 obj <<
/Type /Page
-/Contents 1153 0 R
-/Resources 1151 0 R
+/Contents 1523 0 R
+/Resources 1521 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
+/Parent 1520 0 R
>> endobj
-1154 0 obj <<
-/D [1152 0 R /XYZ 85.0394 794.5015 null]
+1524 0 obj <<
+/D [1522 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-230 0 obj <<
-/D [1152 0 R /XYZ 85.0394 769.5949 null]
+342 0 obj <<
+/D [1522 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1155 0 obj <<
-/D [1152 0 R /XYZ 85.0394 576.7004 null]
+1525 0 obj <<
+/D [1522 0 R /XYZ 85.0394 576.7004 null]
>> endobj
-234 0 obj <<
-/D [1152 0 R /XYZ 85.0394 576.7004 null]
+346 0 obj <<
+/D [1522 0 R /XYZ 85.0394 576.7004 null]
>> endobj
-1156 0 obj <<
-/D [1152 0 R /XYZ 85.0394 544.8207 null]
+1526 0 obj <<
+/D [1522 0 R /XYZ 85.0394 544.8207 null]
>> endobj
-238 0 obj <<
-/D [1152 0 R /XYZ 85.0394 403.9445 null]
+350 0 obj <<
+/D [1522 0 R /XYZ 85.0394 403.9445 null]
>> endobj
-1157 0 obj <<
-/D [1152 0 R /XYZ 85.0394 368.2811 null]
+1527 0 obj <<
+/D [1522 0 R /XYZ 85.0394 368.2811 null]
>> endobj
-1151 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+1521 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1161 0 obj <<
+1530 0 obj <<
/Length 69
/Filter /FlateDecode
>>
stream
xÚ3T0
endobj
-1160 0 obj <<
+1529 0 obj <<
/Type /Page
-/Contents 1161 0 R
-/Resources 1159 0 R
+/Contents 1530 0 R
+/Resources 1528 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
+/Parent 1520 0 R
>> endobj
-1162 0 obj <<
-/D [1160 0 R /XYZ 56.6929 794.5015 null]
+1531 0 obj <<
+/D [1529 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1159 0 obj <<
+1528 0 obj <<
/ProcSet [ /PDF ]
>> endobj
-1165 0 obj <<
-/Length 3113
-/Filter /FlateDecode
->>
-stream
-xÚÍË’ã¶ñ>_¡K*šªŒ7ÍiýØd}p{o¶«Â‘8#ÖJ¤,R;ž|}ºÑ
-Waƒš)m%ÂÌ ™æLZEBµL€ap~ƽ¯Wq/¿£ÍïòI:pH^”ïÛÕª}Žòâäv -©YÕ]O½`ùÐV sø·ëª¨ý’XP»ëÓXu¬,óݤÔ_´ó.>¿Eúï¾û8øoAè…žh!™å^¢óÿíîç_ùd±âû;Δwfò 8
-h\±›f¢š%žfÊÁ¾x燈v œ0“)¥ÌDsͤæEؾr¾:–‘‚9«üð „$™wÎå™ gc”!:à€D´‰œ 8À‚¢|D]QÜxè¡Ê)ºØdlµÌ9íâìr±ØV]w,
-e5¨.·’DBxEÊLØcA€š/OHô³ÚÝ’Æ„ñ
-‘šC^¢@È º[”ÔsŸÄÝÑ-*4Ý}
-{Häí¶–Y@ªùîj
-&1èI Û§ u~M ð§4)Ú1^¤ç§j¾Ïˆ!чTÿX½`Œ(Ä=''$Ô*N± ÕH>ÀŽB×­l2¹/G™fœ °PÛx ±éJ€5 
-2Æ­®¯¶Â+Þ0¸/…Ö=gb”Œ»Á!hgAó1S:Æ/ ‰4¶¿BgK —â—PaÙó~]yÅ8™ßH@¾‹RÞ@"jÕX@ç"X™JÖNgC÷ šY¹Êðl3ÎúóÞp%º¶·âyÀw‘gÃj­óœuíà:<ÓÎeÏe³ø*ëà•cZ€EŸÛbé=D<n]k¦¡¦x½[Ogc”™mæPÞq m
-h4:‰[q=`¼Âµ®•úë3ö¼pÃåÀ Ô^VØiÝÌW»E…ŠiÎ|3‘]8~½ÑXQÎDzLe=HF}Ü7Pƒˆq6F™‰î*ÓÂíNòÈlATq®ðãcµ| …ˆ×EãJQß²R×À…,®2È…Ñ&ð¼h×eÝœD2åYám±‡}u,Kgc”¹h&!e0GTž;â–q<3â™ÔvúÛî^€‡SFøÛõ[:ªÔfú¼¬Ã ?×álù1ŒÄƒI/4]q@óí?Ñ8’ñ†Æ1b§ú½\ÏrGþ›t<ù‹”:cPÒ5رdŒ/¬¯ºží÷ãˆW°>ëlŠMˆó‚ºŽá{°!H€K}E]%L°Z‹¨®=nì9u`o§®c”ÔõÊj^¯ËÕuý{È®Àëâ%…¨V»-ÔM_=¡g ãŸËÕ.$ið…Ç)ûÓs‚‘ÆЗ®Ú”Û²'xØ
-”]—»Íùb¿؟¡©°¡k8<Óï2§r<¬3Ék
-©rŒjæµò‡•ñ
-'öuð8Z¿›· CHU™îá|éAæshQ‰P¼××ãÞÍcoY~®°ç¦åú¡~ÚÕý }À£/­ê-uÊüo<»ÓŽþ­w]D÷På¢à¢î;N-xœZ¼L¤v³¡»ÙÖ%¾4©h<,z¾¥™äut¼×
-Ÿ6ô’fŽ&û@d !{A¹I1ùO!&Ó
-²>Ÿ2˜ÄáÎG9ü)¿²ÁrÔ™½ã7àã~€ª;'è¼UðB4²nÃÑ2–'ÁN;ú3Þ*ü?ÚªŠª•YZêð€rõ\¾ÄE^í…
-¶ÍÍ^f"|-Ô—0zp™=Ÿ?¬†3©­ÒŠI®åÍØ^fSi Ó¿ŒËX9\+ÒGêý:ƒÑZ0)-Ø ºÈÙ"{Kšž‡ã$¾6Ï_Ôr i;B]œ°ž¤ïQ¥åþ_"ÑÔendstream
+1534 0 obj <<
+/Length 3198
+/Filter /FlateDecode
+>>
+stream
+xÚÍË’ã¶ñ>_¡K*šªŒ7ÍiýØd}p{o¶«Â‘8#ÖJ¤,R;ž|}ºÑ
+ŸiÇð€ÏͶz¬Ïpª ¹!åTE€O ³êÀí(NoÇjÂxUßkqä9êE.îF¿šØœY¨÷Úm†]Ì¥ÑÖô¡3Τâ*ÐÌ­ƒŽ‘¯f|À8£<e\€Ú¢™'° )Ä
+=XdJdßPÞÙUÕ‰…š‚I zcèåöiBG{ü)ÍGŠvŒéù©šï3bHô!Õ?V/X#
+q@ÏÉÉ
+»[ƒbä]Ža «”ç±|4šÄ­¸0^áZ×ÆJ}Èõû^¸áràj/+ì´næ«Ý¢Â‡bÚ†=ßLdNŸAo4V”3‘SY’Q@÷Å Ô bœQf¢»‡Ê´pû‰“<r[Uœ+üx[-ÈF!âuQç¸RÔ·¬Á5p!‹k rac´ </ÚuY7'‘LyVx[ìa_ËÆÙe.šIHÌ•çöƒ¸e÷L†x&µþ¶» Æa—»~K[•ÚLŸ—u8`€áç:ìíÂ`Ø7†‘¸1©ãღ#h¾ýá'G2ÞÐØ#ÆCìT¿—ëYnË“¶'‘Rg JBº+–Œñ…õU׳ýzñ
+ÖgM± q^Pב"Ü*ïJ¬}9ÊôÅ9u•½Ma®¨«„¬ÖbP„sÉ dKFè±2dw£CF:ñPïBFã!¤C‘Ÿ·(9˜p@Ê@èë‹òˆq6F™‰xT¨âTD_ZÈœW¡¸8öõëýGz<i=Ô°…¼¦BNƒñø¸ˆ=º†s/ÞÎß0^pw$Vóz]®®;¼¿‡ä‚6žq)^i·¥‘ºé«' Ìaüs¹Ú…ÞðøÉþð…`¤1ô¦«6å¶ì ÞÆÚ×åüÜ/Rü‹ý‘êb:ÅÅ#¡.³©k @;“‚®*kÌÌkå7V°
+*3ëÛk
endobj
-1164 0 obj <<
+1533 0 obj <<
/Type /Page
-/Contents 1165 0 R
-/Resources 1163 0 R
+/Contents 1534 0 R
+/Resources 1532 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
-/Annots [ 1171 0 R ]
+/Parent 1520 0 R
+/Annots [ 1540 0 R ]
>> endobj
-1171 0 obj <<
+1540 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
/Rect [356.2946 363.7923 412.5133 376.6291]
/Subtype /Link
/A << /S /GoTo /D (address_match_lists) >>
>> endobj
-1166 0 obj <<
-/D [1164 0 R /XYZ 85.0394 794.5015 null]
+1535 0 obj <<
+/D [1533 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-242 0 obj <<
-/D [1164 0 R /XYZ 85.0394 769.5949 null]
+354 0 obj <<
+/D [1533 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1167 0 obj <<
-/D [1164 0 R /XYZ 85.0394 576.7004 null]
+1536 0 obj <<
+/D [1533 0 R /XYZ 85.0394 576.7004 null]
>> endobj
-246 0 obj <<
-/D [1164 0 R /XYZ 85.0394 479.565 null]
+358 0 obj <<
+/D [1533 0 R /XYZ 85.0394 479.565 null]
>> endobj
-1168 0 obj <<
-/D [1164 0 R /XYZ 85.0394 441.8891 null]
+1537 0 obj <<
+/D [1533 0 R /XYZ 85.0394 441.8891 null]
>> endobj
-1169 0 obj <<
-/D [1164 0 R /XYZ 85.0394 424.9629 null]
+1538 0 obj <<
+/D [1533 0 R /XYZ 85.0394 424.9629 null]
>> endobj
-1170 0 obj <<
-/D [1164 0 R /XYZ 85.0394 413.0077 null]
+1539 0 obj <<
+/D [1533 0 R /XYZ 85.0394 413.0077 null]
>> endobj
-1163 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+1532 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1175 0 obj <<
-/Length 4063
+1544 0 obj <<
+/Length 4062
/Filter /FlateDecode
>>
stream
@@ -4911,3276 +6264,3737 @@ s–Ö*hîžm­™â‰µ
ÚŒ8‹Áµñ.pÃ\bŸ®šîN N!‚š æP³‡yãKΨ ©ÐCËxMU›U×ܯ°ÔùÒ¨0 D¬x/DyHvkͬ”ÚHI0×¥™¿bjïJÚMÿÖÅ º½8‹A¼¤_âÛ5±ŒêmšSØQ-1ØÅÇüͦé¦î²]K×Fm4PÕ]½H©0u?º‡ ŒŒyÏh)ÓánŤ ÷JìøßLŸÁc®ã‡âÃr F×Ѐӟƒs)Ýõçvg»ëR<|×?š_0ÃéÁBm!3Î5¿LñÄ},Øh‚«¶–) '%’¹
ÇÉ} ((º™dàâ^좀Ë*§2¤Ô™üuC{2

-›¬s짼h "”IŒ)%F*<zé“'â¡jÿÿÍ”àxÒ‡BvÉ
+›¬s짼h "”IŒ)%F*<zé“'â¡jÿÿÍ”àxÒ‡BvÉ
endobj
-1174 0 obj <<
+1543 0 obj <<
/Type /Page
-/Contents 1175 0 R
-/Resources 1173 0 R
+/Contents 1544 0 R
+/Resources 1542 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
+/Parent 1520 0 R
>> endobj
-1176 0 obj <<
-/D [1174 0 R /XYZ 56.6929 794.5015 null]
+1545 0 obj <<
+/D [1543 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-250 0 obj <<
-/D [1174 0 R /XYZ 56.6929 165.9801 null]
+362 0 obj <<
+/D [1543 0 R /XYZ 56.6929 165.9801 null]
>> endobj
-1172 0 obj <<
-/D [1174 0 R /XYZ 56.6929 136.242 null]
+1541 0 obj <<
+/D [1543 0 R /XYZ 56.6929 136.242 null]
>> endobj
-254 0 obj <<
-/D [1174 0 R /XYZ 56.6929 136.242 null]
+366 0 obj <<
+/D [1543 0 R /XYZ 56.6929 136.242 null]
>> endobj
-1177 0 obj <<
-/D [1174 0 R /XYZ 56.6929 106.2766 null]
+1546 0 obj <<
+/D [1543 0 R /XYZ 56.6929 106.2766 null]
>> endobj
-1173 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R /F21 714 0 R /F48 953 0 R >>
+1542 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1180 0 obj <<
-/Length 3096
+1549 0 obj <<
+/Length 3065
/Filter /FlateDecode
>>
stream
-xÚ­ZÝsÛ6÷_¡Î=Dn,˜øà×õ)uÖÖÉ%ÎÜÍ4”–`‹cŠTHÊŽçîþ÷ÛÅ.(R¢å~Üèàb±X,v¿%'üä$ E S3‰S#Â@†“ùê(˜ÜBß÷G’yfžiÖçúöêèôµŽ'©H#M®nz²$‰œ\-~™žýðêíÕù»ã™
-ƒi$ŽgaL¿½¸üŽ()=ÎÞ\¾¾øþûWDZ™^]¼¹$ò»ó×çïÎ/ÏÎáDÃxÉžðúâ§sjÿtþóùåÕûã_¯~<:¿êÓ_° 4®äóÑ/¿“¬ûÇ£@è4 'ð™¦j²:2¡¡ÑÚSŠ£÷GÿèözÝÐ1†:a¢â Ù³  ”Hc%'q˜ŠH+íLxggQ`ãS¾ öè‘Í‹Oe¶²⿹o±¨mÓ|Zeí|ù©È›–èÿ¥ÇÇ ”hÓת¯ÃLÆ"Õ¨«s±r: å¥PÇ3ÀÐïìÇ PeÞæUIæÎÊ5>4Ù­e±ª'6˜@7X(4NÞ+ÐíX&SÐÆÅzꔤ&jê¨jšÑ×u¾Êê¼x¤×McÔj+z.lkëU^Z<ŸwâçUÙ:YUA„›ª¦Æ=ˆ¬6<_cë{ËÕÚÖ®°ŸÓq:½ZÂFÀÊp-RŠ4 É6=%aÒ¢©¨µ9–SVQMó’žíÒŽØ<IÀ³"p!'×o˘vߌF‹ cæD«ïK“©c#™§©êÖíý¾0m„Ò‰Ö´YkW¶li½!®—”¶Ñéía™ÓNI´jÓæí¦õ‹çUfÃÝU¼»h»™„”I¼ e·fr yÆ.um½k=R£º¡g»äž›ª(ª‡¼¼ýûSQ™*Ž§µ>— JizVJ¡™èž,Ô÷c ãÝIaU0Èćgí¸ö§lŽ  m¢á´Þ6oÙ6C‡.¨ƒ‹·÷†-V{öûȇû¨™T,b&Ϙ©ÇuÀLžëy3šµg¦ÝiÇÍÔŸv×Lk2&­/[;åÌõÛé j”Uëþ ©`>“êôSõ¸˜Ês=oªC³öLµ;í¸©úÓf´twÆ8“}w®Åµ \o9¿_?nƒp$õ@î1FúÜsG sWrX¢wÓÎSS8xB˜æ Åû\O[¼ãzÖâgÝZ|oÚQ‹¦íÒÛýÌæýv/¬ýéÍm¦ÜÙ™‡¼]Ú¥ŒHbú³c^ŒíM(”TÉïÞ›Î#†Qö¦Çu`o<×ó{shÖÞÞìN;¾7ýi9J 'ðâì…-çEÕø1>³\×@:÷ÀúiEx
-e$EßùödÕš>h¸£O+Ðã6#E€Èû ­Œ…ÍpøÑ‹ý2/²UƈLã‘[ßQæºß¾zY c[GŒÖ ‹|Qoá—Ö~QÐBmHÚGð8ˆñádÄŽRV¥%Ò
-ÀQâÏŠæædXDùC=™(L„6Aô;Jn)B-=öÝÝØÎ`ƒ,ÐKØÀâq9cÁUµV"ƒd¸§œ “û„2®köÒ-І·$@ða¼=àÈŸma ž>íH,ǽøN¬ñë ;OŒ_Ø2·ÝøÙX¸ PÌÛ*<«Lºzõ‘SVôîäŸP»SªÇç&E\¡ƒÔË·ÍŒ6R‘ñ(—<ƒÂ1¿+uÂÊ¡8î¶{_ Â8 Òj<I›|ÔMc)àÌŠžhÆ’I!’‘£†¦ eÌaÜăù>ol=j¢DÉç„%ûÂÆc6„JÂäÏÈ›góåØ5e¢EFZ⸞iõvšþ1©pŽ”Í ¸ö¾¼È™$PKÚzeHËpxºnÖ~§+sÐÝB‘èáî“°ä^lóЭð0ÞúÐÑ×™*ÄÅxë]R¸[Vض&i¥[m0Q¤S‡›5dˆ`Á€AÓ]:#tÑô}¾Ê‹¬!¥ôÊ=qá‘D"Nõﹺ©…D“ÃÎWPS=@„ÖœÑ>4¹F‹¶—ÓH¬èÉ8 cF_¤
-/^,Ý "áfGä*Cða_ð€ž¼ Û ÍÏ ÙŽ]Ñ?U/¡=FÑÆñb1œ±°H71·eŽç< o¬¼à!«m)#
-§ßZöa§Ú Ÿ<A¤»–³¾6^“™79®í2»Ï«È3tÁ®íΠ/Zëî^Œefôh6×e^çnØ®L
-K徃ÿ° $V >)J¹•š·U †XÑ+gP©ºä„<.ÿÁ¨¢ªî6k"ÒÀ=½\b•j?¡ÉY©K- Ýtú¡¯BdÁ¹Ô]¼~EÜ[SΔJ¶‚G`N,’T›^°~qÙYÆìô
-œ…ËãkЈºÜE=<1z\y íþR8J«ùƒá=v6lLžá|â?Û‘$qºãçþÊ"ó7Õ¶€¡Ù¾¦¼™ñ5mÇÜ»üá:ù®~Ó‘lç?BûOÐgÕj[½Ç®/Ïuæ/šÆÿ&å[ªN¼4$Ž.–|Môî›1s7ý;(ƒw6cp¹‡^]ûü„-8R[Û¬éÆÃ}ú~Ü`ö®ATw?Å^}hÍñkU n7µ¿úç"ÞƒèHN¯ŽS<~\‡›  ‘Nkx²ãÜÖ¬©nˆèò (˜û.‡êþ„¾ú¶KwKÝt·ÝîÆžŠ­ebÎêKáì„Ÿ/_žP^ªê± k–¶(N׶î®Rq9£õ½,nÿ£ „déû„‘OûÄ©Ó€¿±Î¤ˆ&oûÚuxë÷:®Üq…¡ðÏŒ´-ØêÜÉõzî’žg$8%‡wçdezôSþ†¤B„b©ÓS’û—õzùrìŠñoÿéØYqûÃåÅ¿¨å¶ÚË+ù¿-nçŸøâ¤C¶ùòt{õ—ÿÓ³ýt%…N5þ ICbOT{¥ÐZ*ÝÕ¼ûóϾêÿ®4~»endstream
+xÚ¥ZÝsÛ6÷_¡>En,˜ø ^ŸR×iÝi“\âÎ=4”–`‹cŠTHÊŽ§wÿûíb’’(¹£
+éLxoŸNgIaåS¾ ú©Èæŧ2[Ù-â¾o±¨mÓ|Zeí|ù©È›–èÿ£âcs´Îùk1ÔaÆ5K%êª@iÎS§Zž3q:ã ýÎ~Œ"Qæm^•dî¬\På—&»³^¬ˆ&3‘0såä½ÝN¹™‚~0NË©S’ª¨©£ŠiFLD_×ù*«ó≚›Æ.¨ÖVT.lkëU^Z?x>ïÄÏ«²u²ª‚·UM•Ymü|­¬ï¨Ö¶Îp… øœÔéôz +õpÎÒ8n-%aÒ¢©¨¶9åS¯¢˜æ%•íÒŽØÜð¬\ÈÉÃõÛr¦Ý7£’,Jcí9ÑêûÒxÊb­¸çiªºu{¿/L*&¤ š6kíÊ–-­7Æõ’Ò¶ :µ—9íG«6mÞnÚ°x¿Êl{w…ß]´ÝŒÃ ä‘2Á†¼[39Ð<ó.ucƒk=Q¥º¥²]úžÛª(ªÇ¼¼ûסSž(ÎtªÓãamÈå%8io¥ªFd¡¾#®w'…UÁ ¥ÏÚqíO»µ9<‚ºJ¶§ ¶¹zçm³eèØêèê݃ò«ûCŽû¨™„`FjñŒ™\G̸ž7Ó±YfÚvÜLÃiwÍ´&#aÐúÒÛ)÷\¿Ÿ¿ JYµîÀ5U$™ÑÉ3å눩×ó¦:6ëÀT»ÓŽ›j8mFKwwŒ3ÙwgÞµ¼G-(Ö[ßožúC8z ö(ÅC칧€¹«G
+1ÌÈÝ°sÈâ±åñØ·øë°Å;®g-~tÖÞâ{ÓŽZ|kÚ.|ѽ=ŒlÁo÷Žu¸¡ÚGÊyÌÛå±½BÁ¶«8Üóblob&¸0zo’˜bøñ½pÙ›ÀõüÞ›u°7»ÓŽïÍpZJ 7ðâ¯ì…-çEÕ„1!²ÜÔ@º÷Àúi”$x‚ùÂe³Jé¯>¨¸«O
+Ðã.#E€è÷j…ÍpùQÃ~™Ù*óˆLâ•[ßSƺ߿zQ ϶L<Zƒ.òEÙÃ/)â †Ú´à=pcádhG)«Òi ù-„Ž¢šgŲjZ?P ?¹LyÏPÚ¶Á‘;8… ¹;Wh¢A³Ÿ«ž Í h.¬G…²…©½ ¿¬:3cåÆ÷ÝV› SÞ´cPoa›y¯{Ü»‡IðX¹JwvX'Èm¼v‚[Å ºW£/.â’—“)ìî¦ñÄU¶°;|!– tå Õš§²Íæm>§1Íù¾jeÓyÑ`pF¬«¼)¡Æ$Ë] fÚäå|Ô4oê¼õàôvÐOy§ÖÞ©¸]u¸ý!+òEF RmÁvôùjÓRƒ¶üŽücGDFºux¾õX¹“€¢ÃYFhî`®áÓ7àÄ`Ç&=·µ˜\xô€§á™¸@í¢A<"/¼slºPÑ.)-ÙÜù…iQÍ7¸WεGýè?K‹æ5d(îrXÛC :
+"è1þ(¹q$1o*?¾Íî­¹. Púù˱`’­IÓê 䀭ÅP
+>}‹±;¼æÚm¾²øB Äô‡êÑ>t®+eJgIŠh HCÃhŸ7yUPÖ2kCÍ“(4b 
+Š"?GÊMVg0­Û_lnJØuªfcÞålæÏß
+ –^P‘p»#r•!ø°/ü€‚ŒðÚ Õ…Ÿ¢Uº¤QïçKý³î(ÚxK žÀöÀBà ‹ xÃx€ !é¸+s¼ç!™
+¬_²Õº°n–Ô§X;‘LjÉRÓaXΓçB}ƒY™š~E•qùÍX|ë$Œ¤Ï\tc©ÕƒZN‰
+覷=èv/P>ÂQl­'æ^r) \œùòåË3ŠKU=ú”¸´Eq¾¶u÷”ú„ËÍïe‚€=éýƒqï!C§Pü°Sœ;bH›4†.¦•¤ÿ(|í:‚bƒŽkw_á(B™QAû‚µÎŸ\oà.©¼ ÁÒ¡ÈÁÁÝ9½2ú¹ÿˆ¥L
endobj
-1179 0 obj <<
+1548 0 obj <<
/Type /Page
-/Contents 1180 0 R
-/Resources 1178 0 R
+/Contents 1549 0 R
+/Resources 1547 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
+/Parent 1520 0 R
>> endobj
-1181 0 obj <<
-/D [1179 0 R /XYZ 85.0394 794.5015 null]
+1550 0 obj <<
+/D [1548 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-258 0 obj <<
-/D [1179 0 R /XYZ 85.0394 731.767 null]
+370 0 obj <<
+/D [1548 0 R /XYZ 85.0394 730.0812 null]
>> endobj
-1182 0 obj <<
-/D [1179 0 R /XYZ 85.0394 703.7216 null]
+1551 0 obj <<
+/D [1548 0 R /XYZ 85.0394 700.9798 null]
>> endobj
-262 0 obj <<
-/D [1179 0 R /XYZ 85.0394 229.6467 null]
+374 0 obj <<
+/D [1548 0 R /XYZ 85.0394 216.5924 null]
>> endobj
-1183 0 obj <<
-/D [1179 0 R /XYZ 85.0394 201.8883 null]
+1552 0 obj <<
+/D [1548 0 R /XYZ 85.0394 187.7778 null]
>> endobj
-266 0 obj <<
-/D [1179 0 R /XYZ 85.0394 144.1965 null]
+378 0 obj <<
+/D [1548 0 R /XYZ 85.0394 127.6814 null]
>> endobj
-1184 0 obj <<
-/D [1179 0 R /XYZ 85.0394 118.9605 null]
+1553 0 obj <<
+/D [1548 0 R /XYZ 85.0394 101.3894 null]
>> endobj
-1178 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F21 714 0 R /F22 737 0 R /F14 740 0 R /F39 899 0 R >>
+1547 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F21 930 0 R /F22 953 0 R /F14 956 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1188 0 obj <<
-/Length 2472
+1556 0 obj <<
+/Length 2310
/Filter /FlateDecode
>>
stream
-xÚ½koã6ò{~…~¨½>õh?ew“4Åí¶Í¦8Ú§È\[¨,¹’œ4ýõ7ä•(6¹"@ÄÇp8œ÷ŒÙŒÂ›©ˆD)Ogq*‰¢LÍòí­aïì€9˜¥Z†Po/ŽNE<KIñhvù9À•š$lv¹úyN€Îß}ÿñôü짋ãE,ç—çß\,¹¢óÓóàèìâøÇã‹Å’%ŠÍß}{üÃåÉnEÇÛóïq%ÅÏH/NNO.N>¾;YüzùÝÁÉeÿ–ð½Œ
-óß~þ•ÎVðìï(i¢f70¡„¥)Ÿm¤DI!üJyðéàÇa°kNòQÂEÄ'ÈÙUJ"Á…c rà
-¥tþ^ÿB)¯Š®¨+|jV­pðS›­µy/`åV:[rIRɤÅ÷®ÞnuÕµxh›Ý:4»Îòöf£›KæWºMÖáèfStºÝe¹~AáiÃÏ µ¼® ýë}“ /0+¥&†tC,‹I*x‚Ä.Û«„àpØS.„˜·]Öt¸qSt\ì6¶»©q%ßdM–wºiqãè ®ÿBmˬÝÂ\!:Xce™jÀ4Â;ÞáŠÅ
-Œ4žgžÑfoÜ•ºÓ¥Û\é²ØÇW8uTÐÈœoý™þ‰† _°y>Ï*\9p ÈaëêþRÃXœÔ•¿;ÃÏ®nPVv÷³ß½‰Û7•Eå´¢vŠ`n0_P'ìí¾ìŠ]éà̉öŽäã±äùHò\0ó¢ªîpçÊA
-ðö‰rü´û„V5~˺Zƒ³uDûGÜNPé€8ÿjî„‚%ç1a2HÄS’$qŠ¶öÕW½µÉ4´6˜9%1C§Á0B 6ãgí¡ÀÏšùÑ~C?kÑy‰SŒ^öR°©jïÑÖwîÑΨÕhg·¹m—S–WäYiüad½ŒñÈ"1X¿‹Þ‹˜±ufͱÂi–[#¯Ûçƒï23sñøŽöGý*¬m²k[WnPÖëáÌàwab]䄹M8ÌCë,ß «Þ½zw‚^+ô6V$ÊØhaƒ–ñ–Œ:oið¡·|Ž:Bí|™oY2nqhoŒ¸ö9¬ð×ö¦îÞŒ0âL_ëÊUï×w¶ãp˜7¡BþÂG¼Ú®Ñ×E½oï›ëDØܧ.ËÐꌡxIìtãöœÕNëo뽃ÀðóY7ƒ-=e·½.„æ:!lH!ˆŒÀPKéI
-ÞÍ'ŸÈŸ¿£÷±cÅ?«ö<¼õÓú/^ ôSµ–H"¢€£Ï*¶'iªät±„&œÄ)•ãÂsp¹¡?1F5µ1’„ªd¨ÉxŸi€
-Dœˆ˜E3 ÀÇ•eÑ¿›P¨
- Jv€‚ûeL¨ÀGþgÁ$<Ž¤C¼4c[$V!8hõ¶ÈëÒ” fj\¿ù½€Œ©õ7 0:ô9x¶vGM £¹Cž¹û|p´0{êìn‹ßÛ·´M„‰sQ½/MWÒúSœe8ýsÁ”‹Ç0ÃÚÓ,™!fh—f'x‘9]T+°(}q·ó`X €­Œ`Á]3TºöÙ®‚ÂB³Ó“ ˤÉ(%<I“™SÓôåšol ìTèY¼Ì.ÇÆ$i,ÓDȈ‡I õ-"×Ýx7Õ8-|òsÖdÛmÖ<\Å©ðÆÇÁÊ\ßF)~î·"aÛ¢µa@lœ¯“§‘ë Ž!ŠÈxþéœöp.蚣£W¨ð䃊`£¸òÑS‚»zf₺r¥»éRЮ{c°Ø2Ü ðÝJë½…0úœ—u‹µ1ì]A– í[i:ÿ`˳pg‚~é³;= «²Î‡òvµöý%ŸÕfa*+[Ÿèf[T™í‰ŒëjwUÀè‰ÆÂ¥O Â.€¢cß½½ÝïLD¯¾¾kŸ øKÏXœFUô[)Ø^léï
-"#°ÿXKóžð'î³{Ò’)pJL7+SAD"ÀºcJb¼ÍòrÂ8M èŒ]`\aÓ:Ò(µîâC•mmÕ+ç?àR¶Z¡ZºÍº|cåe¶K°YÓïJSdãå9BǶÕØaùVNéhß6­»nú’©½ï€A²
-ªîYÈŽ—1؈R±((z>Jâ!™IA¸¤ì ™Éˆ$<Š{kmê²}†äòÒYEÛ·s{ã²]¶ãîß•îùë˜~u;dóxmH&K©)@|*ÕT«|‚8¨RÒHxâö]QÝí‚16D†{^Æðÿ§ ƒ/Ó'd($Ib†©Z^{¿ÒOŠÐÁµ#ôߧ™ÐóZL{}gEcÈÓeôӌҰ³„ßôí“ kw:/ ƒ,Ï"j× $¯Àílû<‚¢2;Øy‰\
-ßlzÅoÞg5¾ñå6ëåTÛiоíCÕå§ó³GÄpâµüÈ×Wib$ùãÒJ¡b¡þ´P¯×æýM^"†|Âæ>0rÝûòƒæÚº|X¼6ó¾Qa ¿} ç,,"ØB1¿µ±y‹ >W˜ˆ3ídRïe°áuEõŠ–¥€V%žðF±"4UPÊ›F?MÂÉF”ûq@¦$Š"ßfÂá>ZðƒQ,m½šLÀ¦‹60¿
+xÚ½koã6ò{~…~8{3|èÙ~Êf“\ŠÛ´—õâîÐ8EæÆBeɵäMÓ_3R¢låÑf{ñ1ç=c1áð'&aÄ¢T¦“8 XÈE8É×G|r{—GÂÂÌÐ܇z»8:¹Pñ$ei$£ÉⓇ+a<IÄd±üq1Éf€OϾ¿¾¸ºüxs:‹ƒéâêûëÙ\†|zqõs]Þœ¾z3›‹$Ó³¿Ÿþ°8¿¡­Èâx{uýŽVRú<‚ôæüâüæüúì|öó⻣óE÷ÿ½‚+|ȯG?þÌ'KxöwGœ©4 '÷0áL¤©œ¬‚P±0PÊ­”GŽþÙ!ôvÍÑQþ ΤŠä1ÆÀ0e‘’Ê0ð«Ù<â|ºX Ü7£±Gy½^몵»ºê7k;þx}õo5+]– 2 ( ÁÒ0”þµYµ¤ÁFoK„;¹>ÉpJ)&D'mò– BgÞéŸ8—UÑx3ÊÅ ÃÁÇ&»ÓŸâ“K|gô¤†­³‹f³ÑÙÖ¡|¸_éíL$SM+í*kit¿*ZÝl²\? p´Ñ§W±¼®þ»Ý6ë_€+¥fËb–*™±ó¦}(á*¥¤Fƒ35mÚlÛÒÆ}Ñ®h±]YØö¾¦•|•m³¼ÕÛ†6NÞÐúO<äM™5«c˜‡„ÖA¦"˜¦Ç›Z1àš‰C‚ ÚV˜Lßê<Û5z¨ $V §x<Í£qoÜ”ºÕ¥Ý\ê²XÇ—4µTðÏ7îL÷D$CÂãgbڡϳŠ·²ØÚº»”´'uåîÎ賩·$+³ûÉí(xYTV+j«x~Aa¬°×»²-6¥…ÃÍžäã¡äå@òR |QU·´sk!
+LHE(ãÍã{¦˜…“«µš¼«á‰ï•ïÜClùÖœdC¶ïŽùøÿÌD
+̽·%1SA$ýfŒ)‹Eœ¸n–ímœ5.
+—ú\n³õ:Û>ZÅÖ:Áö$™í:À(¥Ïaó!R¸Ø š
+Œ[†,Šñ6ËËãgÛ¸¸¤þ¥q¤QjÜ%ć*[›š V®~ ¥l¹$4tµùÊÈ ·K°Yìv¥)Hrk‘å9AǦÑØRñVŽéh×4­Û•ÞvSsè€ãsqÏŽ×ñ%Š(î z9Jwâ‘AQ”<#2òqh›†M5µ«Ÿ‘[^Z›hºVnÇaZXAŽ ËfØù»Õw-ËoúLþ°û-RŽÅ‡Ë£¶Õ2!*”ÕŽ€vmQíÃL1}\‚w^Çî¿P‚ DC!¢§%˜@ôLÛä
+ós.ÔÓ‹c–Šš¿è‡g¹Õlt^ w Ã"nË ¯Àݬ»ü“÷Áê·D¶î„o¶ ‡’7ï²×î²›õhøß¿{éÏ®éBÔâÃÕåã²òøð:Æ`[‰â È*bI”¨±ßßøäYÕé¯}}öÄ ­Dú…˜gñq‚¨!.dU JN÷³ …òHÿ’ Q>endstream
endobj
-1187 0 obj <<
+1555 0 obj <<
/Type /Page
-/Contents 1188 0 R
-/Resources 1186 0 R
+/Contents 1556 0 R
+/Resources 1554 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1158 0 R
+/Parent 1562 0 R
>> endobj
-1185 0 obj <<
-/Type /XObject
-/Subtype /Form
-/FormType 1
-/PTEX.FileName (/usr/local/share/db2latex/xsl/figures/warning.pdf)
-/PTEX.PageNumber 1
-/Matrix [1.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000]
-/BBox [0.00000000 0.00000000 31.00000000 31.00000000]
-/Resources <<
-/ProcSet [ /PDF ]
->>
-/Length 557
-/Filter [/FlateDecode]
->>
-stream
-xÚm”In1 EOPw¨u€$ÅIg0²Êľÿ6¤¤êV5 oʯÅésÀóή¯ƒÖ×O²Î Ž¢‘ÿ¨#h8Çùø:„5?ùÆ [ÄIÚL’~”F Ø PÈùYÌÀ¹dˆÐzZ8å±Ýƒ²ÙËò‘–Œ€f¾Å(ÌÀE#@x˜oL Û¹[ƒ±ñðù
-6\>RgÈbÏWÖ¹j[†›
-WŒÏ¢®{6;»²þFÃÇñ÷ø]š¨)Õ/Ô¬Mu;pk;Ì©Ëdh<åE–ñ¬AÏw³ð¬±±Nê¦ó¡Ä½t•‹ùD„™Â²]°Ä(‡;„ ·åŽ°Š­r²ÂÙÄLûˆ T¥Í¡誋ŠŽt’¹w_ =Î]ˆ‹=¦uSä÷—ä"ï±yl±‡µÃ-ËkHsŠöreOÚ³êvg›<7ºt,‡Ýe—;ãÒèЭ/I…B÷&ê(ýê³ö󻉨YÙ¹Ç,çkRÔšÚ'^ m" ^˜h±ÎW9AVªy­Â©/fýÆ"•œãûFy-Sng \Çdª¼˜©Æ¥†Í}B©•µŒÎ$âw1.¶&Øíþ²C¶O–ÃVç X×9g¹E{îÇ< •ãóP)!ÍZÜÅŸLÞª~ÑÔ'¯UâXLµüc“ÅXsЖõÚ¯½˜Ó’~òBL–§èªÆ¹O¦ºNZ_[Èü.øšŠû*]3QôçÇñ!Ö-žendstream
-endobj
-1189 0 obj <<
-/D [1187 0 R /XYZ 56.6929 794.5015 null]
+1557 0 obj <<
+/D [1555 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-270 0 obj <<
-/D [1187 0 R /XYZ 56.6929 769.5949 null]
+382 0 obj <<
+/D [1555 0 R /XYZ 56.6929 730.9277 null]
>> endobj
-1190 0 obj <<
-/D [1187 0 R /XYZ 56.6929 749.9737 null]
+1558 0 obj <<
+/D [1555 0 R /XYZ 56.6929 704.9004 null]
>> endobj
-274 0 obj <<
-/D [1187 0 R /XYZ 56.6929 282.0726 null]
+386 0 obj <<
+/D [1555 0 R /XYZ 56.6929 236.9993 null]
>> endobj
-1191 0 obj <<
-/D [1187 0 R /XYZ 56.6929 250.2286 null]
+1559 0 obj <<
+/D [1555 0 R /XYZ 56.6929 205.1553 null]
>> endobj
-1192 0 obj <<
-/D [1187 0 R /XYZ 56.6929 191.4593 null]
+1560 0 obj <<
+/D [1555 0 R /XYZ 56.6929 146.386 null]
>> endobj
-1193 0 obj <<
-/D [1187 0 R /XYZ 56.6929 179.5041 null]
+1561 0 obj <<
+/D [1555 0 R /XYZ 56.6929 134.4308 null]
>> endobj
-1186 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F62 1062 0 R >>
-/XObject << /Im3 1185 0 R >>
+1554 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F21 930 0 R /F22 953 0 R /F62 1352 0 R >>
+/XObject << /Im3 1500 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1196 0 obj <<
-/Length 2134
+1565 0 obj <<
+/Length 2383
/Filter /FlateDecode
>>
stream
-xÚÍYMsã6½ûWè¶òVˆàƒˆääx<§fœÄvN“©)Z¢$f(Ò+RV¼»ùïÛ$ʦ,;ÖTmù  4¯×´pøƒ4a\Ùx`lÌ.’Áh~ÄS{w$üœ(LŠº³~¸>úö­2ˬ–zp=éèJOS1¸žþxòËõÙåq$>Ôì8J4þp~ñ†$–~N¾x{þî·Ë“c¯Ï¾ ñåÙ۳˳‹Ó³ãH¤‰€õÒkرàíùû3j½»<ùðáäòøÓõOGg×ë³tÏ+¸Âƒüëèã'>ñ:âLÙ4¬ Ã™°VæGq¢X+$åÑÕѯk…Q·´¿X*&¥Uƒ(á,b÷®´‡]}VZ´s{ÓHˆ„©D¡Kâ˜qË7.‘¢ã!3Ò&“X¦•TÎ'ó¬ióEƒØÀ|ÙÏS&bƒûàÄqþ;ç²Ê›ãH™d˜áO<¬²y>&IÐä:eÑ´4cR/HTT£rÙuº4޴˯²òšš2»ËÑ"ØŽÇl’Hgÿë*'—®7ÃΨ̖MÞ°‡N¸a©ábÐæu`++Y"´DaÂ!ý'afÊå>ÿ©Â:HêÛ }†ÿFuÕ.ŽE:¬K„ͦÃiYßd%¶í°Éwù‚ä0]=].²Ö¹ '„}Ü ç)l4yÛÐø8Ÿd˲m¶ÝF÷Þ…
-üÍ©^ÔW½2:™Àö€¯­ei¢cBÒS1j¢Ñ,«ª¼|Vúƒ,ã@Ä ˜h N˜Ï—U1ò.p¢ ÎõÚš~§yKl4Ê7hpöìÚ+cÁ¸„ÌL{Rr}lZ´ž·uÍ6çÚíÕ.^ÿÇWJ -»ïNi“0k:~»X›0Ž¾ä÷/{Îð2@jL‡n=õß\\]R>hÇÔC]”¯¨ºÁcµQ Þ¶œÞ–»"_½IŸqÜZ+‡O
-Á‰‰`% ¤â"pT’¾«`¯ŸÙ|žyºwÏËñ-‚,`§@“¦_/êýÇ‘ÂðŽl1úl<^À›øyžµ£ÙgW5àÜèÁdÊð}ßw0°!†ÈÑþîáäž½¡›WlÈ1ZhüÖdÓ¾»ûऻCI¤!”p÷ž$
-¶.5 ³J·ñEÝ”xfV J;€P²e xcp ù‡ (/¯ãÆKBΓxU´³>gRfù:Ñï A‡p“c•„ÖÑF…ßx¬' 4?& Í|5#fŸ¥³Vµ¿?‚Õˆn-VDb}´Óډ׉%¼EÁ×)Ëz•{ñÆ{à&Mjœ…™ÓuÑI=ªn–EÙFEõÝÃNˆ˜c$dYÈGJ<ï5‚ª^óÒרoU°ƒ”|ù3E
-¨Ž0 vr‘(¯‚bFKŸK«ûž ±
-è{¡ÀkŸ•þ¾ÌꦷªFæ
-‚*oWõâ uŠªÍ“ Ž†Uß'¥6ä抶ùžë@òÚ‚7xèF*ùKjè°b§ç¤Ñ,NíÞhXð
-³q]•·Íó]'lì 4”‹y! ¢!!§º‘ý’Oqlí/OÂøjVàSŠœkPF®éûŽ;ËйBwrãwF߯jÇD`)ihÚ¸&aU·Ô¸%¢páRŒýŠŒ~VŽDC£…A¿nœÃ6ó¢êý¸L!%c¯Ô=ô’¤Ì+P2mg õ]£=@MôÐÚ
-zGºÄð¼¢±féØ$+A0Êšü›Þ/A†ià’ëªd·«£õÜ­²©æÝ„·¾8ÁvhzÛ·ùZÞ|C²? "Æö¥õJ,Neªº¶îÈ(1§ï54s÷­í^‡×]±Í­}I™{xb! æ‰Lð?@ npúÌ2W*°ß¨­”Þ)~Âÿ°D
-Utb75ò%ûìOŸü_XØ)°3ñdd£eSϸu‰>Ò ¸b-µ±{Ùíg^®ó_R!KLŒ™™X%NÅ?ý)í é§Õ~—ÛzÑ®uo:Ÿ| Š„4 Éy_µIk1´u$÷=1¨ÁøµØƒ¢ÔïêTà Oõö]|„
-clkïEqYú“fPgP µªåü&÷pÖ«*4»âé¢^Þ>¿èDûL{x_¤}¥{ß_UÂb
-€öÒÊçþgvóokp±JÓ_Ö×Î…–+ñ(K©”%©4=¦ÿüÑU&endstream
+xÚÍZ_sÛ6÷§ÐÛÉ7  }r'çNâö÷)Ídh‰–x¡HŸHÅõÝõ»ß.¤(‡’ìF7“ñ°Xì.v YŒ8ü‰‘3Œ+¯GÖkf¸0£éò„æ0öúDÄ9“vÒ¤?ëÇë“¿½Rvä™Od2º¾íñrŒ;'F׳÷ã?ûåúüêt" 'ìtb>þñâò%Q<}^ü|ùêâõ¯Wg§V¯/~¾$òÕù«ó«óËç§ጀõ2rرàÕÅ›sj½¾:{ûöìêôÃõO'ç×ÝYúç\áAþuòþÍàØ?p¦¼3£{èp&¼—£å‰6Š­TK)NÞü£cØ K‡ô§¥bRz5šδ»w¥8ì›°Ò£œÛ›N„0L…&ÑšqÏ7&‘¢g!³Ò›‘5ž%Jª`“¢šÏórŽºù²?Ÿ;&´Å}pb}—Móß8—Y ZUv|¿Hj5‹ n\g«ÏÙŠˆÀ¸þššÓrÖ.QáÆÙÖº0—,³S1®ëtN›¸qçƒx œ•yc$ ”• {lSÃ-s–‹Q__§_å%3"±£I;á˜&“0ÓqyÈdÊ@Cx2Ùý
+ÔsÐ`ÓªDsÍפÂvEŸ¿GH”é2› ðUš%VÅIMu:Q‰§E- Ö6‘TÇ/Ñ‹|¾h&÷~h
+RÁI2K³I°íÄi¦B\!SÀXV%Ýà߸áòKÃœ–>Šô2x
+F'ÏVMšÇÐ÷¥‰P»‰°‰)}î(ÇN:;í&­ó}ÚïëëTõÿ½4*aÚëCÊ7pq¤Tð=ˆOù´žLiYfÅ“â„™6kÄLÀËåºÌ§ÑÔ² =L‹øg 5Òé4«Ã ÅÁÜ¥ãRªÉwÒÍÛ?ݹöXu£®oùJI¨#”;”É &’FY­!'Ì&Ÿ²‡ç¥3¼ Ý8¬§þËËwïÎ_PîQhOÔoùšpÎ@]s‹H˜°\ElPè~ªF1å£6mO{Ví¯Rn2êÊîj­ïh„fp@€MF
+LçG« %´œ.Ú¼³„ÀÙd%²=†ìiè¾Æ9DÞ‡²¤ñ”m>çÙý³¯DÌa­—ãÝŠëKt¬Ðþc*Î&Ì
+w¨ª26áÚm
+¿oÊ2(3Ûʱì /eºúv7Ȇl기-Zë@mwZ4V´­étÝ¢aGt6„ëX'YÙnÑ¥%ƒŠ\Z&§BŸ¾ ,
+αú.ˆß»V øæµJ—Ë4ÂNÝ?/GLÁ¼¤àÀ !ND!ÔûO´mÔÛ·³ÚõÇeÚLCùJøG“©„ÿ㇡ƒ <'‰( $è%ݼ|‚©4Ưø`4`±G'ÝíJµ®„»P~¢ücÓãëÔ²uÏסVÆOý°¼©Š|J=Ò*¶BÖÃieü‚* g†õÉ8è”ÆP± ªdîÆq«9•ÐÊÛƆ÷-•|Ë-AîV9xÁu r&K)ͤ“nÛ¬ÕmTë–LÁµI&Ã)ñB >>‹7¼Ùn*N"¼‰!¾Ýœ½xSwï.!}C]«¤ _V”õ„'E¥’  ¤l ƒQCaþɤ¤.×uäq)mÌžù>oCxÜ:(µ»@¿ÃpZÝÆ€› Ë]zÏÄò¸ñ´•ž$HPñ3¢@Áu¯ ?àˆ—U¼?œÅõ=#ÑÛiímä¥ÍEÝÓ*vŠ¢ºÏfƒú¾^ÄI·Î"Ô]4Ò
+ÿ ¡ 6k „ÌjE¥Õ_ã1í è§Õq—»jÕt¼7[غã˶§˜ÉùP J E.z—Œëñ„¸{P¢öe°t^¼_GŒ±þ²¡ÿ+’]ÓSÙc_ᣃØë©ÿs²ù‡ÐrnÇÛJçœQ(<“V_\eðHã¤ý|[moendstream
endobj
-1195 0 obj <<
+1564 0 obj <<
/Type /Page
-/Contents 1196 0 R
-/Resources 1194 0 R
+/Contents 1565 0 R
+/Resources 1563 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1203 0 R
+/Parent 1562 0 R
>> endobj
-1197 0 obj <<
-/D [1195 0 R /XYZ 85.0394 794.5015 null]
+1566 0 obj <<
+/D [1564 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-278 0 obj <<
-/D [1195 0 R /XYZ 85.0394 585.0446 null]
+390 0 obj <<
+/D [1564 0 R /XYZ 85.0394 513.3136 null]
>> endobj
-1198 0 obj <<
-/D [1195 0 R /XYZ 85.0394 560.705 null]
+1567 0 obj <<
+/D [1564 0 R /XYZ 85.0394 488.974 null]
>> endobj
-282 0 obj <<
-/D [1195 0 R /XYZ 85.0394 491.9365 null]
+394 0 obj <<
+/D [1564 0 R /XYZ 85.0394 420.2055 null]
>> endobj
-1199 0 obj <<
-/D [1195 0 R /XYZ 85.0394 461.8226 null]
+1568 0 obj <<
+/D [1564 0 R /XYZ 85.0394 390.0916 null]
>> endobj
-1200 0 obj <<
-/D [1195 0 R /XYZ 85.0394 384.4846 null]
+1569 0 obj <<
+/D [1564 0 R /XYZ 85.0394 312.7536 null]
>> endobj
-1201 0 obj <<
-/D [1195 0 R /XYZ 85.0394 372.5294 null]
+1570 0 obj <<
+/D [1564 0 R /XYZ 85.0394 300.7984 null]
>> endobj
-286 0 obj <<
-/D [1195 0 R /XYZ 85.0394 206.4979 null]
+398 0 obj <<
+/D [1564 0 R /XYZ 85.0394 159.3 null]
>> endobj
-1202 0 obj <<
-/D [1195 0 R /XYZ 85.0394 171.8379 null]
+1571 0 obj <<
+/D [1564 0 R /XYZ 85.0394 131.3824 null]
>> endobj
-1194 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+1563 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1206 0 obj <<
-/Length 4496
-/Filter /FlateDecode
->>
-stream
-xÚµ[_sÛ8’ϧÐÛ)W ó”Í$sÙÚÍÌ&žª½š™Z¢-V$Ò'Rñø>ýu£” Û[É•HP£Ñhtÿºæ |¡Ë¢tÂ-ŒS…f\/Öûlq }?½àaÌ*ZMGýõêÅ_ÞK³p…+E¹¸º™Ð²³–/®6¿-ËB/[¾ýùãû?ýúéÍK£–W~þør%4[¾ÿð÷wôöÓ§7ÿøÇ›O/WÜj¾|û_o~¹z÷‰ºÊ@ã¯>þH-Žˆ~z÷þݧwß¾{ùÇÕß^¼»Jk™®—3‰ ùŸ¿ýÁXöß^°B:«÷ðÁ
-îœXì_(- ­¤Œ-»Ÿ_ü3œôúŸfåÇY!d)2|Áyá´3 jW”RÈ$ABaŒ-×];º]O«ü<TC½¯Û>¬gL´ÍÐt-µTí†^~í«Ûe3ŠÉ–±ÅJ
-ú½X¤p…TÜF¹r$e"Ö‡CS­©¥íÚÕ?O»ûãnjzCrØ ?!)ÂÛTŠ8=è$·…qÜøiß´Ip]Xà8,²ië!# ¯–‹©Þ¦ IÝðÃ.›ž+ú¼zû }÷ÝúK=Ðûô«n›ö–ÆT¡™ú»zÝà„ÝÌœ"UÂÑבå»SË$•+³rQ:VaÄsl“€Z›·L«Dq5%ÍÎD­4ì²3|œ9¼ë9¡
-^0m?#ÏßZ./Š@i0Êt÷»‰ Q|BJ›‚—¥™‹ ÚlD yXÅ+X¸”Ëûm³ÞÒéQЯ™²s«²®PVÖz{&,hZøþðËWE-Ý!µ”ôæ𧩠£„¾pÀŽqaÔEÁ
-0òVXž“õäš®&ÏÅ
-ºQXî.ŽzLª²pLE±‚ÕõCÔl¼"7Ê £¤òÿ3CÊVƒUŸŒúiVÁé=4ýxç$^èAðM =wÁ¬ySŒ²ïéIº £âFÙå}³Û¬É‚oÂfŽõià´@–s
-F¨­×è\¼—ÓHÊ;%E~Zªõº¾È×i°·jBà ==[øB^ð?zGLz:#K5jOi ½tbÙQ?Y3úÍ2!J*×ÍóD¯'ÓÀQ\ 7ƒ†è#o”Õ梪ri ر„“kKðߪª‘àjJñ\U¹â`œ'~LWUÁx©ŸÐU6 yý:矂ip ZvCÂ{莠ZÎE ¦®Ý=Њø\´ÎRñ$<PÚê‰G‚¤ä0Û®[Waºm×iK½×;ÙÝ]Wë/a¯G5ú¯qWÊ+ˆç0#,YHn"O`É
-<Ã=
-€†1–8ÑcXföß‘õ8Ýxœðãîn×øæ!y:2dAûh¬O¿CǦ aÃÐþ©ExñMG$mƒ÷fèëÝ ‰‹ÃA!@£ÇO?ËÀQQºåÝ¡ÙWžGø¨ŽÃ¶;4ÿ›RÞn¹¯ñ 7ýžÒ”Y>ŸP÷p5|¤3þ|„¡¨‰¬»„ý2¾ 4ø!4Á B´R}‡$h¤¸š’̘` ¸Þ‚¤Ò°gc Ö
-0%ÿÁÄaTôð´ü[LÌXIL—ªœïpFHà,¬³r¡ ¼“ýÍ"ŠôV‚ç2àv0|‹ƒ.B üF+å †²ËwùÛ³Ô3X4æ.+fo¦o¾×bÁÇW‹Û±Ò=½\øB«2•"0;rÉ Þýõ†Q Ý÷[m$øøj
-ø˜T›à‹ÂÜ(,x1'€AÆ%(Ñ纾TÏUVLK‹ë£¾Ãí‚^>å*ÙÓñ$‘©d§Q¸Ôß>Õ{r{F,?RùÊÈå4·ÔúvÆ?tz²ö¦õ³¸@묓œñ~V;N£ž`¶¤à|ÏxnÚ³Y¯k.øs%–Æ?5ÿ]ïÎ)n'é@ÌW
-8u@ 7I "[ç6
-ð/õ5-å4!‹Y?ZÚñµÎP4*HÒ7žAån0¸9§_
-X½ŽwïÃÃN¢c¼ÓÇYë–ÞÂE.l‹×Çf7 ¡.è–N,Vbßšô³"÷Ë¢âÍø¦¢tiN"ÊÇ¥ !‰LâÁ]{+@vyŒb·S]ƒ9dÂpH|…ò¹Å…¬—«*WÆ|4sÏQ³RÏ|º‚¥N"v%íç(N9¦©o@bÇ"båº
-%ïQ ¡ÜMiM}=+|ÃË¡jûx«Ì:Š¡ò*àä€@WØ^x³¯Bs‹U
- ÁèM¦%£-Þ¨x¹V¥Ü|7Ím3Pe&†H7- ,3¡’iƒ±ff<ÔØ:–Kàc¿º?Lc†í14yî°És‡/dòüðl Å¥RO>˜í¸7ylÁ|ˆø¾úBlá:‚½6àkÁhŸØë®ï›kŸà’lKC•wlðwK$¢oð“ä%¡;l
-´[zŒ0' iÆÌ høKã¯]BñE‰ÞR¡Rºp7 :`:o}ahÜѳb®§o±A@"ÒÃûîð%,5Z^
-Ú¥[,><P›OÂ(
-}Hú*fOÔ˜=9·-<8þïÈO¥bvu3ø°j¦ƒ] ¾ß@ì«Í r iþ¦È°Û%È.}nÚuM)Ô!k¢¢Z‰g™(;^Vš™(¤îQé¶÷×s¨ ïgïèI…Êĉï>\VÉíï@¯ý)ÁQG–hßГ$„¿´Ô
-oD„«Tþp`J“FЕ±íŽ» 5¢É£·œOåë—0­×*<ù«!R&lußøÒ
-IX‘”2W‚`É(|ó? NêP3‚âBMÅØBY ˜Â•Ë³úIúïÂsÖÿb]+endstream
+1574 0 obj <<
+/Length 4330
+/Filter /FlateDecode
+>>
+stream
+xÚ­[_sÛ¸÷§Ð[åŽÅÃ_‚HžÒ\rõM›»&¾™vîn:´D[œH¤+Rçs;ýîÝÅ )A–;ÉøA$
+lþö‡ﯿûéã›K£æ7×?|¸\Íæï¯ÿòŽž¾ûøæ¯}óñrÁ ÍçoÿüæÇ›w©+÷4þtýá[j±ôs‚èÇwïß}|÷áí»Ë_o¾¿xw×2^/gò¯‹Ÿe³,ûû –I[èÙ#¼°Œ[+fÛ ¥e¦•”¡esñéâo‘à¨×}š”g™¹HPñ‘
+Ó‰4-sû“Á13Ó½lAÏJ/ÃÜÌÛ;ü-ÜG®¡)·5uÕî7P,8ŠÎ$P~ï›LŠŸ «Ãn/
+ꢥá.-Lv¼’.0Ž„wÍj™Ø!3.ãvíûzS÷OD%BŒ7~Âe»Ý‚–x® ßÉE
+›IÅ´5jñÞïêê·ŠZš¶Y|ûáÓ¸»Ûoz¯§w$ˆ­WJÿ ‰žÆbÄéA)¹Í”…5à´oš„(¸Î
+àØ/²nª>!  b .ÆŠwDD}×b^wÔXÒëÍÛé½k—Ÿ«žžÑ&TMÝÜÓ˜Ò7“f@C÷P-k<ƒ°‰c¤r0†:°üph«¥²c…œÕÈ
+åÖZÀ
+‹"m«‘âbLÒâ©^iØekø03røÐîRB<c6h—;$/o .OŠ@ipSÆ_O‘â(m2žçf*‚rµÚ §ð
+.åüq]/×tzôk¦Š©YY–(«¢pM iþýúÇßµ´»Ø’Ó“cÀ¦LŒúÄi
+&Ó`ÙG£~aš•p€wu÷ž9IØ{}Ý@σ·lΣø;ú%õ†Qa¯Šùc½Y-ÉŠ¯ü~{õšA€Ó×LæS3
+v¨©–è`œ§ÓHÊ9&E¾ZÊå²zèÉßiwÈ°·lž|Ãý:¶ð<á:GL::K*P^
+epc .ѯs±“YGþóêpŒÕr:q#"OÎr'tå-½ý"„JÈVÆr°‹ç¬¨Î€õ|bE‘¢£ ­i=k·ÕÀÑ ©„zÂ+ ?lžYSiàP&ùr (.Æ$ÈÂ3‡ÅÇaÏ` Þ…ÛáÔhÎÀ`ÎoyC*²Å·ˆ£±í½®»nïû$îL<"bºŽ&aŒð«£tÉçþ[Ÿ/£¹}¬{"°P`ïòx¦Êͦ}LÙ ‹»Ž †É` TØaZ'm§ÉU8ìî"ôÒÓ@âÄh¼;M¡%…2Zx[ Sx Þð!Þ‚L$Ô=yyx½-½Ö
+³H=8*l;š;oê&*œ
+¡ûW“A¤xFRÎñC¤†a™.
+ œEa ÀLf
+¥ b¾b/ƺsÈãøås û_‹2U™ÆÄ4SÏX³<Q<Hl6ì Ö¶_¢8ù¯¾‰íc¬ˆ%ìÒ×¾úº7å?,4uÕ¤»²é³ÂR`í”`ñGºüöÂSqåë™k,W¸H F¯j?-hqFÅÉÅ°L(up¤Võ}ÝS‰&†7. ,3¾¤YxcÍÌp¨±u¨›ÀË,~y>ŒcúõÞ79î°Éq‡dòÜðd-Åd¹Rç+ ÌvÜ™<¶à®{"¾-?[¸o¯ øZ0ÚSq<´]WߺL—ô`[*Ácƒ»g"}ƒŸ$/ Ý~S ½ Ÿæ$ÍBƒµ§¾4îR*4ì”è=U,¥õ÷Ä ¦sÖ††=ªº9\¦Î€"ˆHD¼ÑöØî>û¥Ë
+9ѽ1W·.ýU¥Q^^‡«ltsiçÛ×þzÖ`šX°ÏxÀíQºº¢¶ª;Ïòxš!ºÄ¢W‘ƒpÇ€~1\Má™$¿ »à…Kq˜x•Ò/Lå6I“«“4ý­€ûdè»"ÃÞ¿N©+Žåã8èð?aR‹ÌXéÊ™T~oñ?b´ÿ@"›ýªJþCÌw»¤
+kþï%A\uWo*´>¯O¦—u†ÿ•HL²Èüÿ£Õ†xB…8‘i5EAƒ Láj”:â<üGÖ1ëÿnI”endstream
endobj
-1205 0 obj <<
+1573 0 obj <<
/Type /Page
-/Contents 1206 0 R
-/Resources 1204 0 R
+/Contents 1574 0 R
+/Resources 1572 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1203 0 R
-/Annots [ 1208 0 R 1209 0 R ]
+/Parent 1562 0 R
+/Annots [ 1576 0 R 1577 0 R ]
>> endobj
-1208 0 obj <<
+1576 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [55.6967 480.2482 256.3816 492.3078]
+/Rect [55.6967 387.5149 256.3816 399.5745]
/Subtype /Link
/A << /S /GoTo /D (rndc) >>
>> endobj
-1209 0 obj <<
+1577 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [268.5158 480.2482 332.4306 492.3078]
+/Rect [268.5158 387.5149 332.4306 399.5745]
/Subtype /Link
/A << /S /GoTo /D (admin_tools) >>
>> endobj
-1207 0 obj <<
-/D [1205 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-290 0 obj <<
-/D [1205 0 R /XYZ 56.6929 769.5949 null]
->> endobj
-1043 0 obj <<
-/D [1205 0 R /XYZ 56.6929 749.0409 null]
+1575 0 obj <<
+/D [1573 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-294 0 obj <<
-/D [1205 0 R /XYZ 56.6929 209.5509 null]
+402 0 obj <<
+/D [1573 0 R /XYZ 56.6929 692.9565 null]
>> endobj
-1210 0 obj <<
-/D [1205 0 R /XYZ 56.6929 183.9497 null]
+1329 0 obj <<
+/D [1573 0 R /XYZ 56.6929 660.5438 null]
>> endobj
-298 0 obj <<
-/D [1205 0 R /XYZ 56.6929 147.0778 null]
+406 0 obj <<
+/D [1573 0 R /XYZ 56.6929 112.3379 null]
>> endobj
-1211 0 obj <<
-/D [1205 0 R /XYZ 56.6929 116.7981 null]
+1578 0 obj <<
+/D [1573 0 R /XYZ 56.6929 85.6994 null]
>> endobj
-1204 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F48 953 0 R /F14 740 0 R >>
+1572 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F21 930 0 R /F22 953 0 R /F48 1228 0 R /F14 956 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1215 0 obj <<
-/Length 2349
+1582 0 obj <<
+/Length 2372
/Filter /FlateDecode
>>
stream
-xÚµ]sÛ8îÝ¿ÂÊLÅòC¥ÉS·›ô²w›½K½OÝNG‘[³¶äµäd|·ûß$HY²ä:½Î’ €
-ÞÿíÝ?7W!—4ˆÉU(cüpwÿ#ΤøyÿËýí݇_Þ]©(XÜýrÓ7·77÷ïo®B–Hû¹£pfÃíÝ?núððîçŸß=\}^ü4»Yt²ôåeTAþ˜}úLçˆýÓŒ‘&rþJXšòùfIAd$„ŸYÏ>ÎþÕì­Ú­Sú“"!2ájBœÍ#©”| A™’Xpa5h„V 
-” ö†‹»å‡žvøah_à1]#øG£ö G`ß#n¤$à½é€›‘“tX—xQ3<€"2àõÖ®œÞò\l£P”$ŒË¡5櫬ªôÍæŒNYÄà¶c5iJø%vØá},Ë)Í61`r8IAlóHz¤ÍçëçŸPòš$¨,Æ(Q±0ÊJH"hú Å È|Í_
-ÀK¢¨<•
-*žÊàïúÐà … ÆŠ€ECÄhaB—0œáä QÔ1wJÁ£rAãiDGo:ª€G_ˆ5$Äÿ5NáI€$N&‹ÖêªÀMc–£3”cJ»\I"˜Šspkí®^7RÀó™˜gæÔn¬6#0Rˆ røsb‘˜I5—qL"•$—ÜØã‡ý Ž4¢ûJW– ZÁ¬O~ìÌë#jÇÐhXØì÷jÚ ‡¯¤Ü‹™¹et%XÀ¡ J˜ q.*Hqb`îC(€sHˆâx.#xZ"•¾&#ã$M@¸É|,ì(†}’VYCÖ¸$Q*£ãɆŲ˜ò"ç¦(ÅcÒ <£©â*ø½ª_*³¿¨@³fÓU¶Ñv'J‡”áJQo²Òí7Xí«ò½^paªj˧dU¸ip
-I}*ÔèݳÞMy)dnŒOwÇ0BäY0í G(Ÿ¢·«Ì͸Sq¶îG-ØW.»À‰Iî-]ò*²êÇaâŠyiþ&kó• . zl^Ñ~lY—Èr¢•$ €7¸7‡LTV{à•ΉÀ°¾Êž5®=j]á\' ÀN˜Äff­
-û'!K°˜Ä0GxHâïŽXž^Ø#8XÌK¦,éŽÅ'ÔFŸÉtXÉDöb–Q+^kÊ-»P»kpë.Éï]ŒÛJûo¶n Õ6àzB¾Áb6Y"žç-”bd¾.ÛÌÆ4<Š…GDÉ™^ÊX”v½ Ôõ‚ÖõréÌùé„aÛ§#rì€1ÙªiÓõ¥ý„]‹ 7ø‚éZ€ÛwRØIŠHOåÚ¡o³v…»':o¬.d „GGZÞ_ ü'~öպܔö.Cèó”ƒ:úMùo=‚à…ëï 'år§6‡TÙ‡¿<ey¹†gpªMèwµ…Þí¦øúÓË·^å¸îóÁ¦Ñ& kGEå0„xº( N­‡j{ÉvUgþôvj?eÎvaf KY=Õƒm…~Ü;BŽ+ק@]PpýeÞ±¯ñáqA·à2mhÞpV'îA;ñ²Uõõå»GJCŽšSjKï—¨L[Ô_¯ày(·]òDÖoóõ¯—uvòÜ
-¸ucØ·uÃ}Eü?¶Ä©PþÝñL¾O\¤l¢-.T¯9‡5—™Åî¸0iÇè9Û•Úؤ˜|Ä`uBÛÉm‹qÑ °[.\ámpñÍ”+Ud²©LÜL5ûdJ 'ñ)£÷cñ }SDªääíj—amkÞ¿¦ÎK»Á^A½o·û×6º]ÕEókM`|“¹•N"Û^°W&úqÍŒl<q(/¦
-Ár“+Xw A»Ú™ù6ŸM„¥3;vNÌÕUž®4¡¬”Pé3æÎ%'Š(¯ÒNCÒ%%&Ðk;»]Õ/˜Ë¯÷.‡È× M혙%6Æ’}šqL‚Ñ3tAÎýñ'$1ÿÖM´Ùhç{ßý§àñS¨ÆD’œi¿ C­–*Ï”Q’§œwÿŽYÿ/%Ž\endstream
+xÚµËrã6òî¯ÐQ®
+<,Ÿ&ÛëìÆÙxœÓdjŠ&a‹>‘²W»É¿§)R¤,ﺶt`h4ºýB‹-(üØBKBE.TI™\¤å]<ÁÚõó8A‡ ±¾»?ûöJ¨ELâˆG‹ûÇ-M¨ÖlqŸ}^~üÛ‡Þ_Þ\ÒeDÎÑåw7·ßãLŒŸ?Ý^Ý\ÿr÷á\…Ëû›ŸnqúîòêòîòöãåyÀ´d°Ÿ{
+G6\Ýüã¡ë»?þøáîüËýg—÷½,CyVßÏ>¡‹ ÄþáŒk¹x%,Žù¢< ¥ 2¢›)Î>ýܬº­sú“B©¹šQ g ÆH,%iPÆ$\8 Z¡#P
+Îq³æ_I¹.Ì70âùrD÷ú±Dà’Š Wzg±óëMþ ˆ8øÍìÎÙ²éxIüÞÄÛ”‹Žo´“>y(¼÷ÕU±CèÁQU
+gRLöõ„ÝáÉC)’g~.™‘ R‹ë„zÎÍË\D€úQQy($-ËåßÍ®Á2x{Œ{ Çöˆ‘ÃU?–3ü‚¼Š:åN)"B®Ni<éDã RG•ð`ð qgÄ
+·Önꢙ+ƒ4x¿d»qÚ ÁH!>Èq;æÐ4$“j*A4„”SÝáà 3®4¡ûF‡– ZmH~êÐÖ).&ÔöaÒ²PnŸA|UÒ%,Ÿ=“ö ~AÀ¡ –8åÇ¢‚ö'¢)€sxE‘ ñ‘ŽÂ·¼Ã8‰µÖó¯° § I:eYƒz Œ¡êèÑ\-žÍy‘wS”âkÒ <£©âjù[U¿T& ~QvÍ•0<r• ÛÉña‘q%«Ë$÷û}½жÊßWXÂÂTÕæ;,¹y4>€1¶t®É—7-N£kðÐѳ®U:Ø!c|}^sT¸D!iWùBvÆK)¡ŒÏ=lÑ&}hÀdlºÇ`3AÇ‚ÜÎøSq¶F-Ø—?õ &Ü›û Õ©È©‹…QˆË2ä¥ñøeÒ¦+\@ôÈfÒal)rdžBŽ­—ÀÜŽŸC¦‚gG]úW’>ÖWɳÁµc*œë…Ø £]%i'К
+¢b-N‘Ò¤8gˆE·8½™/.££ÄäKLèYÎ kF}Yêýä€P…ò€ždü(½.ú‡#Ù]ÉTˆƒVÑÐb¶6îÏc
+q„Ìc–!l4+׬‘¢oT¸oFˆ'|7búz EF ˜öÉ],m“¨Ü–ˆTmË`aÁUÔr¢óþùêÈæ.~Áúçƒq\Á ™, c߉WÙaìÛÖ Ø½!OdFÙ1ÔÇLðC 4ѶbD‰®6´"ÈÍG¢Vy,ê3ö.B–`‰ `ΠryoÈêCŠÓ%lK0fz0fQ€f+b%µ„-«Y¼Ù˜: n¡ö7á×}?¸¿•Óvr Ú.æmµï·¸£m¡èÛbm_Jú…ÄœIc‚(Äm f"ÊøÖ¦Xì[CEýôä-úiŒaïhìûaLA½jÛóCa?#Fß0 ¾bÁ6 à÷<í$E¤Ç¼ðèë¤]áî£}8.Ô „„G{ZÇZøül«"/sw—!ôe.õ{úMþo3 Ç w³rùS›]ªÂ_}oz7º]mf6›9¾þèä+Š½C>ؼ Æ–aín¯¨ÔöžÓ¤) N­Çj{I6UoÝé5ì4Ý”=Ûš‘,yõX¶eæaë y®|§u9BÝÁõçéPÄ¡ÆÇÇ]ƒÇ´Íà«^ÜñÒÉVÕ§ï)÷fJlJ©Í;w8EeÞ¢þ|Ïc¹»Ñ)Odæß
+­ù|ƒAЊËXuLYÎÃIï·ÿ“sÊú_—0‰Äendstream
endobj
-1214 0 obj <<
+1581 0 obj <<
/Type /Page
-/Contents 1215 0 R
-/Resources 1213 0 R
+/Contents 1582 0 R
+/Resources 1580 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1203 0 R
-/Annots [ 1219 0 R 1220 0 R 1221 0 R ]
+/Parent 1562 0 R
+/Annots [ 1587 0 R 1588 0 R 1589 0 R ]
>> endobj
-1219 0 obj <<
+1587 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [406.6264 617.3695 456.8481 629.4292]
+/Rect [406.6264 524.1437 456.8481 536.2033]
/Subtype /Link
/A << /S /GoTo /D (tsig) >>
>> endobj
-1220 0 obj <<
+1588 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [140.5805 606.0819 196.7992 617.474]
+/Rect [140.5805 512.856 196.7992 524.2481]
/Subtype /Link
/A << /S /GoTo /D (controls_statement_definition_and_usage) >>
>> endobj
-1221 0 obj <<
+1589 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [103.6195 562.6731 159.8382 574.7328]
+/Rect [103.6195 470.0794 159.8382 482.1391]
/Subtype /Link
/A << /S /GoTo /D (controls_statement_definition_and_usage) >>
>> endobj
-1216 0 obj <<
-/D [1214 0 R /XYZ 85.0394 794.5015 null]
+1583 0 obj <<
+/D [1581 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-302 0 obj <<
-/D [1214 0 R /XYZ 85.0394 769.5949 null]
+410 0 obj <<
+/D [1581 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1217 0 obj <<
-/D [1214 0 R /XYZ 85.0394 749.0225 null]
+1584 0 obj <<
+/D [1581 0 R /XYZ 85.0394 749.3189 null]
>> endobj
-306 0 obj <<
-/D [1214 0 R /XYZ 85.0394 668.2594 null]
+414 0 obj <<
+/D [1581 0 R /XYZ 85.0394 679.8163 null]
>> endobj
-1218 0 obj <<
-/D [1214 0 R /XYZ 85.0394 636.8261 null]
+1585 0 obj <<
+/D [1581 0 R /XYZ 85.0394 652.1211 null]
>> endobj
-310 0 obj <<
-/D [1214 0 R /XYZ 85.0394 425.0299 null]
+418 0 obj <<
+/D [1581 0 R /XYZ 85.0394 573.4726 null]
>> endobj
-1222 0 obj <<
-/D [1214 0 R /XYZ 85.0394 396.4061 null]
+1586 0 obj <<
+/D [1581 0 R /XYZ 85.0394 542.9681 null]
>> endobj
-314 0 obj <<
-/D [1214 0 R /XYZ 85.0394 136.3155 null]
+422 0 obj <<
+/D [1581 0 R /XYZ 85.0394 335.1831 null]
>> endobj
-1223 0 obj <<
-/D [1214 0 R /XYZ 85.0394 104.8822 null]
+1590 0 obj <<
+/D [1581 0 R /XYZ 85.0394 307.4879 null]
>> endobj
-1213 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F41 939 0 R /F22 737 0 R /F53 1029 0 R >>
+1580 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1226 0 obj <<
-/Length 3704
-/Filter /FlateDecode
->>
-stream
-xÚ­]sã¶ñݿ“—Ê3'†
-‹ÏÖZŽJࢮ:K:Ž›’{¼ ÞÊ)×YÔ©yÁ¦à}% ›0¼+öUa§t2¡ÝÉ„™ex2%gUO3G‹&¦Ô€&ô¬k-#Rÿ\Ë%ª/:œÕœ1¸’gf[Ý“cüóý˜YÞÁ¸+÷À2Iö©Ž nl¢HV&*ÁMö=‰þvÈ .
-ÈÙ¹9öíž½DKO8r³bª âɤ¿ÕúÄ­ü,eðÂHˆ™“×<$QG-±ˆˆ¨ÝÈ'Y‡‹”íÊe…§Gñ>W£¹H“Èh¢TI”«Lù¨ AK@,ŽÁæïÕÌúóãf_teØॎÒ$Î,²7Î=‚à™ÒC¿;ô4~hËnÊ̶)§\Þ¶l´v+•y¡1ŽÇ‚™á£QÀtkþ^â§öÀç*˜oÛâ‘7w äP‡ä 2ÜN×x<Ñ"²‘å‘ÐM¼þ-Ø¢3鈗Ƹ0[±az{èzš«še}X•.ÜúL¬–/ë‚7Mö›¢'hW<uoh#+áöFg•u¹ìK°õÖ-¯c×sÆ`M¦­5á³ç'˜684—<™ÎYoÓWËC]ìé?.¯‹eUWýÓbvò:¾057ØnlnviL±enbÈ?àϪꖌÅ:¿<á]OQ#Á’l \
-Q8ê‰SÙ¬®¶èåHtŒùLЮÙãÉh9ü«Ýr+.
-“yý·iDÐL„Ô&Äl•jÏl•"GˆªeßÑ$©&®r´ã2k3©õ™ø
-W¶ô\”ËvkÀI¸:(nj\a×±\០µç6d/i±Ó³+>¸Ëb¹áw­Fž%;èßÁ™¬‚úªJr
-Š$šäg2tc¢$VNsüùžë¨¹1&2yÂêSVŸÚ¡…¤Ö•5ýrÈ’/ùÎN¤œç Vân¤“}aÓikPh›8C2ÂÑ¢X>v4?È gÚõÀ ;=
-ä‚zÉ8=ñ“ËT*yc —²ýTr~…#.á`„r¨õi:{k5€Ëàámš¬¶I6BIB0XnÚ–ÌN²=ÉÙcYîÜ>´7/hë FGCðÚS…5ñ“Ü=>µ- ŠPžÏÅ ó(M}:Š‚MR,xÈlö›üáhQ®[_²ÂÿŠá¶Ø‚')l¨’
-tˆûF{ëñ¥5à¬\¢Ôuí²¢¼é;V[G™‘á‚7ª!îœÅ‘ŽOÒ²}H!N¢Ôš³HÃÍ.­¸FÖì"Æ)¢L/JÆbœ§°àòã²,WÝÉ‹U³ª–| X„œÁæ¬LgïZZá"
-»s;:ZH™iM¼"ð¥é¶øXm[çÀȹŠQwuÒ:X”›âCåûÇç .@Žk`ëÐN[–c_ô”·”KÓº÷­Npª¥Pc½èJEž¸E>;:uÉJ§ê"+G6Õº.xï&RbH²é9}•·YEó+׿Nà|!§¢o‰'ò\WÈ$\ô¿ŠÙÕ\þSô yàHÆÛ×Ák¤}ÕôsªXqÝSÙïêhÝôÆίɽäJîlÔ™o}p“62 °äâLŸIŽúLrÚú@
-¾aÖàÍÒLœvó_ õ­­ŽÏVü)$øIž¼È0Aþäj­mÁ8w`qXßÆföǦ=2”ûáö"ÿã«©¸¨”· Çrß„›‚ñi6m[DRGHnêv­šT^Še[TuØ+$žÜ³Hœþ­
-pÕ¡ÙÌDf—S öŸ#æâ#®Ì"P¢ôR<õ.È_}ò@ó?)À\gâ 9Lp iŠ$ ‘8½=–»™,É^ÂâÒ†å>(,Ðœ\êKIAYËû’zŽ¹Gr)¦u¿;ÇçX\Š¤n—Eª¢%¨ ‰åoÂ#þw<zŒG~&zÔg“|¦séÏD áÁ«Yß²:›$FecTé$Í¥QØß.ýÇIŒ½¾D~ºdC•p÷-bâé턯7àOwØíÚ=÷ÄŒ‚«ÄxF.·ÓvC”š}K=þÓ› W:R·OÅ÷ÌŸ›ï°DìUÍä¿+âk
-I;¥Ž©‡]n›$ÊÓL6|öEõ°ÁÝeNÚOTt5êÓœ}m‚Ë6–6ºáµiêšE"Kcre;7jöýà{dî-Qæã†+œÊϺ,:Ú
-W¹*
+1593 0 obj <<
+/Length 3489
+/Filter /FlateDecode
+>>
+stream
+xÚ­Z_“㶠ßO±“'ïÌYÿJê=]’½tÓæ’^6Óé$™ŒlË»êYÒÖ’ooÛéw/@€”ä¥ïÜöÆ"A
+@ø²¸Lá'.Ml!‹Ë¬Ð‰I…¹\7éåŒ}{!xÎÒOZNg}u{ñåk•]Ia¥½¼ÝNxåIšçâòvóËÂ&2¹éâëÞ¼¾ùöç·¯®2½¸½ùáÍÕRštñúæÏ×Ôúöí«ï¿õöj)r#_ÿñÕ·×oiÈ2¯nÞ|C”‚'˜¾½~}ýöúÍ××W¿Ý~wq}t™ê+R…Šüãâ—ßÒË ¨ýÝEš¨"7—ÐIQò²¹ÐF%F+å)»‹Ÿ.þNFÝ«Qû‰4‘Êʈ¥¸")Œ‘3 š"±Jª`A‘‚UÒ4]캻»º½#-Ê¡jªv î7Õ¯i*Ûz¨»–(e»¡ÆÏ}yW¡-`E9Ù²ô†“ãò°Ôí½Ÿ$&“dš¤*30çx ž3S9hYž×Â)•-Ö]‹ÒÝöW"_T=RóEIƒõ¦¢Öûr_WÃuº-Í
+J;âê×SgÛí©1ÜW4·-fÕWû÷Õý'“‹›¡h§ÀÖ*‹½¾/Û¶ÚEÔ[j‘%&ËÕå2l¼ðp¿/{XR*°wßwëôî±/Ýax8 4ÖTÃ}·é_`O£àMÉ#A#|…¶ ¨}Ò×h
+ìí ·ã)õ•
+09¤ …@Ã&tž™‰è¯øìÜáÀV¸ÚÕ½ .v`+ð…Ý­½od”O¸/yUÌfÆãZî{çÁ&ÍH3a¼fÂ.rÔLÉE=ÐÈ£ãsi@fÑwNŽ %Ï$z/¦í3r[*U$µÁ~™%ÃÁø
+›0©j‡òµ«½ìöüJÝÒ“ó¨Šl*Œ†M…ö]Çot³7u8\‘}öQŽƒ&ïYR ð±ÔD bR·ÞE•_¥Ô‘P!¬ •ûýZÆvÔËES#êa’JÎ4ýCµ®Q{Î0Gn´™N¬Á¸ª
+¨}ùÔ ‚¡Ë«Ä{Ä"8Éš
+Žú†šbƒ#ω³
+‡H¿nêˆ$'ÐØÎD¢âœP±ŸN°7÷8h+~©\¯«‡ÁA2_=-0îPMMFNÀ‘ºÂÆ<)„)øDÔí¶‹Åš<ÉEbMjÄ ro­³$SFÌ]ÃÁ?%²Ñß°ã-<ƒ'c§Œ!7a’\ûœ†•Á&v’Ó¤(” !²j+õ¯<Ô ¯
+Ð]’Fâ$F˜ü]¡PÐ^"…<­˜Æ1¤vDtþ ýÙƒ «dê6q(/@¡‹€Îy y˜
+’˜ÈT&ya—~&[a‹Ë7há¶Àtú,[¼vQÈÕïc€©ÀF*í4Ö÷]G§Nòq’‹wUõàסµyB·ÛPc¢’·A*l¨Y˜áöôøè4À(Áý|¾ ¦H²,@QÜXñM—’ùâïùakUm»P®B¿fº+´àIþ«"`§m–†+ úçò@P™÷AÏ<ìK¬@ºÈJŠ†,²ŽŒ­I‰ ösf (Ôœ™Ïð.Ø~~^q¡4æçš 8…ÒâH¡ô´BPNÈ3-7×̤\œ{Îê!‹b§Ÿv¨
+0sÈèi.AëÆò9¤}kÂé e5ð¬=Lò×å’oŸG\d¹Ø-ÆRˆoÍÒĤG †o¹=
+ˆÒ†–/º°µáúØpˆD ;&9^UÌÅúHáÈÕ‡uUmú£ëvS¯Y!˜„–Á{Y™-Þt4Ãg
+
+̉ˆµ·üƹ|Aƒ*ŒEN ( #Ëì§Ñ0Ai‡(ö*›•Ã~èÐx!”J´qŠ¯|½…„°Ð†X
+íISÓkè K¿ q:Ö©J”ÍåÜF‘#%ón·#w‘|×+±vXïëU ¯º÷üWÖÒ•ðh«Gj€¢‚ØJ8ñw‡Ã`aØ©äôs
+vk^)úåDa%“…KåãVYH13ø ŠmG+4ÝtÝM9”\k
+ü“Ål7·5Ú'}Á¯"´ú‚HcÀÀž¢í¶dÚ¼Œ~?Ú×í°¤jç=U}ô#Í›ª s—QqÏùw2Eš<\{ðõl$a@Z)ĉ+&9¹b’ók$0L’Óë#Ép2
+kî²Úc¯0¹¿C8_Pø;v! ¹(Éï3S|µŒ@x"BÉ_– IJ,Ç÷xc$†âÖ•Æ'Ëý н.ô' &
endobj
-1225 0 obj <<
+1592 0 obj <<
/Type /Page
-/Contents 1226 0 R
-/Resources 1224 0 R
+/Contents 1593 0 R
+/Resources 1591 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1203 0 R
+/Parent 1562 0 R
>> endobj
-1227 0 obj <<
-/D [1225 0 R /XYZ 56.6929 794.5015 null]
+1594 0 obj <<
+/D [1592 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-318 0 obj <<
-/D [1225 0 R /XYZ 56.6929 607.7662 null]
+426 0 obj <<
+/D [1592 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1228 0 obj <<
-/D [1225 0 R /XYZ 56.6929 584.6557 null]
+1595 0 obj <<
+/D [1592 0 R /XYZ 56.6929 749.2381 null]
>> endobj
-1224 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F41 939 0 R /F39 899 0 R >>
+430 0 obj <<
+/D [1592 0 R /XYZ 56.6929 540.3599 null]
+>> endobj
+1596 0 obj <<
+/D [1592 0 R /XYZ 56.6929 517.4049 null]
+>> endobj
+1591 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1231 0 obj <<
-/Length 2890
-/Filter /FlateDecode
->>
-stream
-xÚ½ZÝoãÆ÷_aäådà´ÙOry÷tIíä‚äÒ:îS4EÉD)R!©SÔ"ÿ{gvv)RZÛ)
-‡÷{çó73+‹kÿĵ5Œ«L_§™f† s]l¯øõæ¾¹~Í2,ZNW}õpõåJ¯3–%2¹~XOβŒ[+®V?/¾þöÃ_nïo–ÒðEÂn–&ዯ>~ú dôùúÇOw¿ùûý‡›T/>þø‰†ïoïnïo?}}{³ÖØ/ý Ïl¸ûøý-µ¾¹ÿðÃîo~yøîêöaäeʯà
-ùíêç_øõ
-ØþîŠ3•Ys}€g"ËäõöJÅŒV*ŒÔW?]ým<p2ë¶Æäg”eÆÊ4"@)c4K”TN€M;G%}û².‹¡\QoÝvÔžü|ñ”7MY¿§Þ¶ìû|SöÔk×ô}ª6OeÎû\vÕp¤^ ½Ú¯>Tu=¿;/Šrw3”+0jaIf¥£ô#®E¶8¶{jäÝ°‹’:û±è«fƒ;o1á;µLÉ Å…ÇôǾnò©x¤e©©_öŽM²ÝÐ(€Ë³µe6Qfv6+Úf¹À¦R.ýÚ]Wµ —
-e‡ç“4_ußbË.VåPvÛªñ<žòZ ÅfØçu}¤þ.ï{8¥¶”B0¥µé –CÒžœ´Úýæ l<±bq‡ªU`ßåïùvW—È17pç?8— ŠfÕ"§E^íÔYçEU;b/oV´ô¤j7ÜG䥸
-0^†,/rÐ,5:êó–J’2 JrN §zÈËv\e„\—×$€rz$—l,ÆâKR­çÎph÷µ
-ÿQüC“fôÂ~X•]³ÙŒ -Ó*zP’7ؾ(jòl¯*Oî€\$#uÙ ±ƒÖê¾a¶/»Ïó@oüÎ~
-‡Í›Ó=ôdÃP³ÙwùrÔø4d~ž5¸Wœ˜Š¼ñƒûݱËßAz=ØMMé€.\· v
-“…)RÑ\_­%@+Ò¬\u¤1ðŠÎc$ôâi•’I¥’×±P:8¿—÷éîÖñ|=K 9Ä0R±eìla˜< ?ªÊ=É붮ÛBÙ”­œ>»Â38ì¡÷‚´7'dV† &ÃΉ^Jb)!QÚª¹„»fUx
-Ï2.œ;­‚¾q8F‡Ö«¯’§ZO
-·{¡ÝdžØúø¹ÇŠK1d€RJœêÿfX:-Gä`™MÁÖhé“KÌ´
-êÙ$à¼ÇW ÿÀ¹Ïð2°/ÿž‚] ì‘«`·¯š"š¦¤‚q‘þ9:DHTè}Ï…ÕþŸ5f^aH) ç@ʤL7+¡–*;WMçlÚî¡&I™Hm£>ƒ[j0-ùYD!ðøm“«—1¯÷fÐBT§f1Þæzî05§iï=´É[ ?úi²:j;SO±j¯b¤›wP«¡fBÈÁ
-&&¥%³b|O 9œ=wÌä
-zk ép_ˆÓÊQØñ1Z~$xßRgÉ3õ®TS2Ñ3Ÿ)xù˜ýµ;¬qzOD~œ_ Ⱥ¢– &"!%ÚöÑWÊo=n&„)Hºç.êlr[¯\H5óú{uŠ†1Gné—ºTJ+YÊ«)ñ¢4Ù=vïè]Ý
-ÓeôNÿì^¡áù¥/AJ0lajçFÜ&´œÓ6º²³Z3œ3þ0≙-•‘¢Ÿ .¨¡ß&ætùŸ‹&ÛbÔÈ5yØìëL_ó`hPg ü1P$Bý¼Ô'uTTèâ¼>sNÊ
-/?/ü¿=9ög
+1599 0 obj <<
+/Length 3318
+/Filter /FlateDecode
+>>
+stream
+xÚ¥ZYoãF~÷¯ò220êôÁ£9ó4™µ“ 6“]Çû”-Q‰THÊŠv±ÿ}«ºªyÈm{‚…a°/v×ùUUSj&áOÍl,¤É¢YšE"–*ž-÷Wr¶¹o¯¯YøE‹ñªo¾5é,Y¢“Ùýz´—ÒZ5»_ý<ÿø݇ÜßÜ]/t,牸^ĉœóéóßh$£ÇÇ?ß~úö_w®Óh~ÿéÇÏ4|ws{swóùãÍõBÙXÁûšwxæ…ÛO¿¡Ö·w~øáÃÝõ¯÷ß_ÝÜ÷¼ŒùUÒ #\ýü«œ­€íﯤ0™g'èH¡²LÏöWQlDãGvW?]ý³ßp4ë^ É/6VÄV§j`œ‰ÄhãXÕp”©y¾ÛQc/Ë]Ù•EË͵²ó‚:íñp¨›®XQ·®&/Ëy}(š¼+« /?·]±oAªÀÃü»ú„²Ôˆ,Æ"†0ƒÁ+»zÃëÆä%+ý²SééÝæÕjÇä틶Í7žò¶¨˜¹®æç¶lqëÙÂÈTè4«SJdq¬Ý®Ìû•læ%îGóUÑ.›òÁ1Ã=»m`G©X¨46vIJ®Öž@»©V)¯Ýç¼óx
+eÓô¯É =UšùöÀÞ‘¬ž9 ŽðGù¹+ò–›õšÖ Õ»Þ0xåc±£æ¦|,˜„$ª4
+³ÒÔàÁbØžÛbW, Á¡·®›ÁÕÈöALU±{O½¢¢¯é¹á߯'zŽH^Í=:;_¢õx—‘SWA¨‹TFV^pØ9^ ‡Õ–n
+Ò‘'ö±ÌƒKÄÚD_fL„ˆÞZÉxf–ŒÔ#ßÄ ôM½ˆ&S|SrD¿iY­ëŸ(aMoòaÕ@
+$mR_
+8”\Rá°y3œC@6 5›c“/zõó¬)pÇL ”Yr êÒp,þéµå#¯Ó]¸fïí
+Sÿ&t«&b_­À’‰ÌG)MœJH•œÃBÇe^0CÉóèXè ùÂlÂd 0—AÎÚ¢#h-Jʯ‚£Î4^Ñ0FBï¹*YC g’×±Pº/“HÞ=¤»Sûý£IJ(!†Å> Y„öÆ:]Kþ`¨&g’×õnWŸÊÆlåô8Ô~œÁa½¤½ÙÄÙ0éß¹a ÂÖÀ˜h¨pÈ7šjµd
+ˆü"Š¤{'BEc„LåEiÇ3¢å Y=ˆ&Òñü¹D6u;iÖXûÖŽp5ów/ÖÂÙÁg¸:sNjYR0ß×Iµ|à†ÀË¢9¡\ˆy˜° õB^î|­ÝáØ¡æ•œ¤àå/Pú«—öP,Ë5Wgùh ¡yIýÞ@FÕœRjþö¢Fdôp¸ ïCi"= åò7wÎolƒ8óÇ«6‡]jw]b˜ÁE_­ëú«÷¡
+au–z¢³(½¤¼ÿµÕSÒÿ:[)Žendstream
endobj
-1230 0 obj <<
+1598 0 obj <<
/Type /Page
-/Contents 1231 0 R
-/Resources 1229 0 R
+/Contents 1599 0 R
+/Resources 1597 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1203 0 R
-/Annots [ 1233 0 R ]
+/Parent 1562 0 R
+/Annots [ 1601 0 R ]
>> endobj
-1233 0 obj <<
+1601 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [173.6261 333.9221 242.2981 343.3317]
+/Rect [173.6261 273.4719 242.2981 282.8815]
/Subtype /Link
/A << /S /GoTo /D (the_category_phrase) >>
>> endobj
-1232 0 obj <<
-/D [1230 0 R /XYZ 85.0394 794.5015 null]
+1600 0 obj <<
+/D [1598 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1229 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F41 939 0 R >>
+1597 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1237 0 obj <<
-/Length 2569
+1605 0 obj <<
+/Length 2400
/Filter /FlateDecode
>>
stream
-xÚµ]sÛ6òÝ¿BÓ—H3B€ žŸÜÄιsIz®ûpÓv24IœP¤Ê»êÍý÷ÛÅüiÙ½äÆ‹Åb¿4ŸyðÇg2da,âYLz\ÎÒÝ™7ÛÀÚû3nq–i9ÄúþöìÍ•Íb‡"œÝ®´ó”â³ÛÕ/ó ¶
-Þüí§W×ï¾¹XDÁüöúÓÇÅRHo~uýK½¿¹øðáâf±äJòùÛ¿_üx{yCK¡¥ñýõÇw‰éç ¢7—W—7—ß^.~»ýáìò¶»Ëð¾Üóñ"¿Ÿýò›7[Áµ8ó˜+9{€‰Çx‹Ùî,>“ï;H~öÓÙ?;‚ƒU³uR~ÜcÂÅ„
-s’+j²ÒoT¿m­W†7i8šàçP¾L摈Ãvœ–Z‰4zeYBÓ%ÁF‚ .Ž‚G²n@M¡A0Å•25åv«¥r"4ž&ddüoc8ÊÚaäLCÍ ý@Ÿ¯ß½¦ÉÖ j¤óÕy‚7ºÐ•½D‡Ëò©ÀÒfŠ£¿Ä~f¹¯›¤j¬¡ªy»·â‹¤ø‘ø ã`äu“aÎÀaµ€]EA`n¤Yc-K¼IäÓi
-RšP± ËÍK
-(vžƒ‹ŒÁ³ÞÝG
-Y@°#ˆ®H´Õ‰À碋ÏD ¹ .Ê°ñ©H­ã–8ìóÂȵ$¨)Ö›)9 <ÜÒŽï4°œ» Ö ! ·–ie´9œ'y£|^Ñ̆/ Ùfy³47k5!õ²É)ˆ¾žÒÛ]kEGÇš`e½+WÙúp»]%@Ù¨Ülº¨}gQ÷eV44‡Ü”Uæ2Ob·x¾M:=öaÏh‹óAÝ‹eT\ÔE·[=:Ü2öã¶JjýD=°8ેœóø1ÄŸ~¢æ;„Ü_ tør^—´`FoE Jý
-E@‰4vAG Ç©1•²xÕ é“Œ)ÒÀªE‹z4[&ã@ YÂYm‰”둯Xƒ\Sžîð;íq‚ã„lÚN×u²Ñ–笘ºŸ-Ë„¨Ü1ˆ/ÂÑûBÅ6BŒ”ÒL–¿<PHÿq|œ'$‹]Ì®€ÕºÑ :¸Gi"”4çZi"¬“&‚uŽ†°G¢
-”ã¡8äc`uäØë2ÏˇÎ1œŽ|×Nú0ëêI,Jþ6Á½q`ìHGš£!ìs}¨A™çc Éáö’&åÝE@FŸá\ÿ‘ìö¹6²€2K7¯jZ¨“aZA‡Î±
-™=J;•®Ëü¾{²Z¼ï>þ´XJ(HÉaW‹b~ß}£yݦ[\¦×iD3qöE±áßkZËËòK»¯i}Oya2Ý`yëjO§RltóõØCÒ<£6|ø¨˜ôq©Sû£ gºå§t>æ×)(ð€’€šËN¡ääghoöl{éGïþ?‚ˆùJ rÕ¨U‹®ŠÜ}’w_Ç-Ö€õÿî@+(endstream
-endobj
-1236 0 obj <<
+xÚ­]sÛ6òÝ¿BÓ—H3B€ ^žÒÔιÓ$=ŸûpÓv2´IœR¤JRqÕ›ûï·‹]ðC¦ß%ã‹Åb¿?`9 àOÎt,âT¥³$„¤ž­öÁl {o/$ã,=ÒrˆõÝíÅË«0™¥"U<»Ý h#g·ë_æ±Pb‚ù›ﯮßþ|óz‘DóÛëïK¥ƒùÕõ—´z{óúÝ»×7‹¥4ZÎßüýõO·—7´3ï®ßO”~!zsyuysùþÍåâ·Û..o;Y†òÊ DAþ¸øå·`¶±¸D˜=»‡@È4U³ýE¤C¡£0ôââŸÿèvÝÑIýÉ@¨0V
+Ί@&q
+NØ5©q»°)$x ë±Ìöv-êc9¡qÈAʘ”1ó’/Ýñc¹‰¹ªþÝ~¬s'Ž]µU}ZH)ç‚´±ˆ’$öžž8úWÐRitWG
+kü"YS•Í· <Ê&À=b¿*MÈ*£P˜TJ–`yœÒ[ˆP!GrUí÷.áG‘—î& ^Ôæ_ïL¿ÇÆ®oÚq4Á‡Ë“±~žÎ•úhí,:¸mÅiíšYB×%Å&J(©¢±ße›–òçy^PÂH£†LM…” m¼
+]¤)¸øÛ:´a?L¼k˜yiï òóõ÷ßÒŠt {- ÒŃé" Á[[Úš¥Ópy1•Õ@Û"2iò?±Ÿ3÷M›Õ-;ª™¬¾HªHž©Ï1NÞ´9–\Ö 8U–D¾VvÖªBI’nè:oV™ÛZƒÝÁQŒš_ohïTiQZË÷8mÂï*;´G26Ñ£:‚[¤/Ô¬ zûcÓùcrÎ(È?Ç+®ïóv7®BTܺà~$¢”„”ú”°Ü>7 €b9:ðÎpt÷™‚3K ¬1‚@gáT[?‘ø|v …Š´ìË(²ñ¡\q
+ù§ÿ0ó½KBî›G¡ž7m8Y×)!Ô³"ˆJ?€@s òU†í®ÚŠ¶ËØ÷ž#†N1šßÓ ¯%‹€_ÐÕÊsê\¥*_´CzÎ%SÊ4°ËhIÆm’sÔÎ&RmF±Â¹¡:ÝáwÖ!ç„Àq
+* Ø$´½mšlk™ç¼œ’Û2e&U
+*ÁÄ‹pŒ>„P“§e€´“½¯Œ4t
+ª÷ .k}ü “sgó'í—<œ_÷§^G4ΞÅÄñÛ+‡ôÍð8‚¿yõ5§î!±×õæû ¯ò½šª†ç.;ÁÁ™O ðôÜ=4­³ªŸzºfKeÁ“Þ bœ–£æ<5LzÇD/µHÂ~šÃŒ‡ìB׎çæ)Ïù ±'2ÄŸ[/±< S½] ’À¹AÆ4 rb=Eáé4r5ÈŠAÔ×vü 0Bè§,/²».†ŒºÄpm(,î
+;Ízm×c?Ú¾@´€Ú6âÁÃOB¤3Ç"ÔÐÚ?ãéê–H‚äì¥ñÿ;åÁ^ju¬õãй
+endobj
+1604 0 obj <<
/Type /Page
-/Contents 1237 0 R
-/Resources 1235 0 R
+/Contents 1605 0 R
+/Resources 1603 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1203 0 R
+/Parent 1609 0 R
>> endobj
-1238 0 obj <<
-/D [1236 0 R /XYZ 56.6929 794.5015 null]
+1606 0 obj <<
+/D [1604 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-322 0 obj <<
-/D [1236 0 R /XYZ 56.6929 556.3324 null]
+434 0 obj <<
+/D [1604 0 R /XYZ 56.6929 520.4669 null]
>> endobj
-1234 0 obj <<
-/D [1236 0 R /XYZ 56.6929 531.5504 null]
+1602 0 obj <<
+/D [1604 0 R /XYZ 56.6929 495.6849 null]
>> endobj
-1239 0 obj <<
-/D [1236 0 R /XYZ 56.6929 214.5791 null]
+1607 0 obj <<
+/D [1604 0 R /XYZ 56.6929 178.7136 null]
>> endobj
-1240 0 obj <<
-/D [1236 0 R /XYZ 56.6929 202.6239 null]
+1608 0 obj <<
+/D [1604 0 R /XYZ 56.6929 166.7584 null]
>> endobj
-1235 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R /F21 714 0 R >>
+1603 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1243 0 obj <<
-/Length 2985
+1612 0 obj <<
+/Length 2418
/Filter /FlateDecode
>>
stream
-xÚÍZÝsÛ¸÷_¡™>=W±ø"@æͱåÔ7;µÝ™¶w÷@‹°Í EêDÊ>ß_ßv!Q
-e6M2“x&Xâc,»¿]ˆOüñIšÄLfjb2'Œ'“ùâˆM íݧ>ÓÐiÚïõööèoçÒL²8ÓBOnï{¼Ò˜¥)ŸÜ¿D§?ùp;»>žŠ„E:>ž&šEo/.Ï°&ÃâôêòüâÝ?¯OŽŠn/®.±úzv>»ž]žÎŽ§<M8ŒÄáÀ€ó‹ŸgH½»>yÿþäúø·ÛŸŽf·›½ô÷Ë™tùýè—ßؤ€mÿtÄb™¥Éä>X̳LLG*‘q¢¤ 5ÕÑÍÑ?6 {­~èüã1‰œLe«$IO‹S0˜–HÎã,Iögri€“qg’蘹9Á{g•ŒS)“‰I²XK!ý¡üqoWÇ<¦eícDo ˆÆ$ÊÀD®ïšÚ¢H»U^·0²¥ÏGªoíê øyº¤FÏÞÎmùTÖñþ)(8£µ˜ôÿe‘*%hˆ†:|M+³Œ%c2V&ÖÆð]7ëî ¹µuñºx{ëþžÅ+EÌe"ÇÄ+a[‚g^buÓ•÷/£‚½ ò»¼º½8ÿ7ÒK0M×Ì›êááªÔ÷.<=S&Æ„'¤ÛVê¥2¯J[kå”Óܶ-¨Ê®¹Ç’Xô.ûïkÛví+òì-ôkÉŒš1ŸeOȃòԚŊ)5&OX[ʹö‚Z׋¼›?ÚbT¤ïA–ùƒ… œp·;§ÐŸD;S kÁ!u¾d,ÁtfJP¯çœx®ëü®²Ä¿Á²°]-Ê:TÃ¥
-{Ÿ¯+bYúÀšw–Ôs7táý„ä>•P^PJÔw]UCâá± ÂyÌëÚ¾b‰ûWòË®ù7µÄ˜+•YbÀ  ZâÚvÏÍêã¨Ý¸¤~hƒ—v•weS¿bmû‹ùŽ½—+¦²1c«ƒˆ‚‘±]p3F%vö†³œ£ÄpÌkâÚ®ã{–X»D¦é˜¸œí`|¶âš¶v¾^•Ý8b:Y<zÊ+^^H¶.CeÀtŸú›øj²Ö&–
-Ö`2“mÍëb‰f5îå.j9Z}ò;— óäÖËÁ‡„=EfB4ÜßQkÛ,,ÖÜçeµÆŽ‡aFs_ fg¯f?aF>1>v
- !
-Þ¹WT´wö_KE!žŸåýiÄAåBÄàÜFUTdâjŠ—ÁgL Âéã†ÍGŸL÷ôé , úu¤@íèŸëÝ`_»¸Še•—Ô×Å=ž(ÖvÐîxŸE]¹°€ýœ]……474` ¾ê¾óóC•cåë6ƒQ©w¬ªïÐ3e™í”öÎR¢ÎóS$
-"ÇE :‹•~SP9Cщ¾i€jtïn0…ÍPgÿ
-e‡Ó=X„ó.©Ða¹=:}„j‡íihƒ%²eã£Ó楹Ÿ>#Æ;ˆ´hꨒ¶ 2Lç\‚¢½q©3²«RR:Ç |ÊÃy^#™GÝQ“×f)A‹A”H"ä Û6’î[KÑ){&{©TÁLõ„˜¡Ûðµ5Ø_Tu¨%U‡ê êóá‹Šò1½”£Î¨›
-™òm4uOyU@Â7=¬»ná9…2£Ä„ÜP÷à m£Ùý ‘~ìõp4¾õq¯ã}Ìòe8h ­¶?žû5žc˜Ùû5Þÿ7*,„ë _¦‰†nøŒ~Å÷ɯù„à±É
+xÚÍZKsã6¾ûW¨j+W"çæØò¬S3ö¬­­ÚÝ$Z„%ÖP¤"Rö8¿> 4(R2%Æe¹jì@
+CÜ÷+SÙ£YõB|q}[šŠ¡ÃÌJ­-Ô?Ú}Ëõtn«ƒa\b³jn°
+FÑu¾ˆ«éBU¤ŸËxflìcŒ;®µÐDYsA³º:@J¢€ûVO±ïsÇ÷–ö¸þ LS™Õ"Íëb0
+mGŒ‚nø«­¨;Íâ:^Û.Ç#‚Èd,xš§6â ôP¸|Mìeóe4vÿ¼\(§À¡Ê¯á15O å6
+«È7f­h4<ÃpЖ֡lL˶Agòa–Ö¹r½XÄ«güpþÒ8+ ß°˜ÍÓ5—"L»; „0ª7¸ï5%® “µ§qef ÏCÂSº Í·ÁŸÌÝä„ldàK ëÒ{02,)Ñþ ÌMÒ+6ÄŠ¬¾\ã*1+Gw~´Y4HÌC¼Î|—iÕÅÂZÑƼЧ—Ià—B°zû®³¬ FD Î<ÎssÈ·Lòmfþ¾ž˜q"µèõÄLRôĹ©žŠÕ×^¿qíÛ¡Îì:‡¼mk2ßs觔(®ûˆ•¢áÌ[÷z™€iôŸXžÁs¦S„ eáÕšÈwŒ—ÔoBôà%#N¸Œ¢^£ÒÂÒªŸ3-=AzŒ³sbò´.¬™€WÇ+˜@{GÃ:b„kþªý^‹ìE[D!ˆC|êA[Ã(4À“,~•B€ïCùni¦–Á:Üžšj?ë>Ðí΋u–Ô‡_L7áÊ9cÒåµÏÀWB€çWÕz n?ÐÐŽê蜭uÇ ›ÙD›Žˆ§Àø«Ýõþ
+MhÈ6Œ$ÇïúvaÖÇ<N„àr{ªÆSF¶÷S6Ä@¹u"õ„už{êš  ¸nMð$;f ƒ:2KY}ÏcG .“{rRi¡·©…ÐFX“tÂŽèÈͳv..´.Cu/‹Uå®jAdÿôÅW_p‚q’ø›_am²c|Û£ æïâÞ4!_z+Ü%ØfŽ¶5°LßÎó?[Úˆ</ 0/Ø劾íÐDÈð¾•ÙØÜŽ#º7¶ÍÜâU€ý¼0eŠ’ 
+iŽ› Ç|«º±ê(sÃ;‘t–;³ƒB;æݦ5Û²Ž¹¡0Ò™cº. flãº*p
+P>9ÿ‚™(ˆ$Ìd#Ã727M=Län|Ž}Þ|µ»Ô…˜“¶˜BF£¬ïÛV8®åv û}~Ñ´;Ÿ›éWg™¶æ"-­'n,×f·÷¥lƒnoõP¹Ë ·;‘ë²zŸÚóKY¥y}· 5ÛÖÐliÞliæჲš);j€à6;×÷O—AÛÏì X: ­ ¢ðÏþ¡¸êÃéˆqŠŽüùCç¶xz"æ[¼Xf†L‹öruéüaq—t{èpÐðРìÅ ¹©ö :ÂA;cw;$¾1ξ+0á@È>b)tD(ç¬ #8'«þø}•ÛÛézO±.¾·}.ÛÄoÆðïr~ËÂqË™3”8Ÿ
+"Òû|'¤ L*¼
+í¼{lñ ¢]@¤ÐDZRY7kMþ/ÌŠpendstream
endobj
-1242 0 obj <<
+1611 0 obj <<
/Type /Page
-/Contents 1243 0 R
-/Resources 1241 0 R
+/Contents 1612 0 R
+/Resources 1610 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1245 0 R
+/Parent 1609 0 R
>> endobj
-1244 0 obj <<
-/D [1242 0 R /XYZ 85.0394 794.5015 null]
+1613 0 obj <<
+/D [1611 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1241 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+1610 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1248 0 obj <<
-/Length 3540
+1616 0 obj <<
+/Length 2956
/Filter /FlateDecode
>>
stream
-xÚÍ[msÛ6þî_¡™ûpòŒ…
-F0c ¦,’ìÚKXÎùôæAÓ?®uý8Óu]Õ]‹¬Õ÷UýˆsÉ'™Ofb©ÊÈD!TÉï^¤, T •±Î@þ®D"mݹëy&E4ÍúmVzžÿÆy0ϊ••­.zA_wU‰pºÐ·ëûû¼¼§üÕº^UnÎOgJÓ›Ó4˜VVÀB—m~gÅml"+­È‡jƒ£Å¥f*HãÉL–†a`Ú –L…f’¹ÆõSÑ´>ÉT7뢥¼䯪²¡ª!ô›Ï¨4/9Ο
-2ÛFŸŠimš€_ÉÓé+Ý4Ù½“RÝQåö!·9ýBb~F=SQû éÍeGÓª,ŒÂQÅ4S²»¢º¿ÇeF`lòöaDßaÈB!«C£‚EKÁ‚’T«ÐŸtÑ0Zâ$bq"è8f© S㢥N[Tl’ÔšÒfòð+ìgM¿ù=N–ìŒ2tfVR¾¼‰ {3•æÕB{y L†Ó__¢ä‹«Ÿ(7·cñ+³ywUQT€ Y%†ÖD3Ž ýE˜<E`ž"ˆ‡ÿâ/‘y
-\èVÏ[có(¾¥â"/5嘱šj ›jMz´5Ðb °(=¢ ™( Ëd@[l>2w%X¢¤°õÀ ãPNªî Ë*ˆ˜JD<´¢eo¯˜¬½:@;,6µÊê6Ÿ¯‹¬FÖ3 ÖÅÊ"®£¯jçÙº9
-±wÎN Ñàïº}¨ê¼ÍÚü“•Ðèú“¶¬ã ²m ‘´Gª3PÈë ²Í@ / Ó1d 4ŠQ½ÒXm^Ãÿa»ÈKï†V•C™¦ùºnhÔ]VSk¬nÇÐ>dí àG=)DßïcèHÆÂÛJ!—VÝÛ
--ªêƒMåôçÓ­ûn‘ÉÐJÁ˜Á¦[GÎxkœ>¨ìv.~€ .(%Ðç"‘ŽsÚ| ŒpEµnŸ5ëù&KMß-ªe–—çžô³ZßdÅy
-Ét ‚ý©‘™ÉÁáCXãÈŽ˜9ìmˆC¾ªš&ï6h+šul—·gŽ}W~~UŽwo²èØÇWÛCÿPÏÅèÈø9^t¿ÃàcuÊ’´?àûœÅÜk7> ¿²Ý|MÆS¡8‘âi»‘
-f,¢ã”(ŽT¢·:ß²ã€%AœPb1ÐPHŽ’õÓG(ÅúÝB>©D+Åy=y9×_´£ºó¥Ìm^¾å?¥oâßòæq–ÄàÆŒê'T0‘XO˜ÒÍžYX óåGé¦ØbÂææEó‡ÍME,áB~ñt±ËÒÎÇŽÃÑý­Þž—Î{?üöqxÜ›—&ˆÜw!Ò»ÝvP‘Ž!üµ¬ªëÕЗÇ+Öô¯®ýbaÛº9dàÓgî·Å‹ßãÖùoÚwÛö(kàÚÍMÀô”5x0û–ÙJ%,q´‡­RÆU“ rEašŽÀ+
-X5±–ÀXͶº?ǃÓå¼Z—­ÕßV„7pt{ÜÓö$!JO¾Øž^;o Üù¥ó¤æóqóßv>‡•·Ž¶Bˆã8¾ÚåÕóW??!|+l·÷ OaÞÓ·Œy¡
-ÕZq<Û5ªµ×£Íã">*<Y—ú•G¦ÛWô–›¼ 0rŒïAâ\»=ÛS A\ugHÛ.ûÀ zÏîöñ ¢ž¶+˜¦"üºÎŸ§³oÙ¹Àà±<@§AÂÂT¶èÂid}D,X+·Ž/³¼X[] iΣõD÷™x[ãîýð¨k!ðÉŒŸO…{Û`çe”:@’»÷Öù¡awαš:¯ F•›{w`ý}êõq±uöX=|Ë<($P] ž<ó“"¢—
-æ6ØÞ‰Ž
-lªÆV ·H¡kùcTä„EþëMÌw/ #÷ gÜÓ‘«Ð.\07ì!9¯&µý^m]FÓkCø¶jK©RßÛGaøµå!cV³ÆƒfL™—z(æ/^¿º¸º¶¹Ý%:J«Z_Ð=ÒK^O‚7ò‘y¹ÃÑ»ìÏÕ°úk8ø¯iXuVã†ì_Jz{F•mÂÞ¯Iór¸±)óˆRuŤÄQêÍß´îô«úáKåže«„Ô„ØØŽ]o¢{µ1p÷„oýÅÜÅÕîtl‘ßaót»;Ær»ˆ÷Â8¿k1¼|ǘuï¡;­˜÷gR±$QýŸ.aßÝ›Úm™oÛ¬ÕË.Êû¡ÎðVü˜W÷»î·录1F _éCĪÂ.–¡q„¬1ëÅ6Ãû‹´»óÅàpÅN<ºú 6¯Ê»ñS*
-ѪÑY힇ÚÙ‘Ïñ;E[»ÙW|ä˜Ë[.ªÖꂼ}¿ÍØÛ p{ð^FþÚ…Oz×Çþm÷¦ÑœãþBçVØAá¼d²3r÷G8»Cÿ7?â[4endstream
+xÚÅYKsÛ8¾ûW¨jKWY Aðé=9;ë©ÄÙu¼sÉä@‘Å
+E*"Åóë§_àC¦wf6‡M*a£4€F?¾†Ôƒ¿jFn”úé"N7ôT¸È·gÞâúÞž)³´ƒ–ãQ¯Î^Ýèx‘ºiäG‹‡õHVâzI¢Å''r}÷$xΛw7·oÿsuÎÃ퇻ó¥zÎÍí»k¦ÞÞ_½u¾TI¨œ7ÿ¼ú×Ãõ=wE"ãõíÝOÌIùó‚Ðûë›ëûë»7×çŸ~>»~èÏ2>¯ò4äëÙ§ÏÞ¢€cÿ|æ¹:MÂÅž«ÒÔ_lÏ‚P»a µåTgÏþÝ õÒÔ9ýžr•êÅÒ¬Z{q]^Ãu…ôU„>Yv©¼ÔUðÜN軉'ý¥øjt)
+¦I¼ˆÃÔ´¯éRLQ·Ë¢l³Ue
+TLòG“@9qÄ°Ž~×<‚V½Èùz0ûÒ´Üè6Y‡Tèl²o†y+cj¦ÖÍþ\%NâytÃc­ ÝUY)cºûÈDq0¸Xv©”›ÂÁh}š¦NWnMsèZ°­CçaS¶ÜÁßÄiÖ­,E¼~òÆ0Aû2Û¦“­Ù3{‘T7ÝÜV¦¬QqèÜß¼a¬'@*ròf»«Ê¬î¸ãW/ôP5²ê˜=µLóÊÝa_‹´È¹ùp¿œ.È^óþú-ß×è¾Ó–Û²Êö̤CóšUœáj€Õ…L†SË|ótÓ–Mݾ¤b+Ö$XÇžsÜ J¥ï‰©ŒO :*Ž<Ôè±kš4 à’¢X;·2™w2³ò‘ ¥h/P#>¬B·ÅŽýv¼Ü£éȘ€C†ßáê¢ÄÚ#°×YYÉÔ†¿¼ßv×b"²Š­³6!| Ú„†&
+5€TÑÔ¦tîÎï íò|$‘(W'N……ÄÖ´mö(Ü<«™Èª¶aj%]dÍZƒŸƒ*™ÜeùÓYm;»úk#ŽˆÆžjQÄ®Ùwl‚i0R"ô¯ÉÜ€[7õ’M¸bêÀ¶¦ž›9ý‰~ÀÚMs¨H×)y¼ö²3-_$°è~à[ÀÝî·emxû*ðë ¼ÅnÚÍZæmfnzØ!† ¥ú0³`e>6¤—~‡Ð±ã5¾™Zî”´
+!#¬ìÞÀßöJM‹™4ð‡óÔ§<ˆ
+ˆ”à·Ü:n„ „Ħ9r$‹S7ðÓÓ@Öo =0eþ ²°áPuÜI€uàœhyhØû\€'*J<?wd2Ç€×ïi"jÌN^ê¼g R(y‘AÀ‰üxa!*lŽR<ŒijΧ! @Ç£‘„w,»ÍÌ}‡¡*åËÒÌååP‹dT™ª’t¶L"7N48£ŠÝTû ¸Г€'L$ÏžfN5ÎÁž³)ñ  ² f˜Œ4ݾ‡ÑÁ¦«qÒfºÊG(-ÃÐùå%_ݾc®…
+ceeÂ[7UÕÁI%šzŸ˜=4¯J‚¸§Âx
+z^ï À¦
+J”Kï¢Æ2oÄÜ=­²„ì.ÕEV¬xØR)FG ã2õù0ƒzMz,CÏI$ 2ÇFL>h©F Ó“²‡äMÕÈ“T‡Ç“w®Øɘqjª=ËšêðFÓ(BgŽ40É`Ü&¢šñΩid)
+†ãõ*¨^úëev «Ô¸6
+á :)rP3uV1wŒr°“ŒTeìÄÆv‰€çN…Ã(Àcw_ÏËü^ …x¤ÈœgLÊ»qÀÇ6ü¹h&n¤6Ø3Pã8LúxÏõ­‚£Ó<ˆëj-ÞÌ埬A‡µmã¦Fy Ù½’±1’Ú>Ñ “!Òfø>Á½ÓÑšµü¾ÞPõ” ìž”ÔÍ?¶Qr‡Â×¾Jj­œÞó±C^û4•©Ô=..i*ÈÞî:nXyÛ¬Àç°Q~ðÓJR"vŠACrÐ}ªÄpÈ4–“dc íl¶6A /”—œf•­¨¾
endobj
-1247 0 obj <<
+1615 0 obj <<
/Type /Page
-/Contents 1248 0 R
-/Resources 1246 0 R
+/Contents 1616 0 R
+/Resources 1614 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1245 0 R
+/Parent 1609 0 R
>> endobj
-1249 0 obj <<
-/D [1247 0 R /XYZ 56.6929 794.5015 null]
+1617 0 obj <<
+/D [1615 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-326 0 obj <<
-/D [1247 0 R /XYZ 56.6929 769.5949 null]
+438 0 obj <<
+/D [1615 0 R /XYZ 56.6929 510.1455 null]
>> endobj
-1250 0 obj <<
-/D [1247 0 R /XYZ 56.6929 749.9737 null]
+1618 0 obj <<
+/D [1615 0 R /XYZ 56.6929 482.5541 null]
>> endobj
-1251 0 obj <<
-/D [1247 0 R /XYZ 56.6929 433.0023 null]
+1619 0 obj <<
+/D [1615 0 R /XYZ 56.6929 117.762 null]
>> endobj
-1252 0 obj <<
-/D [1247 0 R /XYZ 56.6929 421.0471 null]
+1620 0 obj <<
+/D [1615 0 R /XYZ 56.6929 105.8069 null]
>> endobj
-330 0 obj <<
-/D [1247 0 R /XYZ 56.6929 173.1316 null]
+1614 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-1253 0 obj <<
-/D [1247 0 R /XYZ 56.6929 148.792 null]
+1623 0 obj <<
+/Length 2444
+/Filter /FlateDecode
+>>
+stream
+xÚÍ]oÛ8ò=¿Âo§
+òÇÁåG>ÉáØ?p¦ÒÄL¾À€3‘¦r²<ÐF1£•
+ÅÁ‡ƒ¿w{³néØýi.˜FÁM bköoK[pØÖwMÊâØ$;»N…Š™61Ê„'LÊ­H´è‰DhÅ¥Ì$:VIåd².š6[·x7?HÙÇ[‰ŽaÄ»¸)§°KTm–WÅšúõ5µ³¯³EÑP¿½ÉÚÐóKÖ‡"‰Š¦^܆…íº,òþä²n äv›
+ÁRc¤Û¶)Ö°HÁ#$lxê;~ç³ ‹mj=¿y½ÌÊjäXš³TÃÚ¿ëª
+S?«0-gškõ0cnÄÒÁÛrYÔ›Ç
+bW'Lè;aˆ4mÊjæ‘Û°jG°dV”·èM•›Q7ºÈš–baßÜ#¬Þ-<—°‚i>c¼³œ3+“‡ž5"=¢«XŒvÂn£0í
+©»‡
+4i½~œQ)-;£Â¾“/´H
+gveÄìÁ´Ôö›UùˆDµ/¼§)ÄVÇtÌŒÏ'VìÕ1øÏ„µå>üŠ‰¥€•_=ÆQŸdåbãeEojœ«4)*—ÞS"¸ïwpü¢ö"p ‚ZŠSO. “$Mz¾<
+׎GÅ}!„
+G
+Sm8ÒÂo[Wø䉽›lµ**ê—cÙÈ4I>™?.>x¥$Nö«{_‘žË#nþú’€kbï|Iø¾UaS¦b ¥,KâD÷¿@Üù¡8 É4ž`>Î$Wº3©Á}†Ï$J@‡“A¹wÄà‰¬‰òâj3'Ø¢¸- ÉÁÚHQS¯ |SÎ1íćí˜oé4þåÙX 44Ê<Áö¦n<½eš°Ööy4åXñØ]­Žðz>wU L\SÀœKŠG¬³«\|ÁãRf×ûp|~:ûû åèôFµÍå„ÚR¯*æàn=|'/GP³Á‡xWP5žÌ?Þ¼wtzæ¡Ûç ㇎М&sgÑ=
+=ÎG<@xñ`aü?hÕ÷IXÿ%,˜„u'a=.a
+endobj
+1622 0 obj <<
+/Type /Page
+/Contents 1623 0 R
+/Resources 1621 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1609 0 R
>> endobj
-1246 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+1624 0 obj <<
+/D [1622 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+442 0 obj <<
+/D [1622 0 R /XYZ 85.0394 220.329 null]
+>> endobj
+1625 0 obj <<
+/D [1622 0 R /XYZ 85.0394 191.1908 null]
+>> endobj
+1621 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1256 0 obj <<
-/Length 1976
+1628 0 obj <<
+/Length 2008
/Filter /FlateDecode
>>
stream
-xÚ¥YKsã6¾ëWèHW­0Àçæ4™±'N%ή휗‹&! >’²ãd÷¿o7 D‰öj<5UÃf³Ñϯ€Ìç>üãó$d¾Lƒyœ,ôy8Ï«™?_Á·/3neNh±/õýíìÃ…Œç)K#Ío—{ºæ' ŸßwÞ§>þëöüúl!Bß‹ØÙ"Œ|ïûË«ÏÄIéñé—«‹Ë/¿^<‹ïöò—+b_Ÿ_œ_Ÿ_}:?[ð$ä°^X ¯,¸¸ü霨/×þùãõÙýí³óÛ!–ýx¹/1?fw÷þ¼€°œùL¦I8†Ÿñ4ój„’…”ŽSÎnfÿî}5K§òÊ„…‰ˆ'ð©†)‹¤&ÿýcøp!øœs–†¡@Q¾b–D24B˜. K¾ï{ås«:ÊÂMŸõªRuO¯ŸÕo¾/jÝë¦&NVDüÚe+e-‰=ŸÀ™Hyl Ý®ÕàÎNˆ§,‰ŒeÈþ±*°H¥°RÝÎ5)¸—75ú¶Ú¶g<ñÐäö`ÎuVÊ÷:Õ>©Ö~n處£r«/³2z”zµîŸþO k¦)­²A1à 1&¤÷›ú7JB(>K°LQ± Ž9“>¶«9×ûÕwò‹ý¦ú£ôëÅ4ݨ|@½eÈ’ùb
-Œ›ÖŽ³lM}¾º!7†ÎMÈ€!Æ…Ød¹ÂÜÉÄÃMB@#´…¹"ÂúµiêN‘¼/éåÑŠÁéúö,ñ¶9UÊ4…Ój…:³W!Ueumâľ숗ѣnÚ*³Ú)`@Ú·´Ï×f’ ׂ#”‰]!Sav,Ÿ[¬Vƒ1V¥çØ;tJéÛ]>j™Á˜&Ê>Rnv…é”Î æÛ`rÿû†¨ƒ}ÍrðÚšÏj’Q- Òv°:qßêÕÊš*¾bÖþyÆÛ*kóõD HÎDLÌZ$&(|B#맬ø¶Ajò8atFÑîÜó>Óv[Ãh·-|P}þ¡5Å
-…×ROMÑÝÞ1Ø5S,™w;¦¡}Š×i$˜ˆ"ç ®TÿœP 7aŸ…iäCb© qøÉRüj4‚îHo¤Ó{/pî„ã í©û©£‘]½nº~7 ÜÛéëéJ¼ÐÅþëƒ.ÞÔ0ò¿Ð­Êû¦µ³éúp‚q˜#‹oXnŠ¸øïí§¬yÝ£íU×e½È[U
+xÚ¥YYsÛ8~÷¯Ð#]µB
+G«æÓÙü ΤÊ™J±‚%A ' úÒ2($d…sî•O­î(Æ›>íu¥ëž^?ëß8—uÑMMœ´Î‰øµK×3öä¨`|ËL&*2†n7NHŒ„DÂâHa,(CöUI(y‚Y0RÝÞ5_
+/kjôm½kÏEì¡ÿÈíÁœ!ê´2÷:Ý>êÖ.7ôLËÎQ™Õ—Z )=Êb½éŸ4þ%†5Ó”VÙ 0‚@’¾÷øÖ‡ðP‰d*ñ‘¯˜ïG!Ö‰ÖÚõ‚ˆëQaør,Ou'çH+æèFgK4Zü€Åœƒ¾
+°Nu‰ò D‡~Æ1S!‘”Ì¥š…ZŽ¥Ž½;Ò…Ö$H
+nþ±ÓW›zÆ»\£nè‰ÁUXÑ}¢ò¿`·‡#™D
+²à„wÎ4Û, ¦QÈ€«ø(¶¦*úÞ˜ÂÑ:õ9OEY… bæ°‰TÛa즳˜0a5‘Ófk“â Xƒù¬’Ðbè±ÐOs ¦Ðÿèh2ö½‡¢Î;")Hío|¦ô(‹sá0¼i"ÇÞ(n&
+Œ›ÖŽ³lM}¾º!w…ÎMHÅT »3Í4æÎ=Ü!¤4B[k"¬_Û¦î4 AÀý’^¬ ™®oÏco—Q¥LS8­V¨3RUZ×&NìËŽx)=ꦭR«‚&
+'¾vþšöµM«
+Ì#
+ˆoƒAAÔVˆ1f×þûÃ\ê–ƒ*‚»%Wû ª2xâEW¼|ÑuÚgæ4\ö§)ÌœFY6OD"ΈG¬©*çI§­“æÄâf¢;ê´+Êg¢q ¶«–3Ü«Hs¿{8ˆ¶+S7SÿÕÔv|'Û†t ×À&»Ùb*O€ëë?n¨»h7Ö¹µÕ1IÌ ã&¿
+T` à<›)ŒK.æN´£me°1é³Ègo,v‚Cgå/ÍØP2†Î„]©ÿ:£îÉœ Üì'§•!±ÔŸØ|Ò‡"pzî¹#‰´ïÓl³ÌàmvCÞ£‹¶·¾Í 7û9^wMKŒ^îáP g;Þ4]¿Ÿ2îíÕï'ÎÓ}{Yäã×û"?݃¼huÖ7­08¢O ¦ÑòmŸO|‡Ó<Ì| jºåw¸a°´ü\xó·=Æ°îºt[ }úðö8Æ:²VçÐ^EŒ¨BVlÓòT_ÜömJcè·D’oÆ[ÅýYøÖ§§ Ê€¹*Jýölæ»jûÎOñ:l€pòçS,é
+§ìEf;ÿYw÷M{_7'XŸ|þζEþNçù;˜õú–Ow}î7yØ ð‡ô™Ÿ2ù°£}÷ïõûÿ̀ÇÇrþGQÁFƒëý ;ü°ìúÿ
endobj
-1255 0 obj <<
+1627 0 obj <<
/Type /Page
-/Contents 1256 0 R
-/Resources 1254 0 R
+/Contents 1628 0 R
+/Resources 1626 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1245 0 R
-/Annots [ 1259 0 R 1260 0 R ]
+/Parent 1609 0 R
+/Annots [ 1631 0 R 1632 0 R ]
>> endobj
-1259 0 obj <<
+1631 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [519.8432 682.6714 539.579 694.731]
+/Rect [491.4967 730.5319 511.2325 742.5915]
/Subtype /Link
/A << /S /GoTo /D (lwresd) >>
>> endobj
-1260 0 obj <<
+1632 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [84.0431 670.7162 117.8035 682.7759]
+/Rect [55.6967 718.5767 89.457 730.6364]
/Subtype /Link
/A << /S /GoTo /D (lwresd) >>
>> endobj
-1257 0 obj <<
-/D [1255 0 R /XYZ 85.0394 794.5015 null]
+1629 0 obj <<
+/D [1627 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-334 0 obj <<
-/D [1255 0 R /XYZ 85.0394 731.9325 null]
+446 0 obj <<
+/D [1627 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1258 0 obj <<
-/D [1255 0 R /XYZ 85.0394 701.4683 null]
+1630 0 obj <<
+/D [1627 0 R /XYZ 56.6929 749.3309 null]
>> endobj
-338 0 obj <<
-/D [1255 0 R /XYZ 85.0394 475.6865 null]
+450 0 obj <<
+/D [1627 0 R /XYZ 56.6929 523.534 null]
>> endobj
-1261 0 obj <<
-/D [1255 0 R /XYZ 85.0394 450.9966 null]
+1633 0 obj <<
+/D [1627 0 R /XYZ 56.6929 498.8411 null]
>> endobj
-342 0 obj <<
-/D [1255 0 R /XYZ 85.0394 393.3855 null]
+454 0 obj <<
+/D [1627 0 R /XYZ 56.6929 429.268 null]
>> endobj
-1262 0 obj <<
-/D [1255 0 R /XYZ 85.0394 362.9213 null]
+1634 0 obj <<
+/D [1627 0 R /XYZ 56.6929 398.8008 null]
>> endobj
-346 0 obj <<
-/D [1255 0 R /XYZ 85.0394 329.3761 null]
+458 0 obj <<
+/D [1627 0 R /XYZ 56.6929 365.2487 null]
>> endobj
-1263 0 obj <<
-/D [1255 0 R /XYZ 85.0394 301.8169 null]
+1635 0 obj <<
+/D [1627 0 R /XYZ 56.6929 337.6865 null]
>> endobj
-1254 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F21 714 0 R /F22 737 0 R >>
+1626 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1266 0 obj <<
-/Length 1168
+1638 0 obj <<
+/Length 1135
/Filter /FlateDecode
>>
stream
-xÚ½XÛnã6}÷WèÑ.@V÷ ö)›:iÝlëzŸÒÀ %*&B‰Z’rìnößKYK‰ÝJŽ$J<3çpf8¦¡éêÏкh^`CG7-LFºö Þ]ŒêPÚ_}œ~¾²<-€kºÚ<naùP÷}C›Gwcšp¢ôñå—Û«›ë¯³‹‰gç7_n'ÀtôñÕÍoÓòîzvñùóÅl ß1Æ—¿^ü>ŸÎÊWn…ññæö—r$(/G@gÓ«élz{9ÜÏ?¦ó†K›¯¡[‘o£»{]‹íO#ZïhOêA‡F˜Z2² :¶eÕ#tôçè°õv7õ ~†MË5h-}ºº‚òœ
-CœIU3ÂqtBucü ñh¿¼å]‘%ÅŒ ²ùÊèŒy;ßËKdÙEQ¥ã]ƸlÆ‹‡ûò©2!¬íí.?úè“«2¥j]ø¨äæëÆ£¶¾ïÀL ŶÞa´×¥\­EQ¹þîyW£tàúq/d®U( À ¬’m#MWpG%M¸ÂJ•VõÝó;–Æ‘ºø·üì!
-†´RˆÐÎ
-z¶eïPê´ª­Mk ׃–gÚõßSlo1¯{a :žmT¶c¶½í¶nÏ•'¦38ÜÙV¢öRÂò íÛöpoŽZ,Nñßé â› ÷'©¶Zß7›s@Ólšž¯È)Ê©‚‚­¿ò¼>U|íú?ËØ̈endstream
+xÚ½X]s£6}÷¯à1~åÃØ0û”M4;ÝlëºOiÆ#ƒˆ5+ tÛÿ^§†xw2Œ@G÷]]d–ú³ ß3-7“`dz–ía2°Œgõìn`ï€ò%Pëã|ðÓ­;13;cc×°|Óò}Û˜GW7¿\ÿ6ŸÎ†Àñ¬«±9Þغúxÿð³n ôåæËÃíýÝŸ³ëádt5¿ÿò ›gÓÛélúp3Û÷lÕß)Nt¸½ÿuªÝÍ®?¾ž ŸæŸÓyÅ¥Î׶ܜÈ×Áã“eDŠö§eºï[uc™v8F2y®é\·l!ƒ?¿W€µ§/]Ûôó\ßô|gÒ"àÈ® h[¾Œ‚‰1ñsì:î‹‚C0¶¬«¿E@H(±8ºqÄ‚ñeôýSÎW
+lÛ <Ï©ÀL®
+ÔƒeÇÇI oÿÑ´K Ë -($âj
+ÉþŒ(9
+3.Tjv'ÈãÐq-È}Šìîô2¡ò<)c¤‡¸jmKõð.æ` êŽñÒ5æ,ŽcÄ ËiúËò¬vɵº&Aà©ö9Î@…@!@.I‹îHpe5k§ÃUfÈN‡Ö†M[C#t€>@•Ø9Šm¦b7iò¬Û®ä™Z‡†+V(Vú*,pŒØ^’C.Õ‘ç-zÚCM†(•ÊêSÌQÔÃ8ßBë•/ÀÆ\Ę y‚û ;×ȈiùM_ÊüM0Š
+eSÆeÕžß<é»bÓ4Ëñ^.ÿž£O¦PÙh¸VróMÆɱ¾½€9®ä5GC«ƒ.z¶¹)þ\™g:°F„çqÏe.U(2¬«’¦© håQH®R¥fì~§¢ÑRî+µ8[¤sŽ¤SÉ@›)1i4àgÊ8:µÀZጢ,U{^ÈxôŠ×;·ÞÐ1Ù}¯ÁZ(n1‰Âj½vñ Ý_m<è™c¹ïî%[]ü@΂o~ü˜xI0}î®R^oE[]Œ6¬ïh—;ÇÅ
+¸Z1U`å‚„X$PÍ ‚Ks>´V¥÷ôO`‚rg¿l¨ „jn¾ò;ÃnQCrHE\ÚéÅb>ªz/{y%²TU|—ž;
+Š:£Z­À/µ¬ÅºÇG´®ÎÔeö9Ä¡ êQäézH¦ü»^;ʇ· ¤Êsæd¬tYõu¶Íˆ=•+$°¸˜ÞK¢Ê´#—Ëüûl3Y”‚¼¤j†š·tMã SŸ{ïD|á¸^ÛI™ë™ùñV˹–U• ï>E;1Ž&¦ëûNu@æ8µ2×›¾LÊ rΞ{yuÜö:ôÿ
endobj
-1265 0 obj <<
+1637 0 obj <<
/Type /Page
-/Contents 1266 0 R
-/Resources 1264 0 R
+/Contents 1638 0 R
+/Resources 1636 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1245 0 R
+/Parent 1609 0 R
>> endobj
-1267 0 obj <<
-/D [1265 0 R /XYZ 56.6929 794.5015 null]
+1639 0 obj <<
+/D [1637 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1264 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R >>
+1636 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1270 0 obj <<
-/Length 1164
+1642 0 obj <<
+/Length 1187
/Filter /FlateDecode
>>
stream
-xÚµXMsÛ6½ëWðhu(>’˜œWviœVUOªFÆ"r¢4ýï?$‘e‘t<>˜¹oßb ` ™?ly "ÊmËå6d3+XuoÞÝŒpõ Ø}ê_½~¾¦®Å!wˆcÍV5,"ÏÃÖ,œ_\ýzùûl2ÂÐ…Ç€9èâííÝ/å/ÿ]}¸»¾½ùkz9ví‹Ù퇻rx:¹žL'wW“1ÀÃÆžT' ®o›”O7ÓË÷ï/§ãÅìÝh2ÛûR÷#š;òy4_ +4n¿!H¹Ç¬/悘sb­G6£Ù”îF¢ÑŸ£?ö€µ·…i›~ŒzyÄmÐÆ51%Ðs¶\Æ¡C -œƒÐEš(]>ý*Ÿdº< Ï}µ06|\ 0tmÊ
-ˆŸªW3†­Ú …KëÅ»x³ÏM¶9´)wÌSBêÔ>o„Ú‚,Ù¨@€Gç)Ë:_g釡jæ.$Ž Å)ÂäˆpÉÈ„’"ó¶Ñ0±ìSsÛíb}¯˜átÇ×™äîŠ,ë¤u¡íÙ¬è·èG­òãWÏ& XA9&ITŽoE¶LÔ2NX¨Uå¦=ÈŸ*ÉãÍú£PíäˆMúZÈX õèG=±ÖþW •g+¡€–kd|?‘lôKhÈ0êFã D' Wt‚ ’"î“9F~šÚ|̃Êä£è>}ƒ¸™\úQ¹82Ë¡çü5{)ú’ÏU‹d¦EœlD_ÑwA[%jíå~ `>ø"ö¨
-w¼­Æ% wa[M—K “^žîm¬­½mj|{‹¼S©Ü¼*ÉÔ>®Ï.‡”¸mõ™AîºN{mœŠlUq­5²ÜÏpžM¶Ã¦jŸ j£J…„º¼}Ë4è%k íd%ˆC‚k•µ…ëYi Á»Èy%ºÄ…ØöÈÉò¤¼}¶Ë8Ñrµ¡ˆüí®TIf-”Ú§Bè”6Ž ©KìS‚±—¥K!µ9?Ïò|Ò2ð’s Iq8®þ“xvŽ‰e (‘Ê÷¬®žc;`!l´ÿul,äוQr2ùM èþ1qÍ{0ÏŸ–Y*‚ ‚Ä´Ç–å6ý¡ßÓ¾áÁJF»¦ ÿä™öƒO/aDÂe|º·¸ öÂWú£ð5Ø#f+?CŒÚôG2Ȇú “41˯™-Õmiš¦àa™w`Õ¢^¼yŽŒIŠÃ·/‚R*$*ÜõfZ1räù³oŸ¦æ!COËùæ´¡õCOøÁÃPã¶Í6]Þ|J½m]
-•PåE÷“yeº/²$NÂf?%ÿïëê…OAém*ñY˨$é}˜Ê›¼`÷ØäS•<Ê°£ÓQ΂2=ÐZ«¼P
-øÈRÿ¨eêìD!žX™
+xÚÍX[“›6~÷¯àÑîŒT]‚Ù§ÍÖ»ÝL³i\÷ÉõxÈ»j08 oâ&ýï°Y v·Óñ–ÄùÎwnÒAØ@ú‡ fAË!ŽÁ2„™á­ÈxÔkw\¼v/ê[o¦ƒo)7èXÄ2¦Ë
+– ‘mccêφ$p¤ÐðæýÃíýÝï“ë7‡Óû÷#@ÞÞÿ2ÎÿÝM®ß½»žŒ
+ +  gk
endobj
-1269 0 obj <<
+1641 0 obj <<
/Type /Page
-/Contents 1270 0 R
-/Resources 1268 0 R
+/Contents 1642 0 R
+/Resources 1640 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1245 0 R
+/Parent 1644 0 R
>> endobj
-1271 0 obj <<
-/D [1269 0 R /XYZ 85.0394 794.5015 null]
+1643 0 obj <<
+/D [1641 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1268 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R >>
+1640 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1274 0 obj <<
-/Length 2424
+1647 0 obj <<
+/Length 1337
/Filter /FlateDecode
>>
stream
-xÚ¥]s›HòÝ¿Bo‡«af>*OÞÄÉyïÖ¹³½uI*‡ÐH¢‚@ÁŽr»ÿýº§ö*Žý@ÓÓÓÝÓ߃Ø̇6“¡&<™EIàIŸÉY¶9óg+X{wÆ,Û¹Cª_îÎ^¾Ñ,ñ’‡³»å€WìùqÌfw‹Nèqï8øÎë÷×o¯Þý~sqÎÝÕûës—Kßy{õÏK‚ÞÝ\üöÛÅ͹Ëbɜ׿ø×Ýå -…–Ç/W×o“Ðã¦7—o/o.¯__žºûõìò®?Ëð¼Ìx¯g>ù³û×3ßI,gðâ{,IølsHáÉ@ˆSœÝžý»g8X5['íÇ|‹O0`ƾúÀ*’‰
-.Œ?œ»¡ï;›¼tk¥ë«ó"\Ùnæª&ø=>áAªË˜—HÉG,Òo?Ëb[Õš |û_¦÷°ážt±Èu^•iá.ëj㦭^ÓÊN5Ÿ«úsY,ÿW–fkõ\fuZ.€ÇBÝç™e²Mõús™vÖ9áthT£…Ûäßí6„>7[•ý€kt¶v7év«.²VM£šƒƒâŸZ-U]“UÑZm>úÒ'è‚Ø7ø!®ß__ö[Ø gW‹²qÛÅvptŠ§ƒñ™[ëªÒàµB­RŒ·*‹­tz}ËŠvaÙþÏr§yc£÷ÏNÊ©nþÚªzWT«çÆÚ"oÒy¡Ü´XUu®×ë\À4/Gšö$¯F‡:D[Ýÿ<%k(@U‰*üÀ Ø“¬Pi™—+7/µªïÓâ~O>a²"W¥nÜ­ª]ã›SËÙqò>—ÓÁ±0Ç2/«ÒyŸ{Z}ÓÔé&ÕÉüÔf«wnî”ø¡ªDÛ³ªÔi¦OÛ?!þ{UªæÇÃf2ð÷ ÐUÚ类ܲr›*uµ.ž«Ð›S[ˆË…—0?ó„ìƒÅ—o9›õè%
-–Ì‹ƒ Ÿ€XS̪-–¬†¦”[jµè£×7ê£ïóÒ48Â@ƒ"à÷&])+Š&Ä#χÉȺ[«^Ÿ=‹½$I" FšNƒcff#!¤¥kÊ á4J7µ[z®ŠjŽéðþXð¢+|Î\Ù Z4ßÑÇ8À»un·ܤ–›bZ[9¦Ô”)rŒ”¨6;kªC'ÅGä@& mWm’uq 1…=B™8WKBê5$‹EQ9DCLL6Œ½8IØ_[6Ð-ûx'¼L²z#¢ÀyQe_|Èq`B
-±J8¢%\CËhxD亱1ë‡^,“dœO µLÛÂÝC^wÁÝåÍÍÌ‹ g‚^Gâ‘9—ˆÜ!•sGfëfðžÊ(•×*Ó”ßÉIä…A?-¹#š<ôó9ÄŠÏÇ¢1k\Á¥óPÕ_ µÑ (dâ
-à{ßU´¢M"´?1—1fŽ”0k ¤è"@€vjÂt=6U£ 2¦ãÙ…ªÕÛÖ.Ñ¡šîEúÊ[y”8£ÑA'@ã-¼º-'r îapñä6ǨÙrp‹)/QwN„&Ï)bnj
-¥~Q;÷ÑbÅXäÉ(xZzG4!}T¬8‡U)Æâÿ³6©Íà®ó&ŒšT°üÄYì =òŒÛí"5e`S³€ QYÛ÷6F#Xó‚j9—ùGÔà%›žtÛ΋NN*p>:(>ðTß“:‚;o®oo/_ Æ$`_Û,Ìí®eÕ–˜bB
-'_n
-6§‰»ó„;i ‚bZÄÒ‹DŽƒº‹áÅ5ˆ½PF]m5ÕâQ]Bü­‹wdz£EÑTãïÒÞc?ãÁdŒ¿½M¿ÿ ÷Ó?ñíÿÄæÇ|ºRñ<«ž+àÇEÚþx¬úÿ[@•¿endstream
+xÚ­Ûr›8ôÝ_Á£=³¢,.Ó§4uºél“nê>µ ²Í#Šd'ζÿ¾G08$ÁnœÉ ç~Ó‘°aÁ6|bZN06¼`l #\,c ß> p‰ƒ*$ÔÄz7¼¹p<#0×vé¢ÁË7-ßÇÆ4ú6<ÿûìótr3B6±†®9Bĵ†ï.¯ÞkH ç×W—¾Þœ¼ñpzy}¥Á7“‹ÉÍäê|2BØ'èí’×ÿLôêÃÍÙ§Og7£ÛéÇÁdZÛÒ´[Ž2äçàÛ­eD`öÇe:OŒ;x±L¶±Œ‰c’±ãTdðeðoÍ°ñµ íòq|“ø¶×áÀ1n8[¾ŒÏðH`ºŽíü6B®e E¼DðŸÆéÉ]Æ44ݬç,×ë·úq«lÁc3 Än2YÇ)Ê9—¢I݃n#Šï¥ 3žÏRþœ\ܤÏr¾£N=¤çìç† y"µÌ•(ÌHd4d§Q8-r&VHÆë#@ï_I¡‰ÌwG±Àõ8–EK‹ŒçR¯âl¦^zÐÐ(ŠeÌSš EÎ׈näêÔxò
+i¸:&¸í£i<"¶« ɨ\ÍRZy§gp - RXU·l&2®Ðšf‹ ¹"˜8>ñq"¤=üOÑv¬Áß-buzé—~Ì¡^~ (¡aM“§ÿÕqR&Ì
+»fI,ʬùÝà†[ê}ùyë¢ j'¾¯Ø+:Û1ÕÉ»4
+“˜¥U³;M›ƒøª˜¼šqì>L6{5õÄfQ;§ðVɬW‹ 7¹ˆ· 2%Ùõʵ–)“¦›u†«6îí3*©€Ë·UÚ×æ‹)„BžJÊÛý rå9á2Ù°Ãâ9kÍüZ€«ë«ÉQÕÃ@O´‰²Fëxn{~ÔÌû“¶Ó
+°ùÃùŒ žl«Ì)†V¾‘'åbÄÒ¢©¸SÃJ{¼zi>ìŒ,“ÅìÙ£;¾}6vM•’˜*ÔÉòõÕ
endobj
-1273 0 obj <<
+1646 0 obj <<
/Type /Page
-/Contents 1274 0 R
-/Resources 1272 0 R
+/Contents 1647 0 R
+/Resources 1645 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1245 0 R
+/Parent 1644 0 R
>> endobj
-1275 0 obj <<
-/D [1273 0 R /XYZ 56.6929 794.5015 null]
+1648 0 obj <<
+/D [1646 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-350 0 obj <<
-/D [1273 0 R /XYZ 56.6929 418.3076 null]
+462 0 obj <<
+/D [1646 0 R /XYZ 85.0394 122.4687 null]
>> endobj
-1276 0 obj <<
-/D [1273 0 R /XYZ 56.6929 386.0953 null]
+1317 0 obj <<
+/D [1646 0 R /XYZ 85.0394 92.1609 null]
>> endobj
-1272 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F21 714 0 R /F22 737 0 R /F39 899 0 R /F48 953 0 R >>
+1645 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F21 930 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1279 0 obj <<
-/Length 3843
+1651 0 obj <<
+/Length 3032
/Filter /FlateDecode
>>
stream
-xÚµZ_sÛ6÷§ðÛÉsC
-@_ÌsëzH*bkÝvÓkÓ6óêkÝõÖ0‘±Û?†Êgëú÷Š ÃMoà=¿J™Er¡ÁÏ€!5¢çÈ^2Ê1Ó¹kîGœ‡CNÄ} L¨ü Ùm9Gˆcã°MF:ë8»?:²L»˜‡+ÇP,br0—¿´{j°Ð˾«›'Nö÷÷óÅýí‡oèµ_Õµž‹]]<¬ù‹Í [L)«_ãX6UÎÆ©Ž£<Ó¯¤ìëtÊö\‡Y¡Çû¬²(N“ó¢Ó„èaÆ–Q e(Ûfl Ñõº~D¢ªùwÕz½±öìB1²ì;Œ;Hz`Jï¾vÞ‚˜Þ‘æò3QÃÐ…½”ÇeΉÛòPôîœ4ÚÔܸ
-!tS¶U:Js˜Û0^€Ö[½1ÖØÌ¿´»ß½³” –}»óÞºFñ[.ƒ‰Q²ÂM§òœãh
-¤•Ç8éu:O£4ɲó^rö:Ïe¡B±\UsÒÖ‘ßÁ¦§ƒ/&ÏqMˆx˜m*ãl(áC“{ZàeÕðÑoRÛ¬{sݲÖÚÞE¿3ÚK¡PzE{×í9.Æ÷›íIåå‘I_‘í˜&dU—D&‘#á ‡‡¶E¿rp)=†K<¿xUHÄUt£Ê¢/ŠÎ}Ö2À¢Z
-¬-­%JW5ü}W?5źóÝ yjLJ/Òè™ÍYMC¸Â$3´Û:Àfè—"™ÝÓ‘²N fˆD™†:"[¬ ÊÝÉÊ[
-èN‡PÌËÑó!4à:B—ÅQÕr¿ÃÚñT Mt9&=?Ï51…A<€bZ©Ñ(Ýj¦[ÍV ÏþJ̇·Yíü@ëCÆ…6CÔAÿç=¨ïêÊw=µ‚c==ÐkÓ¯_ˆÄõ)ˆHÙRlÄcI3´‡ÚµÙ·u›Íx“Ÿ'Юˆ¡€NR—‚0×oÔô)¡ÎÂSÂÿÒ5hpnNUêÏO6¤©ÈdòùN¶ç²8èU$‰'<1lÜÙ)x®‰9 Ï‹R€ì©N‚2]œ„Þ,FˆÙD‘àó´=Ñcà,¶[Hgw˜Ñ~ÑÒ“«.`W]SÉO[uë¾›N\s<'KâQÀ#{T)Mb
-& ¤® ßk®ø !üvˆTlЯ¨ë€TRuÂAÓ"CK<5À÷*Ë|>hHKSãƒì Â
-v©öqäp‡@vÈeÕ-wõC%F+5 ‹JJ0¶”®C©s÷tIOízþyøÁ±í‹ó¿‡×mã. “ŠÑ£ÚV@Çb0£#ò\¯Ìãx´ó¡#N#€mœ×™Ðá¸,Hkéîk-°2Ò&=/ÕsMˆ•£³T£ ÐÈåhaf?_ÿôfñî'z±³ ýýæ‚«$ qˆaG¬öp Il»UýlS’,n£O›ÒS¯ïîéSFÙ}»l×,kWø3ã%â5@ŒÎøøb:²ü ›dlÝf¦æ%%ýI^6k·ÎÀÌÌÑðºƒÒ/–:=߃cŸ÷§çx)Ngƒ·TX7bð—™ë%}bŸ½z""`‚ÆÍÓ®+_‚°a:u§¶‡k—ê—íf³oê%I»\?
-ÑR‡3,Ò$nƃÕ=·»zSìê5“›ª*ݨ|µo7èþæÃ>øÌŒn£Û-ÞÝ€1ÛKX!gÝ~¹BçóèèiïKl Ü©é
-\;ºe„€7x½/ûmi-Û„¨”­˜ù?PuèŽ:g§²œ[X¹Kýù”AÛì‹\Â¥CÉ×l`б "ÂÁ z÷+öí˪¶‹…,È
-Î"°½ÂÝÃÞ,!kõuUì»ÞÖ®*ヹ̅†ìig®ÞClÌð–u½gI“PG%Y”àÙ0ÊÀþ¼á_#L@%‰C^¼{d±BGy’ŒªäƒÎh_e’;m$ùðÇ*–BÕ~’Såm[þêõç.'Œ w‰¹nôkŠ ‘Å‘Ö®”ñ¤õÅﶂƒfeÓÑ#
-=]ý‹Š j:›B®ÓIÀsY¤³««Ý®*çOh‰GY F\hÎË÷\f£Äpt¨-Ç.“û+_5[ã¯Aø¦·ÙòE0Zø[b Ÿ”ÈÙ[øÃÆ Tw¦å.˜Õ¬ÚàéUéˆÁ™ Â`
-Që@¾bQÂ9Äö†aYm¨ðºÍ¹7a8qK¬yÅ×±£ŠûvKäuõ\­ùsûžŽ³§áX_P²r·9?BìÉæø1ˆ,œMmCs«¾.×û’÷}&òI2C*éöïúžÊ4Àºâ†/ÕWpÅ£cƒîÝe5ìaðr`tó¥:üð{^øìÁk’ÏAHÐòX&S³{ÆN‡INà’*‡îƒË‘"XŽD´EX„V„½uô
-j«8ËXö–ÈÇ›.ãðR†@‡‡‰RuH›b wxá|û0B&wÿºþøãÛÛ»ã€Ð…Þ>×¥K'GÞݽýñæDx(ënÙ>Wƒ,äRš¯C‚@4ýÃW ë¬=á“ð÷åOÿ&üðƒy
+xÚ½]“Û¶ñý~…&/æ͘
+¡ ¯~ý/
+û§+΢,Õ‹'xáLd™\ì®”Ž˜VQä Û«_®þ:œÌš¥^ý ÎdK¥ô)Pg,ŽddX”ëü°íI®§j»¥Ñ²¤ç¡+ v"¥`‰ñ"‘NÂÏ!…S,bJø˜rXÈTÞ÷ùj®à_y¼¹’ˆâòî–gû©N€C–e±šï³Ý6OÝu¥q°íTûmIoUé&ú†žÝ&o¯EXŒÜB«ú½[Dr˜a‘÷ù2ïJ0¸ÖÜÁÌH˜F›ÜlUowjžê)!PÈ"Œ4Dœ¡¤,ÓZÒaZê€-¢`ùLO{Ä/áMfÁòиZÓs" ¼9a¸É-°ßØA—ïì¨Ù—mÞWMo °o¶ÕÊî¸nZÔ>©¨k¶\ddàsæóº
+œ˜hS>e@j&¤Eéú¼/weÝwh•B"]CÿiS€½WÆͦ==Aým[eG½ó©KeÏOàý¶Y‚qž² žžè$ûƒjKX*ѦG¦ Ó OÏœ”Ž¦JÄæÔRñǵˆ³4åbƒ4"ÉþPò,KÓÔŸ:Âb8%ibàœ¹(biœfãÎȤq]Ï)ÆŒK'ÈhhÂ.PH8Oçqk´´ïƒÇBbcM‚lÊz\î1¯²Z Ù”ŒÎ@
+!„Ãêʬ…È®š™|°nKü¸hdudK™f'qu 1ø?ì!:‡ÐV:Íâ–&Ô¨™VdÅ#<p€î—†OU¿±ähî‰Ú…V\o¢í ñÚÎîG™GÍzÀëJ_ÐB!†ÀdôÃÐ=¹±j´´õänc>ètVKt>·ÏÓõks2¸°9"o­v
+»`ÔVa¨&o|[›¨…ç½Ûap£±;ûœ"Mêæ³CÃWLÝ\ é OÍa[ÐpYÎ×æX# C¸äùÅ-&ùiØ‘ùNäaÈ”ñ&¥YÑÔå<«Y?OR‹×´‚L©ÿ&þå–™œ6ÄN²—;{²_@´¼]V}›·–S4^EÁ!/@5:;Ë›ºC2FeÉx¬<hõƒ`£pxwç"©HwXveOc´X3eŽ
+1ı¯þŸŠ—/&9A赟¿_k¸¶.þòžFÓ@¯9=†@Ç¡5ì,ªë3× fC/˜MZ?¨ÑkKeÌ»¹/oaMOqrÆ µ °cnÚ¦u¹ê}*±!ÆÇ(¦¢$Òi°:´$Gät†ýÚÖ´.O
+ aßû4CŸÅ#u®‚´4ôH®¾H/†¾Ç_CÈuÕg_¢‹SmüÈŸ-³
+_£ …^”º­?—mÖMØ5ù9Vá´t¤]}–\Î˳û¦7¥…r>|\(ëÒ
+î%y=][ÁÔ`M^Z``¨£ÏŽ
+‹rÂÀ,L$ ü]É„
+¿<9ñfžš_oÐ$}ŽH‚MCß3RkŠ
+K/(1ºäÒ[»+Îü(&Ò Éâ‘žŸÿófÆ_©„Ei*ýš”IÊT
+D,S¨IŸŽýeÍ)ëÿ)”o#endstream
endobj
-1278 0 obj <<
+1650 0 obj <<
/Type /Page
-/Contents 1279 0 R
-/Resources 1277 0 R
+/Contents 1651 0 R
+/Resources 1649 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1282 0 R
-/Annots [ 1281 0 R ]
+/Parent 1644 0 R
>> endobj
-1281 0 obj <<
+1652 0 obj <<
+/D [1650 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+1649 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F53 1303 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1655 0 obj <<
+/Length 3894
+/Filter /FlateDecode
+>>
+stream
+xÚµ[ÝsÜ8Ž÷_Ño×®KÓü”ÄÚ§Ìäc¼s›ÙM¼µu5³ê–l«Ò-9-u<þï H꣥öÜM]¥’¦@„@øTÄŠÃ±Ê ãÊêUj53\˜ÕîpÅWÐ÷ñJxžM`Ú ¹~¸»ºù Ò•e6‘Éêî~0WÆx–‰Õ]ñëúÇŸÞþýîýçë4|°ëIøú‡ÛOïˆbéçÇ_>}¸ýøÏÏo¯S½¾»ýå‘?¿ÿðþóûO?¾¿ÞˆÌ/ý >Üþ×{j}üüöo{ûùúßw½zßeø¾‚+|‘oW¿þ›¯
+xí¿^q¦lfVÏðÀ™°V®WÚ(f´R²¿úrõ8á × ÓŸQ3™Lg(å@‚C['«ÔX–(©œ«^Ȧ몥ßÆssüZÕø­‹êx-²u¹ëšã˵b ŠÒ ²Û.#zÌû‡l]7Dü^•Ïý*õd½ß8—ûzóA‹Ø2•,Y
+/‹ò:(‹Í×ò¥eÛª.hÈäMA©5~HƒÒ=WmG¬6*Mˆ'W!˜5F:Þ/?½•&¡M~ÌÛGj5÷ôKÒBß…Zu~ð4§Bø=µeA­çª{œy#a¦•â±¾ËÌkÀ¾*“HÏVþÞ•u[55ÍEY°3äŒ8©HAiJÎ8Ï´r‘½ˆ¹¸P
+|Ýbóû=l÷di¡RÆe/¯¹Îâ@GZ2®aSF«ß=¢’•ÊÖÍSçT¡Ù®£mÛf_v%›Ñ¥µLÂñðºD³ÅÏyKSО!©ªé—œöeDèúmŸÊ]uÿâ‰hÈô”wd
+C^ì&YF­ “J%^˜±J'rƒ™&,rb¦Oî€5ÇüÀp)½¾uv‘Eç—­íøM?xn˧ü˜ws 2¥Œø#8[ÖXÏ:„V¡S
+¦sY€Èt.Áȱ1(ŒE¸s6(’õÏŸ0Ôò’¸¶w¬®íì~O­#¤ëûæH”_¾lî¾Ü~ôýOJ‹ÑgëÛ{?šN´âéƒv µeGsæuáùQ7´} x<Îõ؈½Úv,Š²îª|û©%…V`»5@`±îТµAàÁEèñ²ÒÃsµ÷3lK¢äû}óì2C&rýB$‘(‡¼Û=RÄrNħcU盛(–_3˜%Û£s ¨ï
+Eóž¦ã‹ò>?‘‡}zŨƒNɽñØ©9à|¾Ì`¤Éɺ)»ÝÍ×ãÖ°ÞÉN#¼a‰!ÂÃN;õ¾1Ñë}ÔŽOÑ?B;úGh»wV‰rÞ ¨ãXÔòO­óØìÂÔó!`µ v‰<'¢gðcŸÂûƒU÷*­í<²C¡ÖÌlÐ{hìoRj¯Ålˆ4`ið[i¾ûôåfa+f1[!&²V4‡Üݹž6§< àvo“¬ï®­\7$Ù©õ"†³ôfuXÉŒ’a¦A´ÐÜ0—5·( Jel˜æpj½ýåû¶¡Ö6¢ßUÝ÷géÁoï†n{Œê) 'ñÁíÿÌ]¾‘œI V}Ñå¹–]~äŠêëu4òóZ1a^Y;0ͬ=òó:c€Æ'‹Ó1¼æpíüéÉ…éÂAkãQ±  1"à·–šhÛʤ®‰Ð>ú$Ò&¿Ž­‡².Ç4¢O²FJRR‚ ñ`w?¿ÿïÛ‘)ôNø—ËNÝ+øT1C›×vl»}ÞcM2Œ5.ú:‘ @ž@õŠH–ñ4ÉbÖ·{Ìëç1yâÒu\ï¿P£9Òr‘àì1OÁe µ(Û*êÕñ; -È›)2£×öɾ´Âá@$SD,[xû7¤ Á932MÆ
+¢}†ŒÛ'FÐrÛÒ~lŒ¶Ùf(°ƒ¶¶sU‘&´ KØ‹„ûÓ|_áŒøIO7W#
+Äã‚$‡“€mXf‚Ǻ©7åï` 4LdlOÛ~*»ÞW_}rĽPé#O. œ30 «µ•¤Â(™Í²l¾¾¸‰3n†SÎø}‘1# ãŒla˽‡˜À˜É`÷ÇXÀå&c
+¬Õ¡Ë‘Ü®_šâ`>¨,Õ£1¤÷8Ãõx,ßóc€5è€ûJQbà¯ËGBözª÷eëÇÆUƒ/¥$"c™L&¾î ‰ íÿ0hT<œáË€aȵ "W\qg+yúòÒifiy^ÇSãµïBÕ÷ 1ØO—3o~*÷ûƒ;M! ‹/§iû2©ÇtŸ@Z@D:Nì%áêÛ„Þ€‡bGV‹EïX{Rð
+ ƾ y&À™ÎHôã3µ6ŠÀùu`’õÞ'&­Á¼ñ½q5²èÌW<€â­ZN'гoòÂSÂO§í¾Úù.ÛDâ±úNªªW´î)Ý;øX¯ ¯± ÛØ[¹,Êc媞”ËûËÃç/œ²[?Œ¢å  F“`ƒÂ_ðå˜9§¾kúqnœcñÔA^.Ù¼R-r-ŸºÈå€J¾{,7ýeÇèÜÁ¦'£³/pÍ,?:y`¶‰äéx}ª ûœÚ
+UíNEŸ"l:¼˜n°Âë0ÈŒ\f—ªÄþiìgÜ §tæ0’NiÁ$j.²[d³
+öL+¶pJ¤…ÙRuù ˜–ÏH`rõòÐvy¸³ÚµKg=‚µö¢‘é\†ÑYI,K2!GBøHÅGŸ\+ –‘ñxTD1ˆn8ŽÕö¡ o†õOmþàÇõoëçiüb5ýï°BÅ)E­‹eˆ;•™Ü­ý9Kæ
+N™2ó[2—ce
+”78[K¦b8ËŒ~ÅTz¦ ¦â™ÜÝ]U,€5©tzqáÈt¾ò8ÑVLŠd´òÝüµ)¹Ò´÷š½+Íæ\iíÃÝÜvþ2×WìwÇ#áö]¸Ûż3•t£Î{¹9G{®Þ/÷Ü_5Ÿï¹æ˜ÇZÄ/bJÌꬤ#7ÇS}ã,ƒþe°sé7
+Yg2x Ô˜P˜˜«› ìÙ\_
+ ±ªÃaã.Š¹fd׈€é‰ A‘Žë!F€'‡¸7Q$ÄøÇuOŒ8ó§'g­ï E7¢¡_Ÿiû4Ó0þ×eZÜøbÑ\‰:e\s3—jáñÔB×øÛ!BHÇŽ‘Šsúþ"ºG*‰Z°Dдàbl‰KÒ
+fbÞèòpe–Çï¬Ç2ƒ‡ˆŽøI¿çûª omffÅŠ ™’/=
+8¾]^í[}µ¾"D_y}CºÑW,ø<´m/—n–¾Ù‡ ÚÏØ'üõ¾éOÏßÿgüâ6ËnMOX&m„BÁM:•<~ø.úÿ
+endobj
+1654 0 obj <<
+/Type /Page
+/Contents 1655 0 R
+/Resources 1653 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1644 0 R
+/Annots [ 1657 0 R ]
+>> endobj
+1657 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [250.9056 335.8063 314.5963 345.2159]
+/Rect [250.9056 106.0844 314.5963 115.494]
/Subtype /Link
/A << /S /GoTo /D (statsfile) >>
>> endobj
-1280 0 obj <<
-/D [1278 0 R /XYZ 85.0394 794.5015 null]
+1656 0 obj <<
+/D [1654 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1277 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+1653 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F41 1208 0 R /F21 930 0 R /F39 1151 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1286 0 obj <<
-/Length 3459
+1661 0 obj <<
+/Length 3489
/Filter /FlateDecode
>>
stream
-xÚ¥]sÛ6òÝ¿Âs/•g" Aœ>¹±“K¯qîlçz¶´YœP¤*Rv|7÷ßo»€@‰R’¹ñŒ ,‹Åb±_<ð'ÏÓ,ÊŠ¸8Ï ¥B¦ç³Õ™8„±·g’q¦ibýxöý›$?/¢"‹³óûE@KGBky~?ÿm’EqtÄäõ‡›7ïÞ~¼½¼ÈÕäþ݇›‹iœŠÉ›w?_Sëííåû÷—·S©S9yý×Ë¿ß_ßÒPÆ4~|wsE‚>GˆÞ^¿¹¾½¾y}}ñÇýOg×÷~/á~¥Hp#žýö‡8ŸÃ¶:QRèôü:"’EŸ¯ÎTšD©J©ÏîÎþá £vê¨ü¤ˆâ$‹GÇ
-ÙCðbs!õ¤]Ñ
-'{™aÇ*(¶Ìçu‡éõ í #V Xš—:]õèç>X=äräDYé©M"*;lBi=¹GBP¹í—í¦ê_³33¾}бwqè–d· „÷­›ÄÄp°7˜阧jnš™qHxê–Î’AîÂXZÝØžvç”ÄOŒµ¿ê
-úUo¡¬kh¨Â_™}ê<x§;dêðÛõrRÙ¹)Ù¨Ô™ºª®pð…`킾 8xC$kš¬…Å°vÍØñ”Ž¾8Þvl<¾ul´ç‘§¤#)‰ä®ZUu¹±æ_)Ç
-6cË,qƒYÙP£ÜT+87è™ÕÚj¸JàdænÞï"MK탫léõô%=ÃÉåÊÀ,Iઠ«Ð„‡­æ@(V¶E&n͆ñú—õžð¬^aãòæ× )ådOx´ÒMkUEÝ
-g.Ž²¼Œ"RqîŽqMþ#œŽÖ¡3‚ÆSYWó²·Ñ*tŸA/¨U2Ge 1HS’Í–“d휉´;¬œR+XXMáœf§‰‹ðm{$>M覤îV
-ù&¾‚HfC_ww³æíª¬˜Ðð.ÂtkGœ¦ÏtæƬMלä¨Bùûô'—C/³‚' ÇÊÕ.Eò+6ífUÖÔö¦ø<}¢¶´  ÔfÑÈÓød8‡Û6•è ¸+3ç‰N4‘è§äÞÎZ6³¥àEη:¨³²µAÖ±MyîꌖG:ÆwÈ%¡\‘ï&ØPaŽ-‰²5<º]‡Kgœ ˆœsœnøb6âÃY˜f„q
-o ]‘T&
-H™”ØóH­«Í]ÙçÌÛEÿÌä^ˆVÁ ³äœ³1û‘É.|éýÀˆÔðUHëäÔõh€Ž5´øÂ=°NÜs‡eíA70>m›©ù\õ‡I*šÛBæÁc01¬ƒØz‰rÁ50,Á®Ù[a&OÎØ@ÅC»CM(¨Ý-5MÃ5WöeWòqx¶fÕR­QBòR~r‹3uƒ-=HZˆj#ü„Œ‡*Åï•'µ|­÷êá~(„JwOn¶m6ÀÖj•µêƒÔ`± —:­!Öq}ðXÖ™fª®¯f‡%10‚™*ŠÓË{¬‘õª'Q–€D ü‚O¾*ù)òƒ'k ºo¶ïŽ›Kž‚A‡=ÿBíE!0øð2F
-é"s1À@S&7ÄÏ+wum
-)­¸}\ö4àæãû1~Å¢pÑç@|ôX5pçqCˆ<£á 런Ţ7Ž]Ùr›W–ü‚#›~,¯1Œ3ëí#±ÂDŠ/+1 [–/¿µ"Ä>ŒYt[Î’)>´Î` ×|¤{–ÌÃ(¾ÇHÐ
+xÚ¥ZÝsÛ6÷_¡·“g*š ~Ì=¹±’K¯qz¶Ò¹NÓŠ„,N)R%);î_»ØER”ÜÎ%“X,>¸ûÛ/PbæÂ_1SÄ^< cßQ®P³twåΞ`ìÕ`ž…eZô¹¾_]ݼ—á,vâÀ f«Mo­Èq£HÌVÙ¯óÀñœkXÁ¿û|ÿþã‡/·×¡?_}ü|½ð”;ÿñÇ%µ><Ü~útûp½‘ówÿºýiµ| ¡€×øþãýQbzœYôaù~ù°¼·¼þmõÃÕrÕ½Kÿ}…+ñEþ¸úõ7w–Ákÿpå:2ŽÔì:®#âØ›í®|%åKi)ÅÕãÕº{£fê¤ü„ëx2ð&è‹ž
+¡œØ­ °ÚjPºÏ÷I»-“éEójCÔvË>ßØèúY×DÌ»}cÉé¡ÎÛW¨¯¬ïHƒmEä—­.‰’—M[_GóCÚêŒw`¦¬âí¤¼Ý²û¢]Hß‘®¡,œX)ϼZ]f)ÚJy
+d€…îüã†æ•UË ìuš£töQHÐÈô&9Ì—ó`
+©œ@Ä!ïBÎœ GŠ¤D€÷70 <Nä‹70Ùç:ÉŽ‹0Ù4yU.ÀdΠÒóјåå#t\gàà("7ÂàR
+¯‡Kì!.ñÙÚa‹Klç%â[/Û<Ý2§%"™/¡ÇêñãjñS^›OºÔub0‰Ýõëò¤r·Ó•Qí„F2À—bÐM¶#•7?4š“{ø`®AÔÁ§9ì³¤å ‹b
+Ó^ùGL"0˜–J¦qêÓ2 Y¨0Ôa'ä×b> k_9®¿CÛÜ<'õM}(oŒnX¤èw'N(”r|zÃ#~u•û¨Oàf{xN,…@ÑXý4£ÆCw–}Ñç?…ÝɪxG¶O˜àëEŽ?râXÈÁNáo¹Þ8ÇéjxÔˆŒçI‰àóÚt¦}R·yz(’šè¤2Èò&=X{l(@G†SH‰0vÂгò'D-öU‘§Sê
+@]lZàÝé²ý‡EEÔÇžVßb¯¨Òd
+¡R:nìZèT{#t`CK‰È9µt°»Ê„ö½y »„T†„d]Zë ó†Z´šæ
+mŠ/€¥ÕM ¯ðOè=Á˜áИ7D2’<q¬!òší6)í9‡œLü%/ŠQɾÖ6%,¸e²x¦Õnw(óÔQH0·
+êþ©¨Ö / ¢?|¡Ïuß(Âû\n¹ÌåÀ Ú-2ýœ§“!! ÀÌ/nßqMì? !€fx
+9i^}®óA ã2iN­7º®u¶xB$žDt¡äåý;®‰ £@è(ÃۉƗ…^l 2’ó"oèÞØÚ×½¦"ü–Lb
+‘ž'Â{™hŽNZfOˆ¡ת1 ””Z]YŠeYŸW;jÓ[ bð6/2â;ÎÎ[~64B÷p8©xI^y}Z0Åö ÍáZ]ïòRO]ÄA‚Ãn^*€y¼š6”nFäÐ<&¹Ø#yA£ÿòØgp@‹Žohõh¿¤å2ù’š?~¾%–Þž J@€‚Ë… ¤p=OÞ*kx^‡< eî^#²=ZxfíF…1ôwI ç4°†^„Ä5rKc€é}š¥kb ¦÷!i„Æõ`?·óz–9eá|#
+̘oì}ùØ1^Ç–gØ^¿öNñ)'0ɨ‡ü™Ê-cÀæ–%²©÷‡v[ÑO³K-°CU“kÍ (Ç—@z[ÙI¼X¾!‚1ëøëhô2eª-jݬ³e’5³Ö¤wîˆ^low£ÎÖÆšR¾šßšåËk¶æcPòâ£UótºŽ(æ@¿¿aD7Âñq»È
+Ù‹‡Ëòý~Ô÷Ò¼üßóÒ\ÝA?··>‰É?©$i˜–nuú{ӑߙܴÝ]ûxrtyÊÛ×a>¹­s9V¿ôÜå XÌMà-±'a«±^»BÖšMŽ]v6ó]^$µqþ¾o‚M81¸p1§Ó %Eo‹¤Î-WOiÐÓ»½·_ù2;³ª²¢ö‰›õZzÈ|úúÈÉór0<ÈA&TÌ.s ®ŠÏÍcŽ}oïáûŽ áÝW'>8jÇ-J&=¿ïÑL Bc{ Ï§õéÓ‚vž†ø ónù•>Ž™ahþˆ_á~!~yÄÿyOªð‰ûÓ—Çå—OØ¢’ |ihòKjYJÉyìH |W@pÎýØO*¡7‘îÃ?^êÿþ!àñW’~èÈ(ò¦ëH?‚EøPø
+*:-˜øƒ§Gÿ—âƒhendstream
endobj
-1285 0 obj <<
+1660 0 obj <<
/Type /Page
-/Contents 1286 0 R
-/Resources 1284 0 R
+/Contents 1661 0 R
+/Resources 1659 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1282 0 R
+/Parent 1644 0 R
+/Annots [ 1663 0 R ]
>> endobj
-1287 0 obj <<
-/D [1285 0 R /XYZ 56.6929 794.5015 null]
+1663 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [80.6033 659.1254 149.9876 671.185]
+/Subtype /Link
+/A << /S /GoTo /D (dynamic_update_policies) >>
>> endobj
-354 0 obj <<
-/D [1285 0 R /XYZ 56.6929 333.8409 null]
+1662 0 obj <<
+/D [1660 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1072 0 obj <<
-/D [1285 0 R /XYZ 56.6929 308.7186 null]
+1659 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R /F48 1228 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-1284 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F41 939 0 R /F21 714 0 R /F48 953 0 R >>
+1666 0 obj <<
+/Length 3661
+/Filter /FlateDecode
+>>
+stream
+xÚ¥]sܶñ]¿â&O§™ ‚ÄíNgYN•Ä²+«ít’<PGJbÃ#/Gž¥ÓÿÞ]ì‚_âIJk?ÜX,‹ý†Â…€ÿáª@DI¼0I(ªÅzs$·0÷íQÈ8+´b}suôæCdIh©W7Z6Ö†‹«ìÇåé_N>_]¯¤K¯”ËoÎ/ÞÓHB?§Ÿ.>œû·Ë“c/¯Î?]ÐðåÙ‡³Ë³‹Ó³ãUhUë%S8°àÃùg}{yòñãÉåñÏWß]ugž7ä×£‹ ŽýÝ‘¢ÄªÅ|ˆ L¹ØÅ*
+TE~¤<úrô׎à`Ö-“ŸŠl ¬43ŒÃ
+îç«,ÿêƒå}î›Üì›|¿ñŸÿyçv^M¶&ir$f àϪ#­†XN*2œQ« ·ÌŠ&½.óUZÞÖ»¢½Û4SB# Øϲà‘fXË1*0ÖFcÞ o:^¶wˆ–Í6_? !óŒfÞ_|ùrvJ“vÝ\Úòo•Âu^Ö/Q¬ÒMvE|Ü—m±¢»Ñ*°±ŒÆj±av"ÓPaœ  s"k©@´¤iÓ6ßäUÛ¹¥»ãÐ.sþ(áy†,†bùÉ)"ŽÓ‰
+ê„| ôwFô;Võn“–w®ø>!4ÐÜ]ÚÐD™ß´4ÔÑø%¤¹}ÕîŽírß´yÆ;"ÝhBÃMŽ®Ôã¯Òj}G2•UK¶ê­:¯2"ë‹òÊ
+:l·¹W`é”\HŸ¹Œsdä.|!×E•@~.c ¥ˆ¿ºwsÑ3Ðõi=M6C%Âøy,2pXÖ)3ßÞ¹2<§€4i×:Wƒ‡œÕôR”H&cU§;‡”$°I¤Æwþœ@z®bÍ@&lÒöf0ä ‚”ÞØ?dX„ÅzyBä×õö‘èc(ÆÒr
+LlM§¸¤ÆP-?ŠDX¯PMÈ“ãüž4,Œ}¶ ¥ÖoˆRÌ]k( S¯»W$2TC{ªUÍÞÔû
+=xoS08V|@'…„¿>-›šqëͶ SCn+í,|$QpD¼—Ü¡’$ÒcyÆëI=6µË¼|,\Ð1zé²Nƒ¾Ò…
+k¶á8YµÂ›5@ézoç„t¥jò]C®îµÎyÔNF&È K[!æÏ,EŽVzª¹TÒLj§‡v»vý +úþ…¥*ä8\úÔX8‡ŽCN×߀ä”ú†®«¥¨#IÁ(æj HE‡ª€ˆHbÍm,Ž
+é̵câçãV»seôêç´`KÖû{rzÓj#„’Wyg¿I«ôö0=š‘Šžt|¹¢œ¥¯
+mËçqó¦Ë_Æ&ç9Éf»=§ÿ‚—½öÔA+ôaâwé=ã•yuÛÞñ0µìÅ2’ìLbáË€Ò xÞ¹ÿ+– ï—2±­O›.?œò¡äl¯ñ$Ë
+¼_Ü4 f‚¯ôv 7.Î?ëàäò3fä'„B‰%ÎQXEèš[kZ™MP¿¯ï„Ø‘txª¦ßÁ ¡¦4Ž¶WPkdRÑÏ5i! N™ôRØH=bÕcƒý°oë*£ÈÅêäýûËÄöM‡Û<V@®)~wçâ§'Ï(uÅ$Ô9£€swŸïæBÔ¢QWeâÕÏø:(üc­†V¶n!dÌQŒ›aEr½7HØO$Ó]:|áçj茧ø,æç\l
+–ŸŽ±DÞîwÛšð‹?ÖtžˆT& ÕæNÎ:™ºq—c¥]Ó÷5“íþ¾f‡Éò¤z¤áª®V›´]ßu„§#w¶™2vÔ7w=®ý®on=IGë5Pì4»Kt(ܬ±ÛÝOúf·‘•w·³æ„z‡Ïè†
+KÕ©–sÐÄfÝR"§o0Ú7Ûµá×=4<v‰ Ó+œö €
+'ph—%¥UÚ?ãÃpW~Ìå—6ã‹À)¤ƒOW*Y~óÈ]*h=}-C—„¸d@æCR
+ø6«&Ï‚¿SS‡þ^WE³õ¾èNùÿ-iÿ‡¶±/jå|ã :°ÛÄ@%Sλ?:}Êú} ûendstream
+endobj
+1665 0 obj <<
+/Type /Page
+/Contents 1666 0 R
+/Resources 1664 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1644 0 R
+/Annots [ 1668 0 R ]
+>> endobj
+1668 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[0 1 1]
+/Rect [278.4002 485.7209 280.3928 497.7806]
+/Subtype/Link/A<</Type/Action/S/URI/URI()>>
+>> endobj
+1667 0 obj <<
+/D [1665 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+1664 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F21 930 0 R /F22 953 0 R /F48 1228 0 R /F11 1442 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1290 0 obj <<
-/Length 3312
-/Filter /FlateDecode
->>
-stream
-xÚÍ]sã¶ñÝ¿Bo•fŽ ñE—‹}u¦çkg:i’Z¢,6©ˆ”}î¯ï.° A‰’®éÍôÆãá
-\»‹ýØ$?6Ñ*N„‘“ÌÈX%LM曫dòïÞ_1‰<Rb}ûpõÍÈ&&6)O'Ë`.'Z³ÉÃâ—黿¾ýûÃõý,â*™¦ñ,Ri2ýööî;7bÜãÝÇ»›Û÷?Ý¿erúpûñÎ ß_ß\ß_ß½»žEL+ßsšáÄ7·»vÐûû·>¼½ŸýöðýÕõCÇKÈ/K2òÇÕ/¿%“°ýýU £Õä~$13†O6WR‰XI!üÈúêÇ«º ƒ·öÓ1ù)¡c¥y6"@β`™N2eâTpax»œEB«i»*ðïº"¨lÜ3wMÞ´Å®Gz3‹$3øau0ESìž=æK¹^ûÑjá zßf¾ûøp{ó³ƒw3¦§Åû¢!œ¶&\?O¿Ì:.ÜCÄXl”â–©_•,Še¾_·
-cÏHP0” _³hP/ý
-Ð(„@Ã\•Å3šƒ}uÏ}C}s#u¨ÍYóT^¶ : _&¡ÉâÄnsB®vŽà hUþT4oFW‡ð¥!ô„«;eOžÆ™éPnÛ¼iÀïŒÙšŠ¹Pì€B™ttIÖÓÞ.÷Æ*›ÅŒÁ¿tþ^V |ÖçàCê”Ø!ñ
-ßÄJi¯R;ø?;fäˆsrÄÌ18æICøˆ4¤`3‡ol¬À1˵ÑÉèäÇaâgn››˜wõߘ[Ô}4`:0¼7w¼SW©XkchÅ3J"c!D6Tœö_û†¢Ì¢lòÇuAÑÇ‹µ·Ó@288k|˜ø1Ü$‚MRðA@Åg¥~"3±fÊ S¿?÷•'$º')pß%0~+†SESQš0p“?‘Xró æIÈ?pÞli“  ½M½°I›Tç%-&œ"E¨I'°X&²#¬Þ¥…û9|ÈÁÿ&”¿dtü ¦'*3“³22x’71
-{&Ø…ࢊ3Ç€’¯Y` qÁÄ%A¼Ö,3¢ú }–û
-ùš-’C%™¥ý¿à±N©j lúÏ‹í¬a})¹õ­¬ÿG‚ÄL†ŠpÒ€ôÔŽzk‚ÿàú"iÀ j¦Ï·Ö$.-õoê¶ë²ôYJŸý„µáaÖvF`ƒ)'^"Ò²˜·g» J$(ƒý†Sv¬°µ:Ëtصô2A<J3È¥5ðfNôn )
-±Ž5×÷E;,ÛÈ/¢KŽ£´ ³Ôdçï°FV&Cà,®~‹Å<¤AÔ,Örª±ô0vËJ•[*úámQa¹°p/šr³_ç­Û*ß“D¬ú±©×…ÝwþîîG8&-Fûº¥··?üt}?ƒTöçc 6`@š*EŒ–8¨—ªÂõw°Ž©} Ìç:jDd]ÞÛ$Y’¤ö6À:³·ËîmÑÎWÑÓz_omŸBntvíkdñÁÖ
-[r‚«»N/Ou¿ƒØÌñc´GØÔL…S&Á¤G{P{J-|#`ª£äD ¾Pؽ·ßÌó}c5Ö Ö[ôê45–ô4oÛb³mÃn“v+R¯)Íb-ÌP'-Üh*˜šzoù`t^Û'vpûÐø\”‹ê/¯\ß j¸4¯«¦ÝÍôt?'­7ž
-r†9ùÄœ~Ãû¼o&XàèdhÔÊö¤Áy„I/8Ãë´ÁtX®FKľYEØtm¢ºŠšÕ¾]Ô/Õ!%B3—Üœ'¥Ã¡eÀl8 ‰ù‡;Ó‚ZbrÑ|Stç:ð¢øT¶{µØnŒ4¬(ŸÝ9¼ûñöýÃõý‡7˜t¯jšiQÓ
-æB,«êèË4*F^½RؤìáÇ®l‹æðЂJàN£FzþØ%eBvuó™=9tLÇ©‘¬Ï²FŠrbáBÀ‰Ž¥Ì.8å댎y,Û¡Ë‹õ"š¯Ë¢j’>‘±Á„à,Öf¡‚ìŠ I 3¸,í<3Â/9 –36­ÀE‘&µ¶çŒã›íºØ
-1
-§¶#çr7…ç»'“v)ùÁ2˘䂟 ±N[^‡e-¯¬ÊM¾ŽvTq{Ú („ |ž„k„†a Ncùà€ˆÛåˆð äœ:ýŒ°®ƒ°®2ñC)_§ô:¶ó •j¬Æ¡¿U—õ×´ð º…cPÕ9à¸r<§ˆÁtùžNô„°ßŸð:UnW5$å83¤ú®lX8
-î GÁ|áظqbPØhá'qd¹a·¢ì+Bán¦ñ“µ1ô4ëâÉöC¬ê f…¿mµ+øPVîÞØÙ¢t“¿v¡†nxÞª¢‹,y5/†÷¥úÛ[nÈÏ\,WŠÃÁD¢ä¨9Ô‹þ<áŒÙXgÌÎcY³JˆÄÑÜVÇ‘ŽÅÂpuž€k„‚³i‹Lè! ´c&èçì"„I}¬‚¡’^‘«H;«ëF¹xºe¿‹ò£:|ßIQæ»»·®±@•$9VS¡ŽŽ:ΧÏeíºznØj÷w¹`À59Þ;Ëik]ŠoÁëÐÕK>X(_¿ä¯ŸcWº2 ßÕ²¦žRs°jÏRrÈ‹žî»Ìñ±nWÃtÌ_+E
-nÞ¡vM›Å+H¶œS´Úâå³&>uóV¨¯ËŽhQ2¹xÀõ¹·rû+ËP"
-­OÜ‹ Ä
+1671 0 obj <<
+/Length 3076
+/Filter /FlateDecode
+>>
+stream
+xÚÍZÝsÛ¸÷_¡><"ø"
+™1-¹œXm™±–,˜ÏVç‰á|ºYÌD&Ýü›.‚¿t¯™I&Œ{)L°8ðRÈpÿŸ×h P)‘Še¸{?¯£‰ÁèWWWÙ›W¯^f&®‚3@'¹$B°,M¥Ÿ7[•EµmÚäÕÓÁZý9ëüþ¾˜¦ü!ìêõsÈÅÇÙj7/"új‡É¯^-àï‡?ÿ_÷d\±f·X”ã\bIF·Mó_^ÉþÁ%`i+­‚9)ãV©úÂ0€¦oêzUäôýý¶¬«æ
+´\#È>žUÆúÆ@…· ² v}Vð^äYžH³}q–eJÚÀóâ<QNL·ËLªR3¥ ™NgyEÄmA×|>GÜyrK×͹›îªm¹.húC™œ¬È8ãZé°è¦šÏZ‰¸àˆšÎ=ÓqF½!þy±*¶Q‡ñµ`¢PFô—"ræVfDxD•²Ìê,ÈÈ©ŸÞ, BÞ¼Xä»Õ–nÊfä,Œ_. ó«zì(‚"q‰c0Ö3­{ÅÓ &áÝv™Tçõ:/«K1 vjí–épñ!~Ó\êÁê£ð͘U­ÅO¡×õÐ+[ôr‡Ô$ œHm#$..Æä:–YnK„7·x²þš¯ó§@7Å–«+¸þûwïß]¼½¦»Í¹pÓ¢¹‡¸T4AÁ⡼傮¨¨Ò›‡bÓ®æ¡*´`Òº½˜YÕ7—A*Ûî =…;8Çz
+ pÊò¡
+o˜ªfù¶Hê*)>ÂŽr•e
+ªÓ:´\#J ö«%ÓNf Å á,Yû„Môcîœq<2<ê
+TG,ˆîšÈ¢ÊoW!
+Ï–ÅìWÜ-0Kø³-Öõæ‰Ø¡Xø5.¤£|<´Ç”áÌ!‡.Êãò®ªƒ[@Ä4ÐßO^…]Ä`ô}±µÖûó¼âÍq<hÀ–2ö<ô¸Nà!rùÒ±X7[Ͷœ–-βÓË·\#ë 
+%ÁÔ÷tð_VöNÂó÷Ñøù]¤4ŠYë>³‹œ$Ò¦ÐL)¬gB¡B¬íÎ!¡»ØwuAr¿!–Ìé,6´m哹PKc8 ÃÐmA×½ í(Å„è5¢Jê ~l»æ‡²xÑD¦Lp—ö
+¬y}¢+½y1e-“F?ïøY¡mpcÉ ‚épÂ]7D¶è5 *¿Ã·›c«s¦œ6ƒÕCnTÐEÙlÿü}Þ4wÆ|-eR¥bOCÍ[½´èôÒ¼Õ‹žP ­ù~¹çRüÖ]‡ƒÄÔ‚˜€Çö
+s ÝkSð¦â´Ãì\ôw$²Cq,ª†ôj8’Í æ„V-¼…òÉFG'·Ž‰7¡«äGÜMiÇRןänI;iØuŽ÷¢{qvhÜ4eÎe±*=Í”RvûÏ]²Ì¼lðasX¸XÆ¿³˜õà5E¦àЙƒH—Ÿôõ[Y(GEš ¿~ÿ¾YQ^ì=ªÍã +qÆPT÷”@ƒ~Íù™e”ÝD*ÊzxßþÔs_±éô´™Ì&%£#\Â*{ÀÕųþ¡h+ñsݤ¯ÿÿf4¾Vw.û­¬ ”ørüÕUkdÍO9ùžPˆˆü½B?®@áŒo–Ç¡ý vDAÔ¨ñ:µ¾¬í¾(B±iÆ=c<éð—)úÄë5üˆÔUr­y:‹=~Ùo-ÕSâ+6I©æSá¯+´“§«…¡µF`uÊZ==¾bkqÎ 7úkqpºL=“ðŸÅÖ '$5Ò¯ÛXÎ1“
+uÚV™„úÍfÏ$ð#¶ú„xÕSâëµ”Å/Fœ¶”ãLºÐ6†’ù÷ì„'ö”ùRë~±÷ÿ(‚ð³‚3ʘB~½á“gõS¨ØýŠS[¨þœ/”¤…2Ä)‰¿"Òñ‡lüðƒWøEcàê©þ_ì¶Aendstream
endobj
-1289 0 obj <<
+1670 0 obj <<
/Type /Page
-/Contents 1290 0 R
-/Resources 1288 0 R
+/Contents 1671 0 R
+/Resources 1669 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1282 0 R
+/Parent 1675 0 R
>> endobj
-1291 0 obj <<
-/D [1289 0 R /XYZ 85.0394 794.5015 null]
+1672 0 obj <<
+/D [1670 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1292 0 obj <<
-/D [1289 0 R /XYZ 85.0394 625.316 null]
+466 0 obj <<
+/D [1670 0 R /XYZ 56.6929 636.8504 null]
>> endobj
-1293 0 obj <<
-/D [1289 0 R /XYZ 85.0394 613.3608 null]
+1361 0 obj <<
+/D [1670 0 R /XYZ 56.6929 609.3387 null]
>> endobj
-1288 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F48 953 0 R /F39 899 0 R >>
+1673 0 obj <<
+/D [1670 0 R /XYZ 56.6929 172.736 null]
+>> endobj
+1674 0 obj <<
+/D [1670 0 R /XYZ 56.6929 160.7808 null]
+>> endobj
+1669 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F21 930 0 R /F22 953 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1296 0 obj <<
-/Length 3798
-/Filter /FlateDecode
->>
-stream
-xÚ­]sÛ6òÝ¿Bo•g"Ÿ8÷”&N΋sg»3½iû@S´Í‰,*"×÷ëo Pü’äN;™1A`¹»Xì71ãðOÌLÂ’T¦3›jf¸0³üéŒÏ`íÓ™0‹´èBýx{öö£²³”¥‰Lf·÷\ŽqçÄìvùë<a’>ÿåêã姟¯ß[=¿½üru¾†Ï?^þë‚FŸ®ß}þüîú|!œó÷ÿ|÷ïÛ‹kZJŽ/¯>ÐLJH¯/>^\_\½¿8ÿýö§³‹Ûv/Ýý
-®p#ßÎ~ýÏ–°íŸÎ8S©3³gxáL¤©œ=i£˜ÑJÅ™ÕÙÍÙZ„Uÿé”ü´qÌHÌJ3ô§¥,˜€¬IY¢¤j¥,Å””#Jy]5åýËp³N3•87ë"‘@de‡¬K™‚£ï“½¼G’o?jלIcSÀŽ /EM0=lR0#Œ 0¿qÛÇâ|¡àˆ—Å}¶[50'ÞÀŒ³óW700éüêËíåÇÿØSQ×Ù ÷+Ùö\¸yÀPë†FÏÅ:
-NYG‡ËÐOñBÒpê«x,Èâ6Zé ›
-ÏeþHÃ<«?eCÏ
-tc .¦>ÆÍã:}Í¢­£ø]zX\‰e­î´,¢Ó–Éü²¡Ÿ«ÝjICÒjéœÇ\äèÒ·/ôŠÞ —›Ýv>¹Ç“¿Ëeà(ž —aµ ólW{½‡µz•}/ê¹WbºçÞòmV?²Qž’©LÏ}<áê
-&PyñÙB`¨Åçõu]4ôuö•ëº
- Š³øIÈÜ$xÕ˜ûá8¤ôâÕ
-ž´6JHIÙÎ0 `21ð·ó_®/?]^ap¦÷, /›>±z·ÙT¤©ˆ¿"zy”Å<óB’*Zí> ÓŽP¨
-ê×z¦0ˆÑ~o]hoXˆ¢YôNFÙ
--Ž»§.ÔaÿÔBᦶE¾ÛÖèf”S¶\Úã”#ÐåžsâšI§û”ä‡ÆqsÔ9K•tŒ «|©ôj
-ªñýÛ®ðq†”^ÀDÝÔ²~À›¶ X<Q*Ûd?y&•AJ DB,pÚkL.Ó´"’çjû5dËØ°ƒª"2WÒ
-ݲä6yU5JpH\GÑ4ÓɶŒó¥m礛N’ …m b—1ÞÂ`C;ÿŽáŠÊ¨å…4j߬J€ðÎÔÌïý7Õ½=vá%™/³&›
-žÓ´Z
-?µµ#Ú¬CÊrt=ªúºÛÔ¡»)Šzêj²ô€ìÈɨ‚÷E“?.V»©D;¦Eô¥ÙCÆžHG Ðá
-ˆ]Ì~SIß’K`Ï3e$KdêhSUHÀ_Î%Ÿá¥|Ú¬|¿ äöá~Féèèu’Bºx»Âýkç¥à ’”ƒ“Øß¾ü5m‚Œ‹9‡†$ 0)’㎊2`LÉãž±…B‰‚ËX”ËŦªV#ÇÈ!gàÖ̺hÇž1B©«´g‰p ¸Ñù[êÀ‰·}2wš»««UÑLÅ›6É ƒ8ºËVÏÙKÝÖPU¥Zx9; /?„¹Nö€ÐEs0^IKEÇÑcé
-lÙ:— z–á:'£¤YøÅ"Ü×ÁÌ]V—áèî%Ü !Õû—ÝqP­ÙéÔvØ#˜ `œ1Æu¯™&:ÓŽAš.Ntƒ5XŸvZ±Çä¯ÈRŒÀu¼îpˆ‰-uËÁ‹ki½Oߊ5vžåØŠ¥fDrðÂÀ;èXì—9}D§´K+¦S©»m~»Öø]Ð) ¸Ü=mhäôF­…–ˆõ7_«‚&÷½z'‡zÜ’C¬å"íÈ´ø&*/x‰éz*Õ¦×I›^Oe%RùÄÙœ¸œmÓ„.üÄ•ùkïj–~Ö _Ï
-¼L­íñ3ö7êcl“™Yë`Aೌã¶uÄÅF¨6ðýØ’hDî8á4&Ü‹yi‚7/¢O˜Bž²û«·s‡C^*™Ý—¤Ö·c”ãÔ²DëÂßYºÁ粬³;Tu|¹üåãu9£Ç&Û‚ïVÙ–‚óP<À«¿á´ñ÷ ØñÕBøŸ²Ð[†t
-ûÜl«ïårVC벶Ìàš-4A‡¿3€šUƒÓ‚Ê}êG|Ñ…Ÿø½Áë„]I&Üp~,I„é±3Ò´êcl¼hTÌ÷øH lhþj±´ð§8á F35JË…÷ OH¥…:ÁÃÛQg>sRŸh?t¡;›jJ‰ûýH ØõQê-Ôù~Á Ú˜@1Ø£ß*@³/¯ë|[vÌ¥ºŸ0Äü–ÔÊ“}ª24?ˆ@ Mo£Çì/ŸØòïk-P &l÷¬&-0B`cŒí¸®)É ‡ü縮u ŽèZ„¢n°¿}˜Ö5õ$@§ÞBMïëšfÖ[W—þߣkÃ] u ¼°yX׬
-ÃcNœ{ u‚1¶ãºÆA5]bNèZꈮE(¤Øl‹¬YäTeõ¢Þdùødž2…4(ÇÙh¡&øè)ÒÌHnúŒ„>‚û
-0…çÕ-=ýÖàùáË žüíݺùe
+1678 0 obj <<
+/Length 3726
+/Filter /FlateDecode
+>>
+stream
+xÚ­ZÝsã¶÷_á·È3' LŸ.ßÕž¯ñ9ÓI“<ÐeqŽ"‘:û×w @¤DÉÉ´ãñÀûõÛ%Å5‡?qm4ãÊ&×™M˜æB_ë+~ý c®„§™¢ùêûÇ«¿¼WÙµe6•éõãr°–aÜqý¸øeöîooÿùxûp3—šÏRv3×)Ÿ}wÿõXúy÷éþý݇ŸÞÞdÉìñîÓ=u?ܾ¿}¸½w{3F ˜/ý
+g&¼¿ûÇ-µ><¼ýøñíÃÍo¿º}ŒgžWp…ùýê—ßøõŽý÷+Δ5úzœ kåõú*ÑŠéD©ÐS_}¾ú1.8uS§îO
+ˤµÙõ\%̤°Æ€ê„Z!µQpÛÚ²TIo[ÊÁm í$½ÎTIânû¾íK:¿Ê{j5ív×Ô¾ÿôx÷þgjo¶7ÂÌڢ캪y¦¾ª süä|‰D˲èËõ<½à3bÀŒL4KlšÁ E•×»§2--3Yf<;‘g\ƒâdÎdD2­žh>¤¢ûSÚ¨pÇeþ¥œW¿ïÊíËñÞB&RÒÅÍ#ÕÄî#é$Š -Æ»ß5p…Fõ7É̼_›€´ÜÍÃX»é«¶¡Ñ²ÉŸjwï0ÐUë]÷$*xîW%QµO][—NîÐýÃýgjÐ!Eÿ²ñ£w?þ¶¨²ÙÏ7BÀˆ æ·*¨˜äN+˜ÕZ:æ›òk¹%X´¥×“Ázî90Ù6ge›¦–e™’—e;¤:/ÛHåd[öÅjþ\ïÊSÑr˜ššË{Gª‰ÍG¢U oxÜý‘$˜šƒÓlû¼ŒàÂUªH Û_<´@œµ$f¸“«2*õæ28à<å|öR851“2¥Ñ¹9E¾ëœÁ¤1ÀUWnI–ØÙÒoÞ÷åzÓAèt;’J@73ÊŽu‚x‘ÖÌœ/)»vçŨ·hÝΪ§ßEµh¾óíUþÕOٯʆZEÛtýöÆÌv…×zÎ
+Æ­ûôi¶%g‰Œv‡"œØÞB,ÍB,Ý. ©¸™#œS—%™‰w5m \¿¶ž¤‚øVæ‹óF ,Þ|) ©.e rro»~Þõ€Óº¾*N232ir™H5ÁÁØ(Ai–Yp2ºCttPz<†Á_ ¿”åÆ»]AQ~gpDËvë§~%ð M<ì8%E`,†ã—
+˜ÚhYÛ¼ ‹
+NÎ7D½?[÷†žw]9U8€
+œH¨l¶íWÀФ°§VV2Iú:௞D&L¥ /ÛÛ€ê‚Å*gsUS­óz¾õYÆ©wÍ€CÄ—YˆT<ŒƒoÊ bÀwˉ˳€3MúB¹„r¡³tÆ Cn­gбm(Fèt”WuDâ}¬xVX¡ªkšÑ6õ õA&GÓlèHË廹‡é€ñ¬=ªRô«€8® ðžr0%ÆÉ"¦”,*’ÅŽúý•‹ab‹º©ýû®:d@ò+×¼dÏÎÆÐÓÔ峫8ÕWÌ
+Ÿ]† Ô£»‚©‚MÙä!]ç/1¼PÉîk¬ñ•!'Ù.±Ê×ÁR—G^Þϼš¢ŒG‚=(®“ÿCž¡2Î4W¯„¹!Õy³‹TÎìàDßyá²ÆÓ'˜²R_f RMp0:lš2•)3fÁKÌjxЦaÓ« «òCÞÕCˉÓuxÌëÚ°I?ñ:*Y 7Їꉎ×@”ïîß~¼%cÌ(‘˜A uìÔà¤"}­ZªäQ·Ó(è&‚*4B€°f‘û5œ DX£àuüÍ>m”×ûü¥ kl+J½p¤l–­¯#uG»ŽtT¸q…¢ˆŸÚ~5†`ëÀ¶/»@’-#i,Ô,^àf«ÂG« øÌçÏ)²HYª¬}E‘T9P‘uõ˜7ë¯,Z]Þ7RMl<6ÖŒ¥6MÇ;O ÁÄ
+]4¸}¾¦ÆÃP.~>œ0!—“u‘¯Ï¡ž‰¼%LœTç‡Ùš7§Õ¹@õ
+§«y
+ÃÕ‰·"XI¥MÔ‘csù[á0¹RI()&Ñ `ûPZL°nÛôúÇ’¢„b4õó§·Ôøè\kº õ"¨7¢“ÆÏw‡‡_W7<l×ÑC<üÑN§
+CÌ
+G°»½žHŸ1aW”tº(¾ì•ÉÏ„op ›—ß6uUTý—IÆŒäÙŸà2ð&#¿J¾'tŒå¥‹Á#ðR{à¤Mi‚æ‰RØ]¦3êQåœ@TÕI6ÈŽÑMßRb” czÞzÄÁñš\´ŒhX“oöê…EýLÈ ^Ö#¢É”³TêdgΨq1Òe8(Àˆ±—D­§’~]Ù1š±ÇZ80m\XBÄô›¸€2ß4ÓJN°æäR^,þ*wدªbEÍ«,®…ïºð ûv N¦»Ä $ìŠñ$㸪£siìùëJ3ô1‹è¶eJu˜¼owõ‚š>ý2Æ][¹Ä/rzgl [Âp¿Û6~
+U˜ý°am/¬Í¬ò£•ß0¾}„±®”ÚÅÅÖÓ#C*¶y·: »D†…(þJItHuvEªƒÎûvÞµùiA_æssyûH5±ÿ¸l˜@2b`Òz \—Á:ú6|¯%¹ñŸo@£X•ÅlZ¡q0¾Vë¨ÃAdnÙÃïÃCWö4;ÆTDèb"6\Ld~¶ûÞ„â¾K‡ø,_¦ª_£ ï'DA•‡ýtŽ,0pzyȤç>.cãìÿôp÷áîc4=ç~ñªoÖí6›–Ô×oi¿¢m° HÙ—TÁtã²OÊTJ‰’J=ƒ*›aJ¶vï:°ÛǸPðÓ³Ïíº‚’Šv¶j÷¥OÕ}ON3QÓ± K×øòÊÇxt';lú»F¸E¯±xU-
+Ó!mŒÔÎ&ð“4´‰óþ‰
endobj
-1295 0 obj <<
+1677 0 obj <<
/Type /Page
-/Contents 1296 0 R
-/Resources 1294 0 R
+/Contents 1678 0 R
+/Resources 1676 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1282 0 R
-/Annots [ 1298 0 R 1299 0 R 1300 0 R 1301 0 R 1302 0 R 1303 0 R ]
+/Parent 1675 0 R
+/Annots [ 1680 0 R ]
>> endobj
-1298 0 obj <<
+1680 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [154.2681 743.8714 203.5396 755.9311]
+/Rect [182.6146 300.8791 231.8861 312.9387]
/Subtype /Link
/A << /S /GoTo /D (notify) >>
>> endobj
-1299 0 obj <<
+1679 0 obj <<
+/D [1677 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+1676 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F48 1228 0 R /F39 1151 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1683 0 obj <<
+/Length 3742
+/Filter /FlateDecode
+>>
+stream
+xÚ­]sã¶ñÝ¿Bo¥gŽñA|tîìÔž¯µi:IhŠ²9G‘ŠHYq}w±
+o¿Ü]†"Ž‚›Û^Sí‡û«ÏŸ¯î/Cnb|üûÕ¿¯ïiH»9¾¿½ûD=)'&½¿¾¹¾¿¾ûx}ùëã?.®ûµ ×Ë#‰ ùíâç_£Å–ý‹ˆÉÔÄ‹=4"ÆÓT,Ö*–,VRúžêâáâßý„ƒQûé,ÿxÄ„Ôb†B h8‹Ó4^$qÊ´Ò20«aI2ŠÕ%7ÁªÈ;lë YQ^•Eíú~Û—<Ø–E ü’‘>fùKY?ä:{£JÛ•UåfÉóÝ–z³Ö•5 ÆA÷RÐ@[l_ ø8þ7÷MYwŶÎ*j5›b›ueSÀv´»ü7¸rÎÒ8´´–vëîËãíÍ©ž-—[Ä[´n°jš¯»]‚‡¢ppUÛàœÀB>`!ך¥F(@…VE—¿„Ïð…`‡ìV†)n¸Ížš×‚Mä…³„s½H8Ì+sb (BÑöò9ýðPˆv»Ê…ŒLؽm
+~Œó„E\Ëóè{¨üÃõr¼O=&à¡è:+"2J`ËÖÕw•Ì Kt;Ž½í WEú Ø[Ià ól×KAâé%É!´e[ÔKªÝ=PIò7¶\¶ôiV5žè}Ù½Œ&N‚‡/W6þÖ
+aÈ…f\%éXWÍ–$«.žAx_½œÕí¾Øzñ{|qÝËb•íªŽe;Ã+JœðÔ‹WÝÌðÊã'‰ðy{ ÁŒ0ú[¬•4Öøšyk¡Œ0éøô\ô]s¹ªÿb<Uè© uÄ™ ê©ë9 V-a kb¡!1è¦]ëÝ€±VÜr#b±ìU÷Ëe¨yðÿE01ãléBó˜)­¢^ü¶à,Ri* hP·k=ðÀv|w»‹O ¬h1\”›8Îl¥Çª$ÁB+¹ÐB€AÆÙE5(‰ Þ.E®Q®7U±],]GM¥sfPK'[¯tÊ„IÍbÈÜ?·_6B§àóƒ«úsÒŠ”ƒŠ$À0$<9oãD³(æéyëØC!GÁd„å2Ü4M5±‘aI”Ä‹á´SÛ衦Øe:ÒDØP\èý£5‡¨âÍýY¯îÔ÷Ô6UÑ͹`›ŠµéÛIð’Uûì­õõªÉ³®pMðäÛ7ªÞ~r}+kÄšµû€
+dÍI¯«˜ÉHèwöe
+ö/eþBß¹  Xîà<°ÞP6dM
+–äI¶{IŸÎ
+n·6„8Äûý"¶„nÞéÀª¤Œ ä$¸Ùˆ7”‡G)S2±‘·Ïέß­‹‡‡ÌX—ɼ烯0œM¢s¡$ÈØ›!‚‰•ë¡Þ¡c:ÛlLè­¶J 8¬÷$C¨Ó¦½‡ê]îïàkŽ§îÅÜœG즈GÞ6ÕéI>FLÎV&iïl±Þ÷v¶©`’­NôñDÁ[³£ êÂ
+5Ô¬ôC¹,ÛìÉJ=4nº¹gTl²-ˆò®Ê¶4akØtl&žŒ<G ʨ8‡–›Ö)"Ç‘“²†cÇ:;ˆš/çÎĹun¶Ík¹<ìÕ±‚:£¼M…/õDáЬbA§ãLnøŒfyðp?#ÐdzÎè•`ÜS#Áúƒu‹GäL$­‡z‡Šélßjp¤6,VÑ7³¥‡¢É¼Æ(&'8@ñWz¨wh˜ÎvÞØÈõR¾clPgŒ‡šâqò ³½>‹½‡šA?öð NŸ#ü½
+oAŒ$¦ÂØ*Ë˪Ä3-µ«&[Ò Ì`ou “NñX£#”Cm7I¡âǻ۟¹oph[/YèѽÐþÀB(CPP빨ñ–†dÁå. ;såÝ#•viP~úò@•µ½R*ì“ n¸!¤¨|j0+5G%ÔNí?O(Ùùû_Ïì?ìªéS[ÎÒ¯ç;·„øIÌàØ•þA)¯d(…Ñ:\.B2påGLJºØWeís†Y¿½Ç¹Å</6°Óü•ÆòÈÍe7ËçšnMŠåi[
+‡£Óô[:€:cK=”½Œ[.K$)«ÂÕ¶Y‡Ù®{ùÐ_Ž†rlj™1¸¥DšóöP3$ŽO2–ù|L£O¥Êñ¯¥FÞÔdL¤ÒeYRL ½d¯¥=1âG+*Qãl kl¶hðò‰F°(ÆHo¸ëÞ+YŸ¢ÆwUÖà
+\Ó‡£‘¡<Ø•0ÚoòQ¤j;{ãA76‰ ý.mOÅœ`XVQš;¥$5.7j»|>Ý /< „RóæHUìhŸj7ξAßð{ã“üi`-ø/Çä¿ ¯mÖn´-»]æÄ>³1M]vùøî†`¾Üb&ÉÞ&Hzî
+q#g´
+¼›Ý^k³ÿ€ªIŸhÌwÛ–>˜d)œœØø±â°{å‡(iÛÅàQÅ€‡ÓeϧH˜´Ž“£pø >ÃókÕ<ÞÂì³mM±4Ö`ÿ²çbV˜ÎqCf¸ö'‚ùã&DºâÔK‚„qÝÛÇ,‡h’xÀ•U^ ¡B,SÂÅÖƒ‘¶ÎÕ~:RLå™tóÄ“g3…—®3'á¨
+ï<Uö­¸˜&ÜËéâÿ ëpendstream
+endobj
+1682 0 obj <<
+/Type /Page
+/Contents 1683 0 R
+/Resources 1681 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1675 0 R
+/Annots [ 1685 0 R 1686 0 R 1687 0 R 1688 0 R 1689 0 R ]
+>> endobj
+1685 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [80.6033 237.2629 144.294 246.4782]
+/Rect [180.4479 508.2615 244.1386 517.691]
/Subtype /Link
/A << /S /GoTo /D (statsfile) >>
>> endobj
-1300 0 obj <<
+1686 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [265.4578 191.3384 326.6578 203.3981]
+/Rect [265.4578 462.9269 326.6578 474.9865]
/Subtype /Link
/A << /S /GoTo /D (server_statement_definition_and_usage) >>
>> endobj
-1301 0 obj <<
+1687 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [367.5441 191.3384 416.2908 203.3981]
+/Rect [367.5441 462.9269 416.2908 474.9865]
/Subtype /Link
/A << /S /GoTo /D (incremental_zone_transfers) >>
>> endobj
-1302 0 obj <<
+1688 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [280.9692 160.0192 342.1692 172.0789]
+/Rect [280.9692 432.1776 342.1692 444.2372]
/Subtype /Link
/A << /S /GoTo /D (server_statement_definition_and_usage) >>
>> endobj
-1303 0 obj <<
+1689 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [277.6219 128.7 338.8219 140.7596]
+/Rect [277.6219 401.4283 338.8219 413.4879]
/Subtype /Link
/A << /S /GoTo /D (server_statement_definition_and_usage) >>
>> endobj
-1297 0 obj <<
-/D [1295 0 R /XYZ 56.6929 794.5015 null]
+1684 0 obj <<
+/D [1682 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1294 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F48 953 0 R /F62 1062 0 R /F39 899 0 R /F14 740 0 R >>
-/XObject << /Im2 1051 0 R >>
+1681 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F48 1228 0 R /F62 1352 0 R /F39 1151 0 R /F14 956 0 R /F41 1208 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1307 0 obj <<
-/Length 3849
-/Filter /FlateDecode
->>
-stream
-xÚ¥Ërã6òî¯ðm媈!
-“Ûæ×0ÔƒßÇ«Cãt(±ôà™¾º™
-ÈŽ4§Äã!ç€w<ÖÏ ?Wµ,°±K’dÖ5Q˜#…øÍVCG|Cì À‘_A±Ç¹®Ð(²¢“ÑFŸÎÏ„`
-.Å$Éê¶îZ”Nð…ÅS[mY4w… J$Ûb4ôwpÜY“»Ëô\¸3å„ FD^Ö-‘ÀáÈ_gkq¸=Ú“ \²ç/Ƕë*Û?Ž¶édˆ®êÚ›é…kpšËÕµõ“èÛyO;c«ê­h%
-Ö¹ê¬W=úYž*¾+€TÍTíg•û¢ìKöú=
- p¶âp$y×!èÅ¡ZE«ˆÍ¢ûÒqk×Þ¨•ÌF‡ßþÃ_‘ìÖ ®µs[íÛ®Û> ´1Ašå©Øí]ÛBTP‚¿´óY$‰É_('ÁÅ]ˆ¸ïKZöÁበXm•âù•ýªu´@k䙊dg<t†+ò÷PTµ'½±ýéÊ(SG;îBôëUÓžE]·CwºR‘šŽóS ýÈ­Làó…«[øc‡=ѪKÖkp«©óª3ú…9q¤1„–3]\>¬Ž×"º¨"`ø^0@ȦÂ÷lëÙ
- ‚¾4í¹˜}"“ PpÃ#Ú EõY–ñf:MÛs£òsdd*T@“°gølûMÚä‹S£=1,®Ì"áT&ÓFXÑ´K’:‚|…Q¶U‡^§ã ÄÖÁêcœ‰p1ÎnêˈkæíRØ 'èÔºjVF˜Ù
-+š›!6d DÈ l`Û2Æ+•˜0’:î8=·=Q>‹·™„ÐBƒdô¶!QÁÑ¡óãøÛ`˜ìšCâ(ÑÆìFÊÍ<òð³ÌꩲçIŒ;9ümßÛñÇ#꘭ºN8r%ÀÞüÐK¡Pa¤Æ¼-˜…ys®Pàeõ<©lx´eµ{y]ؚΚžl9œ:Žø`‘ÅM!LáâçŠ ÈeAÌÆ-ùÚæ¥l€ê±i½
-2D‘2d^zꋹÂFÝ>
-Dbqj8X€ÎÌ_ñh…éó[܈² S‰K –Nuõ+·¡Ò@%ÊÙÇ¢„p²æàXOU6rj fY¤%¸žŒÌvë©q˱bF¢˜ Ȭ›œU$q§šÈ
-kd]ûe8¢Å§¡¼ ”å[²â brR` ŒÈIRâË`“ƒžR.C•¬>tÂú‰5ûì‰Óã„ã^I©–Ôƒ‘4Š“ÆP{𼌥]V3ÃBÆog™PÌGb týnX–0ÎmÉÓ°ëiŠƒøO¤’€<P³ªPõž,8BßÇ÷ ÐBfÉšèØ
-çÂ:ÙÏù´…ÔÝ»?¡éhÿàWlž'Ôm—˜ŽÖÍ¢ÉÈ|NìycŽ´CÌ_ \†ã¹ðQùÐ;{:5ÅO
-%¹;B¦¿cdN„ÈOœÀkî$áÈÅóQ'3ÊÒ©l†ÐvæBŒÈ ¶º¶ü‚™LÏ]©§ÊûH®– ÏxIT{‹²Ø…oaƇÞr{&V&ô²‡c(V2cºÇ†'å«ÐCÎ9ÌŸB6®øÝUÍcBk
-ß·gûÄqåWKÞ$Oƒ$2.ÈF¼]ôo^Š xÍ+VÕ¼À»ànb†]ͬ‘¢8G)…®Q!&¤b™]Õm "ÝR£p±#ä
-s¶"1Ä‘‚˜<èä”ÈsH±«ÔãÈtñÍ3à S #x«y
-.a\N(αºÉ±xHF@‡XÔ…Å˵v˹žOIµ7ùˆÆZf!ã:rä=!eQ—C]ôÎP~õƒ>³#_bÌA{IÖ,NcÖÑWPdͱ|”³g^0”uûøÈojR"Œ\‰0Š‰ÿèø_Pl®ŽAÇÝ ¶%”ŒbçUÆ"|!m­,Q²ÁFÖ§Ë9T}ï( Gß-¤+ûI[d‰Ž'Ýr´éŒÚ…HÌ tS‘Xôàß`IJè_†±÷rU/hz"ht[þnd˜Nq¾Û(ÀÛg°ñUÉhô,…Á”ñÏs¨SÎÖ¢f`ö¤i½Äˆsµ¥ 54ô”ƒ_NhøÇÊK}hƳâÍêÝÇŸd…F {h)3„6DÝp²ö‰œáêI”äô‰ô †²ïuR¥Xç^z(b?¤Yñ°á;ì”4GÚß°D9汶=Wb3ª
-½ØÀ¶Øhzœ<©ÆzÜz®Ì´-Õ
-fH\óô$™e¥D2: 6fã·Ý,àëª?-‡{l£8“ÆŒBCŽ›ªq!¥›8®(ˆøë TºèRØ;¾º{ '™¥Çô»å¨|áLZÞE\FæßêíáØžŠSåªZ¨b%YA®k²„M§ì[÷8Æî^]ÔqÉkW1냅
-±wÞˆjžB2È×¥µ•Wa|0ŠÔÅ{Ä…UBÊSŒ»Ë=Xiú=äÄ‹ÕüUfœü½òË‚Ý Œò¯X¯¥‘ø[ƒX_¼u™\aKSy‡JSÇòÔY’_úNUá& ‡ ñÚíqL6°M÷‹ s‡Ðä%d­ÀV†ñø²Ã®‘~òò|:cèöÞ8`”Eî€åpr×á<оè.³^Ñ;¯¡ ¿¿BfôæÛ¥£¯ý¾Õ@êh)ôKüß¿}¥É2½¬’&„쌽#
- ÒKÊc÷üÐéÿÝÁ’endstream
+1693 0 obj <<
+/Length 3806
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Ërã6òî¯ðm媈K
+Bã…1R]}¹úÏ°àd”¦®ñ/4‰&:^a Ö*ÚAt‡©mˆEÖe7[g®šæ©?¶Ð ÓÍCß14«Ú†[ç½­y1Ëú‘Áý‘ÝÞÊŒº=Û2˜™ts¿/[*eõ¾í³ªzaà0±°myºQÉÆB„ÝgÏes’ɵ[¹Gß*å¥a¨éYßí›SÙe]ùl·M«ãEµöô ÔPNÀës—6ÆFÞœžwµm[6»%V–ï‘2l3×°U
+:P%ý¶·Þ@aâÜ Rø ñO«`ƒS•ÙÔÙÁ2`  ´ Àê¦Þ
+Uý©…Cщ
+›3Þ#`Á{2KSƒ';Ä?úÑÜ"”mÉÔä šªÇ›™‘”ƒ¡ô.ÜŸïù!xf°úž¯ýxÝÝ ÒvŠÅÞJ­¸û sȺ|¿=dÇ£-¶ 1' .aA†ö}/J‚ôm:¬B¦‚¦ýЋ¢ÈÌ)¹Û±LÉ”f/ ý@ú… [:áØKN%P“b’kHØÀ÷îÓs çD@Š€HPàØ|/-Dn‰ØãzaØú©*ÛŽäo«´†ÈÁ„sekç„ÜwZn…UJZCÑ‚ñ"‰#«îqÔ•æè¤ Î– °RHðŠ>gM­<7§'FgqoúZ02þ<ÙSm+§¸%c§d~I9rš´µ½Q›|
+¼ î&fX¢¼º‘¢8G)…®Q>pÊYæÖ.ƒH·Ô(ÜcìX”mÞô§ìÔ+&5 ´gT¾mR§X¯›Ô ŽŽ±ê80ÞfðÁó®fA‡
+QWMô6!Ö
+%3+/ÀöÎH`ôÈ%h3 ‡cz€dÏ )œ`—lIâ­”ç¸õ j:–Ù œÀîÚh4-̸ŽS/H#gÈ·[[ãnÛ]‰ŒÚ²Å4F{iš…ÁߊØéÈK “‡Ó¥ÁÆ}ÙBC^0x-=«GÁ8ç8ddÜ S•5†™DHwƒè¼øù¬ +ˆd'á»·Õq±›r$gŒ)±'Ö; q :µ;ÈÒä¡oò£ÍÞK¤€Çò™M)´Z<73<H4Â÷»_'¯Jp?2Ú×û/èÀˆì­l ¢e”‰‘<Y‘Ï:ÛÿŽÔ×vÞš {êûr`ºà/A¸‹@G¶³
+–(W£™ã¤ì4˜‰HEl&p´°»¬¯ºa³KI4*
+¤h¬Ïº‡¦¼Î«¾°b†B ÅÓxn‡€_nßÃe'ñÃŽ¬ŠçÓiäâlÎ(d†Æ;øã–Sî1¥B¼!‚Na+Kv&–z,dÃ*|4ÎZ;·ƒŽwlqùã±*—q$k—f¦tLÆhå¡èT,2»±ð5+ˆ­¬°„¿"ŸqªŒ\æÃÉfOÛ¢˯i„òâ!Ë×\T?e„ßغà7~cgà7¤úþd )D"“AíRV`_™~&›wmûÇGÛvõnå…Z/|79¯HÉ]J‡j à`ô=Ùv†¨LSéB`LQ¹có/K=XÎûç{ ² @ 7»&o*)QÈŽc8s
+àNÞ­%!Ä9t…o¦ZÑæ`ó}V—-…µ!ø5Ã-'s“4}ËmÙ€(52„µ5ì°Ð†NÉÿ[n‰¢Áॢ 3IEKYY¬dK_k¸Ì5=™ÔHI«ô¤œ
+m‰õ õи–x³é!Ò„’Oê`TèÀe€Ð @Ð!¾áz¢t@´Ó;€
+=+ÄKR6Of—âƒ+Ì–¹´«TN¶°uéü«ã´¿Æi_‰±d'¥s ÎL““ ‰È·…@EÓ Ñ íXIt`¶sÅ´˜¨–Šð\ɲuµ©æ@¬ˆ_ÌQËCâ ¤‹ïxÎà±VI'Y¹…I˜Ë× -Ž¤$C, v2Ђ¡¡ãÈÙé4.u€tOðE}P[®)]Sšáô- ]¼Ž¢Í$®fp#Á“Ð(ßÛüiQî[–UËñ…+%jð›€zI½šúMø¸C+ Ê¥¾Å1Îp)hUoWWÇÂjš¾6ݽy,öMNp%¶NÊÒKÛ¹bû†G­YõÔ¶NoFV¾­z´å³»—™r¿šüƒÛðT¬ÞÎý'H¯§þ ZþÉ1 ×Û °ÐÙÙ“­óËšª‚},~¾EË€tIÌ,šj_ψùex$˜§â)ÖøÍ›Á±V­…s˜JHfÂd|í
+é2„€s£(ÐòKUÃL4•Œ–G2`ò ?’P"Ï!U¨( Æ‘éâÐ L°Ð~BÍ[aÚDoJ0.'W{ä*›‹‡äÈDTLqúµ¸rXŸ8ÒÓ)éRí3éˆÆÑŽ}.AÝxHÈI\Ê€åÖ*ï+ÈöÎЖj›Ðgv¤›Q†ù­.§"f‡’s¯£ÈšCäÉÄ­¾2W „‘¨ºAÀ¶*pµ” $6þ£eà›ëƒÜqw‚myA
+_3®
+ö\Ρì:GSø͹n¹<n³ƒìƒ"ÑòĬ]dréøB$È"Ažc"«>á[ªÊ…ìo8V€Þ媃 é‰ µÒmøû Ã\gÆ)®dŒmàâ¢ò2g4\r;”+)†“â!h†pf?€4m×.õ\ô0íN–}ydžýóh9+õùeÃÙ2)‡›ÍûO?Ë
+µ@öÐЃ0´!Œlûƒµ²Oà ÿh"ˆÀà &hZW¢ì: >¬Ü½ªxšªNgn Š‡®Ek~Ñà K5ä")&\ìǫ́*7dÅJã:œ¤¿®¹2Ó¶ôéíH’YWJD £³"»î½f7{çiË¿,¿ò°’ñä©HhHᡬÝK’›8®(ˆpÄʽ%¹G%ao:°p°pò <`»¿BIWÎ$›]k=›Sv*‡(T,'+ÈyKØtÊ^Èæî^ÝcÃ’×î‡2\] eÿÛ˜aá›ÓÄ3c%HŠƒi,Xíʆa©yèJž¢— ã™4Š&N¥rÁƒJŠì$WkóÚ7‹ãWÐU"¡%ÞAl`ZîTOUÒ>ïK²îi<y \¶ÈxzóÛÿjÆÆ^»Rn·(¹J dœfÕZñ3I½X 7ô:¿µ—êÈmØœÖØ­¼$
+ƒ¿cwèÅƸˆŽ,ø¼:…ù6ýÚiò²v·HJfœúÅåÀTN5Š†“j£ÌÛQôéõ(Ú!Ç`Ër;òm4Æ‹’$ysëérïYÐ$^ûj¶ùýP–~`i„Y)BÉ ´^šžqäá Zx€cåzt–‘XtТñG Þ`âܯš²xÓÊb;2|‘Þ°Ò¯ƒÅ ìÒ,!å1ÞùÌ4U€RõJ}2»‹¾îg+vÇ3*2ó| ª‡C:"e˜Ø½wŘ_<rCX;KS¥¬ÌÜ„þð@|v3G³ lÓýâÂüþEhò È­[é‡ñâ5îŒqåÊãO
+!D!á‘YR>ü<÷’ôÿÚßÌtendstream
endobj
-1306 0 obj <<
+1692 0 obj <<
/Type /Page
-/Contents 1307 0 R
-/Resources 1305 0 R
+/Contents 1693 0 R
+/Resources 1691 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1282 0 R
+/Parent 1675 0 R
>> endobj
-1308 0 obj <<
-/D [1306 0 R /XYZ 85.0394 794.5015 null]
+1694 0 obj <<
+/D [1692 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1305 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F48 953 0 R /F41 939 0 R >>
+1691 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1311 0 obj <<
-/Length 3367
-/Filter /FlateDecode
->>
-stream
-xÚÅZÝsÛ6÷_áGy&B‰/|t§çN㤶{×™¶ŒDٜȤ*RqÜ¿þv± Š” )¹væâ™\,°‹ÅûRž'ð'Ïm*Ò\åçYn„M¤=Ÿ=%çÐ÷Ùdži`š¹¾¿?ûî­ÎÎs‘§*=¿_ ær"qNžßÏ›¤B‰ ˜!™¼~óöú‡_n//23¹¿~s1U6™¼½þéŠZ?Ü^¾{wy{1•ÎÊÉë]~¸¿º¥®”çøþúæ Qrú90éíÕÛ«Û«›×WÜÿxvu߯e¸^™h\ÈŸg¿ý‘œÏaÙ?ž%BçΞ?ÃC"dž«ó§3cµ°Fë@YžÝýÜO8èõCcö3Ö «L
-–ÔB¥RÇ­,E&%0eF
-eÕ[Yɘ•Zy^·m9›–uñqYî®YªD¸L†ÄÄ÷\ùj _*+œÕj¬ÀIž*§&onîî®^S»Ý¬Vͺ£‡ªFÕvÖ#•&»&~¢ºx*çÌ6«‘ç
-=WD‡ÑrÉyë) ­uÖCÛ­üsÕ :ý
-°ì¢ÚfrrÓtedJ
-þ¹)×/ËæaWpž‰Ôºü¸àÀ<Ú£D‰3‘ä»U9
-ÌfŸiÎÑ)åœöm”1oÚâá&m
-<𙚼… ö±%PÞ¦–!ˈ"’\ýÕÔ>}ÏÂaÊ!©U,Ú8Å“ .kQTËXð³Âärj˜;®º‚Ó–gµ]B‹%fò¢Ôýƒš?ë:&<²Qͽ¢nŸËuËàK¡:ÎíŽOƒ}Ò<#¿ÅàáhŸØ$Zc*(ÿ\ÈÆ׌Ә+÷e|pZ0ÜÍOG°ÔÜúGÈ”šut+r•y6tç0iÎ5ÁÂÏ"Š= ÊNØÄM6þªTOÞš@^–Å’hMÛñùÆï þ„øò$ò<
-îGNƆ‡±ïöík"Ã6ñÈš¹KOœ’,”'jæÕt|*[£Ý8RÑ4Р±j22ÉŽoß­} vÆ› .~V«%¹ŽÌ·Í4û 4ϵwr@ Ž© ú½|E]—ð(äsôîW"0PÙ!aB‘:9¹îˆ‹+/¸UC³Æ«á7>¨<2TðÚ*³A9lŸY;¹}C×_øß%‘|x‡ß›»WÔ¸{É­w¿rƒöûn/¬ü›ö×£õëñcüzT–âz.ä„–„Ï>ó=­UÄK¸Ç[>³'šˆÏ˜62JM˜¼qØDÛP«ªçæ.óÀ\tÜ~yÖb(*–'X6ͧ͊%,F¼álÑzš]"Pg~,zë9'kgw×7ÓË7onÅå퇋\y¨yò‡t—ä:w]ßÜ£W:˜Ne ÷s4rN§z®í‘{ú²WHäÂYÈyŽ
-LÁãB€û]F’_£d´€”VŸLGÇø!À´,Ö-h†Œ‹~"&ôsýçsÎjü)y¸¥ÐÃ( 9 ×ý½É8]¶‰È·×›_.AÚ{¿TŠ‘P‰i·›¡­š¶­úÒós±Ü”Œ±àØ#ÑR
-ÓßžÊ;2A00¡ŸˆÄTˆ_6ÓÿC˜‹ÁVgNäRGí€é0hÓ³ÏÕr>+Öû÷/*ªÆc²Ͼ쑽´„íQz$œ
-
-úA‡¦>|p%L˜»¯´†\GŽnàڞݪîÊØÝ—ýà ÅybËLùãã›åR=VàC¹ÛzT%èj=ž!ãiŠ9Ñ ÔÚjéY¼ê-uùs¿BØ „»Æ^8¶£dH\€êcüò¹}²FG؉ԥ.Z:mÓ(¼‡„<­_þËaŒ#‚÷’šTãKŸüqdtvÊŠuP[ËMI#ödD§(¿T-%Hk,I°¶éè6o÷4÷¬C•¥KÉ\.csa›Ûu?ÁŽ¦^¾PwUOyO<,¥pÂÞgAŸß*ï¿¡-¶ò›M7mý4Ù`šHz¸ic!¢o"¥ÞfN½D?ë¾Ópþí•8 |-˜¶J"'xI£’ÈÞa'¯ºÃrø±\6ÏDíš3.ˆÀ‹ƒÖÖ(‰z¶FÁ£xØâk6©óý\9¤/Áˆü$ì
-¯"Ò"K•þ¶
-Êt€é:Î!ö:÷qDÆUßM¸B‰ ‘÷peånÞþÿƹ²Ù \ ¸Žà*p pe.&ü{ïqœ è{T|Ï‘?~£Eâ ^ŒøíºI'+J©ð0Ù(ë3œ´¯¨ïÉ RuÓû †õx29 ûˆ2ÃP\
+1697 0 obj <<
+/Length 3567
+/Filter /FlateDecode
+>>
+stream
+xÚÅZÝsÛ6÷_áGy&BñMðÑMœž;'g»wiûÀH”­‰Dº"Çýëo ðC‚¤xz3Ï„àb],~ûˆâœÃŸ87–Ù\æçY®™áÂœÏÖgüüú~:g™¦C®ïÏ~x¯²óœåVÚóûÅ`.Ǹsâü~þÛÄ2É.`>yûñæýõO¿Ü^^dzrýñæb* Ÿ¼¿þçµ~º½üðáòöb*œ“·ÿ¸ütuK]6ÌñãõÍ;¢äô80éíÕû«Û«›·WÜÿ|vuß­e¸^Á.äϳßþàçsXöÏgœ©Ü™ógxáLä¹<_Ÿi£˜ÑJEÊêìîì_Ý„ƒ^?4e?m3R[°¤b™i# – <™æ,s¼72 H9r¡‘çUÓ”³iYŸWåî’…äÌeb0$%¾ãJÈ—ùB挒c®HòT:9ywswwõ–ÚÍöé©Þ´ô²¬Pµõ©™æ`Vî'ªŠu9lC±Š³<´ As;ù¥Z•M$•AJ[ÓpííaÆä* )›„‘±\É(âMBWÃT–ŸRT1Ç¥\ŸËÇâkT,Âs¹Ï ñ¼ŽUÝâ”çS%%LM…`¹1ÒÏÕÛ
+êíB
+¡2sî¸WBÑ’-ØÅr1VäÒk€QUL¼rŸ4ˇªhšbz~,+êýZn–‹Âtô Hì ĤÕ²ßCìíý^’{U<³âóAßM\îʶõŠ!JÚG@¡U?… ŠÔT,È¡©»œt0sh©b’[•¾xÚ÷™³ÌºÓ•˜v:BõëvU•›P¥’ŠþIf|Z/ô^´m1ûÒD­É
+þ¹-7/«úaWpž1k\~\pdJí'—Ìjˆ¤#ÉwOå Àë×!yaƒI*'ˆš=Ю½y¬·«9uø¼Ž´¶Ø´å¼›%UI ELÎÅéSŽë>\mÚÆçe‹i'eÓÖF˜ ¹31ˆW¦+l=rAY¬ºi `ˆiH9à$Fíæœ%f
+’ÒLÊ?·>ŒKK c$1ê¤t
+‘Ç«?5¬–T8­ª4Bá8+é~°ûn„‚4B(Õ’ygüÝ“Ì
+ªõ¦¥NF‡ÆpÅDYíì‘nv¼jõfÙ>®I
+ðràÈ&UKÿE@ãÕo>>¬Åß•x¸ŒÍó+Фâ€óݽ†®VâqL2+L>ÎÜdtük¶!¨ôÀ°¦>ì¾àæ:ß;î¾®#î¹z÷]Vmù
+|*7`[*Ž×ãNu1'ý쇭^KÏâUo¨‹~>å„°?Bw-D àèG‰XäÕg8x¿ÝÁ†\Š g]ò¢aP%*1L|JÉð£¶f:" x/©I7b Š829; UT[«mI#öd$§(¿-›0” ­ðüŽ-Ý}ï±:GëÐ=Œ³d.—s¡?uÿ0uåËU‡_(LÞyxï€v1 úüVùø =h±E”_oÛi½è¦ÉÓ$Ò¶I˜ãBèáÝÿÔKô³î ç¿Ê0ƒ eu®ƒU¸˜à•¦ä‰½Ãΰ~èŽËâçrU?µ­Ÿã‚aqÐêÂÅÀ(ÐÓŒâa›C'T¾®ŒELŒG"_W
+æ õ…{dhÅò\w1ˆq%ž}ÝCÕ`<P
endobj
-1310 0 obj <<
+1696 0 obj <<
/Type /Page
-/Contents 1311 0 R
-/Resources 1309 0 R
+/Contents 1697 0 R
+/Resources 1695 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1282 0 R
+/Parent 1675 0 R
>> endobj
-1312 0 obj <<
-/D [1310 0 R /XYZ 56.6929 794.5015 null]
+1698 0 obj <<
+/D [1696 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1309 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F48 953 0 R >>
+1695 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1315 0 obj <<
-/Length 3178
+1701 0 obj <<
+/Length 3339
/Filter /FlateDecode
>>
stream
-xÚ¥ZÝsÛ8Ï_á·Ufj­ø¥Çn›ö²½íöœtnvv÷A¶e[YÊZrr¹¿þ
-à¹&$Ö˜P $¸¿Î¢à
-¹?RìÕ! ]š
-7>q]€ÂmA¾äu†Ü;Ï»rµ£.ã®Ë{ m)@'?š‡²Ï~b~B}ƒª.ÆìVÙÃåóº}öË×Üv<ÑÚðE7* `ËëÞçºŒàž õDN»>Cn)B“ˆìõ=×ÄÎP’qh ¤‹ƒ­)p«LÍcWZÇÍDàitÁ@Ùy 6°9V4b:s€„ð
-KúÒœ?#9¦×e8[ëbù£
-M¬å‰ƒçŸ÷'LDí³u‡©ˆFŠ±<FAÆ(Ù_þ |=×R¸ Ò4Œ£ÌklÄE——U;´á>Èõ}ÂÖ›ÛØQ—a¼í.~ì
-¬7žéû\—£™ç²NŒeÀrG”pÇÀItš¼±»çšØ~øü §£ý‡ÅŸþñMJ˜zú èVf*{¸„–`ø&éßF8[ÆçDâh+
-•P†™÷ù ­Î¯Å)‡Ah{D°‰Ëv.ƒP2Œ´v? X¹'ÞHL¨g‚ˆÈ
-õ˜.ƒc:Ù<=YžA|*ô«;{¦ó­‡
+xÚ­]sã¶ñÝ¿Bo•g"–
+oùO»mu³h›bÑuÕøÔBÇQ–‹lÖ_új‚Ùã@heF‰! ÿ~´5\½óí¹Èæ¶Ûmëò\Ìë»î±Ù–]Ñ•ÏQñ¼¶áÍOkŸšºµ-¡º†o?^âÝ–4Ï[Û1Ù#/xw÷aš5!xD¸àRPQ. žVD¹ÖÄ;m½lÜsE
+t<…eLYÓ“Àé@¯­]veã‰z‚dp¡ôV!‡~îÊ®‹]ÕñÊ-27´4I$Q!bÇãÁz¢,’(OTÆ4Ñ ugJó4Jóܼ®x}ªÓŠ¨&o±,–p±ú™ŒMg¯³¨&ø9KÀ½1d„ÔOäÉY(QëD®æ᎚†o}M#2”Ž0¹Ó7Ä£¾ç´ '~tÚæ0<»'k™ ’5⽬‚TE"‚’—œT€<JEmÝLI_D
+wÜ=­ŠÎ.@äËO‹Oí§‚OÁSˆô Õ ƒÓš82¹ñ@‚WŠ%¤”vò@„“ÁØpô¹¨vŒ7á.5“Ê"£Ó7ìÎD¹’†i¾‚å´ž»{`üÖßß~OÀ}Éû—Ì®=%è“= _ÙÎn7emIe¤4cb9tZÍ~äÜ:Î=6»Š½Ö=îZïÇöä©z°µÝ‚a8ñöæöêCKð¼!y¹àÝvd8ìØšÚ:ƒ;
+ G:Õú/øë¬ç¯3§9GÿÌ7»¶£ ï-= Þ·²…êö -)¡Àqï¥4yMÐV4ZT˜%>nh„¶|Z‚A„’bÙDBÚ‚èËÊŠ™i
+¸ÁÇwÃù” çˆ9Æw7Ãé)ŽóŽ †²A7b‚IŽ«†¸0Åu7^t£ÝÙ“D‘|Â@$e2÷IB½ì%ïe`øB[äœ!@Ì{MrÄqžÀäªËM öWeP”õ
+ý¢\Mߧ¡dl"K»ßu#wRäpq.ÛNC]#i¯šŸŽ¤Ô,Ε8Iaæâó”€zšÜG®¿@1êG±‘é0~AW!•‘Îý%U¥» «õÄb"‰L’¤_dö=Nì«^.-ºpÍ/í\A†(Sùv†({f~201ÃÁig/$°go8ûÕ+ÎÞS!‡Ýö°è–O‹­]omû8Õ®S
+üñ« ª Æí:%ôƒ»ó­KP—C>ü®9ùxäAªŒ|U \)Éœ˜ß½û‰
+)…4â=eH‚›À8'#èÿ£÷e…-µP7†üÕ5ïTšý×Û*Ùj"ÒôÿÑGSie(ÎW5¢OuZ#Ußg`‘m]³(k‚ÇœÈXDª’×Y T¼ô-ã4’ñˆ—‹ªÂÖ‚9ÖþJ‚[9ÔŦ\Žõ@Pí‰Ãݶ¨Û’óvÀ“5í7Â,xò ýPb¸)#¡Ø¹ré¯ôža¶ÈSì‰5`W%—ý™™ß£bgèFe©»Ø#Íš†9—6½\ÚŒzÁ-&¿R’‡¥%QÝ Ôîè}Rã\–e_æeqʱ W<Èb3¥Ð ¬4d[E¡áFXžÓ~*\ñ,KÈ_Ülˆ–R…4@—fHÉQU*Ÿfà¤9G O'»B§,3’-w{õ縘Àõíå;Zy$æTBr*!C–Ð<[^á¨yøæO7ÑÄá|ŸƒÁÞVÕd…zåZ©ï1¤¡5âò´–pȶrm Úéœz)÷ «Ú†0µ]Ú¶-¶^›ÑtQƒý4­ýÓy.ç7?Ò —€½ó¾àrªé|ªà££Jýµ"´,vØGL#í]qÁDÎxàY„YÍöØP_‘µ¥$LÕ_£oR)·Æ®:¢ ^’¹ýü¦e—Tö¦ ×fÄ™ÚøL'kÆ—% ­ §«]sgðA‡;œë]7èpŒu´œo(ˆÛüºA‰a+†S²-ÀôÊî¨nˆº·®ï¨eSÿÇòa*SweÄDšKìEy—Qì LPÜ Å0[îàoÊÄqdâØ»ò±oSÖOÛò¹ðgáv i¸O?!ÓñèóY±D….ï±
+õ*|Ö­¨J
+võ¢ä“"ÒFä¯o¨&v¸{™FZ+5Üšz
+r‰ÐdÏé;Ñ€³±6ƒÖ»ŠF\@Ë}%ˆžã!3
+í«iãCªL¹ÎŸÿdÚ'¥
endobj
-1314 0 obj <<
+1700 0 obj <<
/Type /Page
-/Contents 1315 0 R
-/Resources 1313 0 R
+/Contents 1701 0 R
+/Resources 1699 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1322 0 R
-/Annots [ 1318 0 R 1321 0 R ]
+/Parent 1675 0 R
>> endobj
-1318 0 obj <<
+1702 0 obj <<
+/D [1700 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+470 0 obj <<
+/D [1700 0 R /XYZ 85.0394 227.0652 null]
+>> endobj
+1703 0 obj <<
+/D [1700 0 R /XYZ 85.0394 197.3345 null]
+>> endobj
+1699 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1706 0 obj <<
+/Length 2753
+/Filter /FlateDecode
+>>
+stream
+xÚÍZKsã6¾ûWè¶rÕC<’ÇÉŒ'ëÔffÖã=l%9Ðm³†"Q²×ûë÷k4@ñ%;µIªR®2ÁF£Ñht÷×
+ÏjDYì“L…ŽmæX?TÅ *^®óšyÕ6Ür‹¥®¦&{ÝØ*¦6Ÿk¸i¶yé»nò¶lß ­#ˆ­š§n6¶l4îªæ&¯ºÞ‰~ÍþlêÖjÜꢡœ¾V/›Çb·+7›‚Ô°féÔ=çÇc¾+ gnô5·L|ÊŸ[ì™F8þûoLg³€±-öLyÈwûr}¨ò¿ó‚[ær~"üÃ÷–·´Ž[¶NQ·B„™ÈÚ¥³ :ïóÇb¸>ÎN9§‹©HðŽâÎ$"Aˆ@B/àxxSWÏoi?wmÙšT k2éGÞP¦„bHXoüø?ëfÏÞZ˜ûl¹ÓÅ8Ôµ¡ EÁÅÂDYF1Ì»»7®zAßñ¯ú¦A?•ë‚¾X“û„ü¬„J&
+eø(4É=×kjL¤‘bf«°2E¹T»„k£¤¤´B`¢(Z~8äÕªÝçëo¼†¯ÅîÑ'ÐÑÌp‹Øãäôjm±x.—ëÞyç
+~á´¦5¢ºí±3oì‚…ˆUN9Š(>O6»=÷ÿý©Ù}ëËoõ†ßhnGº©Š­Ÿ…"”ž,._ßç7eURŒ’°ÍÁ«GÉb&î«Î*.šÉßN'ïŸÜ(JðíË/fèÏ Ø!üäÜ„Æ}ÓzY[èVÖ…˜ µ‡Cii^ÆÌ>×iÌì¸h›nWíqëØ©3!í/ª˜fT §AÁCÈ©Mìí¢]Öù6Éžô¡(q9ÿA—·¢ð„máþ|½7S'vÓpoì·Ì‰v΄N·g笱4éÐ1ö»¼nÉ(µÛ ü¤@’R&ÕIæô'Í™H¨LT
+ä-#=@SÛœû··jPo
+¦äpe¦8­A qQ=†Ž{Ïæ£yJÄá½QZæÖ /ïOLÕ²ôÏûœg¢Ä-Ž(ì¶hx3{þ–ŸäHÔÒKçMn©*sÎ^ÇOÓ¼_d:UæýqŒ%±P± C¬¹\Uƒgálí×r¨+Ú·¡ˆw!ÓÌŒ Ð{ˆ ÏÆÃŒíÙ‡b6÷l7EQàli§6'¢|Ýl·Î³è¥báEeX!îæR·JQW&‘õ ¤­õÃWfÆñŸê`Ž®H›à€¶
+ Ê`úáPÉåÓ}¹¾§¦rˆà©]aDt§2Ÿ|üaO¿Ç°¿/ý8G¾`V àÔòŸ'¹(
+ñùIц•Îõ8#âÔ«”¡Nð I­-ª4ä幓¥"K2ŸˆÆÛ1²¡„–:%¶ù3Kçc"µnü|mg× \Uçu›ê µBia‚`§÷tv¤/›Ä3ppä!|†Â ~©¹FVòöBºL2™ V:ìVá芼îųj&(Îm´ìN¡4æÃÁÈÒÚ‰êTŠ$¨f¼¥ð°]ä5Ráí¡¢wÃàæã‡s$n’Ñ‚¼[&ѱÌ-_&Ø”nú
+Úa+$*g«úqØy!¼)*Ÿk•¡÷×ÁŸz†BYº­ŽPwiyÃ>#ÁÊå5þ«åäŠ>µ„¤Gº¥î&zñëBÚ²L3S¯íÖz´#¼½ÜªÅ‡+Zôå¯ú’Ý¢Iz^©´°ØD±6VIÃçGkç“tdX>¯ÖùúàÜvpRËè»@H·ph­Y¿ø+oÈ¥ç±È¤#u8[ôØCå5š5ñ,c3T•.ú{÷ûÜAcŸm! Ž_9~Ÿ³ú ÷Ì]§km^)‰•ÞhýÊ'‘Žk”tW\ï ðH‘3@»¾ä)®x¤6’C †x¤x„fլݥN&ßFtê‹š]àaÏíÂ`=0ÂÏ.¯¹tÖT±~ BK/ç¡iýG8¢S±âJ[â@ÿ†*ãë$Cu'rl½t¾IÊB&¤f— é…Qô,k*‹]W«Û|íN£ž^ì@ü7‡=7è>á(ξ
+,þ³gis×9a®˜ŠÖ'uº k>—×ÅT¾+CAõ­ßPúùß)XçU´§Û×Pb 6lþ£á·¡©'ŽÜ±‘É 
+endobj
+1705 0 obj <<
+/Type /Page
+/Contents 1706 0 R
+/Resources 1704 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1712 0 R
+/Annots [ 1708 0 R 1711 0 R ]
+>> endobj
+1708 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [367.5469 410.6007 428.747 422.5009]
+/Rect [339.2005 701.7636 400.4005 713.6638]
/Subtype /Link
/A << /S /GoTo /D (zone_statement_grammar) >>
>> endobj
-1321 0 obj <<
+1711 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [483.4431 196.7586 539.579 208.8182]
+/Rect [455.0966 503.2689 511.2325 515.3285]
/Subtype /Link
/A << /S /GoTo /D (address_match_lists) >>
>> endobj
-1316 0 obj <<
-/D [1314 0 R /XYZ 85.0394 794.5015 null]
->> endobj
-358 0 obj <<
-/D [1314 0 R /XYZ 85.0394 649.9934 null]
->> endobj
-1317 0 obj <<
-/D [1314 0 R /XYZ 85.0394 622.3077 null]
+1707 0 obj <<
+/D [1705 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-362 0 obj <<
-/D [1314 0 R /XYZ 85.0394 392.0307 null]
+474 0 obj <<
+/D [1705 0 R /XYZ 56.6929 686.5799 null]
>> endobj
-1319 0 obj <<
-/D [1314 0 R /XYZ 85.0394 366.8157 null]
+1709 0 obj <<
+/D [1705 0 R /XYZ 56.6929 663.4862 null]
>> endobj
-366 0 obj <<
-/D [1314 0 R /XYZ 85.0394 245.2415 null]
+478 0 obj <<
+/D [1705 0 R /XYZ 56.6929 548.1865 null]
>> endobj
-1320 0 obj <<
-/D [1314 0 R /XYZ 85.0394 220.1859 null]
+1710 0 obj <<
+/D [1705 0 R /XYZ 56.6929 525.2522 null]
>> endobj
-1313 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+1704 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F63 1355 0 R /F62 1352 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1326 0 obj <<
-/Length 2907
+1716 0 obj <<
+/Length 3489
/Filter /FlateDecode
>>
stream
-xÚÍËnãFòî¯Ð-20êôûœ&OÖÁÆÉ:ÞS’-Ñ#b$Ò©qœÅþûVu5)’¢d“2FÅêêêêêz6)fþÄÌXfƒ 343\˜Ùr{Ág`ìÛ ‘h-Ñ¢OõõÝÅ—ï•›¬´³»‡/ϸ÷bv·úyn™d—ÀÏ¿ùáæýõ·ÿ¾}{éôüîú‡›Ë…4|þþúŸW}{ûöûïßÞ^.„7bþÍ?ÞþxwuKC6ñøúúæaýœ`z{õþêöê曫Ë_ï¾»¸ºëöÒ߯à
-7òÛÅÏ¿òÙ
-¶ýÝg*x3{‚ÎDr¶½ÐF1£•j1›‹Ÿ.þÕ1ìÆ©SúÓÒ3«¬È3)€Ç+–U>jÑO/Ëá0³ÚêÓ¼h^ lg Y-¼`&3[X§ANºã•r& ÆH<_ï˜tØ(Å8¢àxoPÁ‘00cµ@:Á™QRs¤øáraÅüþ—ó£ãð–8Š™…ÍáqáÙo3Á¸AMŽ;=h "¾¼ÞÊÙ»
-ö3ëo)ñ]ôÇYÕ3X!ìW«™ † "£ÀÙfS]
-3Zü¶Ïw`|þ¼XfËK
-üÁr1”à'<Ì_8—9¢òó§u±\¸©–ÙA7ÏV«Ý¥ðs8ë–p™•  <6W‘jU”Ùî™0ïn~"°Ëº)ª²†€¨¸ß­‹Äi›}l™‰ÏcU/P ^87ËA½;ƒÔuq¿Éß
-~«OùnW¬¢¡Áã iœeÆ@•@ UÑ`Éä]%kÏS¼ZoÎY;Óv4…ŠD×éH«d=¾Á*Èö›DW¤Ã€ÌÁÎôÉðºñSÖ2Hu)Ë •TÓ@ƒ2pò…À(΂Rê¯,4
-Ä`APŒ‰abí”8Nži®}϶•‘Z¨ó€€å„4ÖaÛèÂìòå~WÓá^ƒá„0ZŽ\ ¡â¡[7Ö) !Xy÷TÔ“ùb‘2Îëbbiã™7\½fiÔ|_nЃ—…2†3εæºÃ¾À€¿šÂjð«.UG)€–Ö ˆ“mgk€Š¹úXˆÀ™oõXBY0µ¸)§àÚ_ ·ŒÊµ¡§Ü8BVËwi±¿p甯
-~0Û(£<(ä…@t 9†ÍdšjBŒ)ý¹õ;š#QÈB¬uc{ Û¶ýàÇíŒRûcŠO9¡ºðƒèCøÁ!JL€nà –ê,¤: uÕgž§íÐþtñE±éLV>Õao&,RB !ß-rÂ
-¡¸|mÒäÚœ]šŠ¨=çb ’@èʇDsº?;•ht& Î:›h¢XVM?M)ÒCû`Õ I¥OuÚ_;ª ›J+œLx}^†ŽjBˆaëXÁ ¥º¬ì’‹’]rAì(¹àhL.q,Ým!rì®ÒµîŠå¬æ1Ÿ !—r”ObÝ‘®fà³P–òQ ûÚ|2’äsûûÎ44«ØŸ7‡Õsh©æ°\eÍqŸ#”šPîŸ]½£šX^Ž®“‚wn¸þ¨Ê8\rBÎO±±]ìŽmìF¢x€¬÷÷Ûx¡ð»ç2ÛK" [NÀÒ&Û¯&»Íê&O0^qÕ©¹kÍ,DyÊ ’¥Ð”ÌžWy,
-{u~l+Þ0‡©E‚9(°Ñhp÷!]©Üö­¦¥_ô'LXÍßh5ù²)ZWrL¥‘J2í¥Hsd¹Õ 2H¥¡«EÏéË@óH“›Ó¾+ ‡BwoÏûnŸê´ïvTcß]€8OÙn…†2>'0?ªó‚tT’ÈÑ=¬óým»±Uغ1€7ƇÎá|GÜàƒãCtc
-ßѳñ¸Òèµã­8<“â⻑( ^8T‰thR šN £Céå…¶…üò½ö}ë‘¥nkùÿ@QÈyj›#øß©ÚG1 nšó†Ø·:Er訒°)
-S`’„BÒõÄÐz8“
- õXôÿ@««hendstream
+xÚ­ZMsã6½ûWè¶rUÄà‹
+ÅTåGkQ¹RÌwÝ@¾ñ Pp—ÑFô ;Rfß,û¾ív™éŒ*ªÊÚÉt‡ÞÙ ZíCœ÷ h°̼iû&3;ç
+‚ ã© KsB£uëˆ5èZÖÙµ[€j°ã®Û5¹É„-˜ÿO†KFãj›×Ý!Âô«æ¡>l¼N¿²’åŒ/¡]É0ú¦[Ö›]3ô_ÁSVÒ5úIN1P^0 pz¨í Ê«BTb‚aT¼8 >Îh€–àçB~F©Ôù`¥²ÁhAÈÅ£
+",à²Q*£Æ(U`™ë1ŠG‚™€$cSo½ZQDê{Ô€ Ý{lŸꊡ»¡o9`wEÂj Eî¦ x³Ú
+Œó¦®b,ƒfÈ›Ð<æM¼ˆy.\Þ„ßmý»¿M¢nEϾ+‚Ã=±&ס£õ·úfÿÜì‘V’µ.óIuQÂJJ-Çàý¬tÆ*e’
+c.§O \2ñ¹é“©òâÔD? xUŒñ±)½BèÈÇ”ãB@6@œK9\;å*“rð©‹)Ç©¥Å(失èbrvÄ°¼’\R©óÞ¥2Ë¥à ©¡]Ô!Je”S]ÇùX‹±ËŠ˜Z¤ˆ©{'©ïºÔâî-—ÍÓ@Sw…ÛÞ]‘Ø*æ²
+Í“lâÈ@ø‡¡èNŸ›M&šœÏ*›ÍIVAmÏÁAÂvK”W‚w*uAê‡ÃÓªN÷<ª„$ìåÙ£TfúJ ÎR‰ñüŽQ9† ±{cìv!v£{ÐÙî·í@ío_wõ¶]’À·>Q/-20nO½Ûºßþ°ÚÞó»
+y¢†½Š¨ÌH›äF©k:hYHŽž“ê@ryd¨ÛÍyßUÆBª·WBy*uÞw£ÔÔw ÎK½_!P¦Æ` ˆ©®.+¥2šŒŒÁJðÞtY§n¬etch7†æÑñ"º1\ïÈ£CûèÆxá܉O%mêgï¯ô«Ä$|;ÏÆ×å]÷}C×d8Ôkå”ÁÒCçE×^Æ ât’Ü$/„Íä—ï +&º`\&ÿo …Œù ´kþ'Ç}dal¸Ã4|°)*ÔÀ~Ê+K‘:w^mÍÝ]D),ÍWj¼³
+b︌–OAFA2n]pR zžš=Œ´E²ÌÎïn­˜w$Óìêû—‹S+“Fþ‚„]Þ}xÍÙÉÂþ©rÄ ³à†uÙÑKö¦… [°ìWgM+ãvif ü>¼: `%í¹Þ¨
+çù£/°­ë]Fu,L0#Ì_{Å‹¼AxM™qE¡µš ›,/7*XvZ€‘H5`ÏWºXv‡ ù‰ÒÑê° e<–‘'ûià1È8Y»[⻵Á3
+’÷~-Ú릃n¹©ýÒDHM…'¿jžüî‚’¯‘²iq4°úø M/ÀmJû.
+GÞàgÓöµºcZ­ ›3j5ÔˆLO¿Ñ–/LŠ¤¬)’#¸HŽïqN?ÂÁñCAÛZìðt›ç&¨K[&XšÕjì³TzçœÏ=˜~Nk•I6%…úôÄÏEü€ˆÃû&-‰âaòÃÐùùîÎ!ót3$Á ”a&9>ãìø]Ê•Ã0á"ø•ô’J]
+¦Ã†3ÐxåôÌ…¢ 4¹yˆ)¼~€ṁÕ¬F­}÷ñ+nŽ¨£—Á–Ñr–MYK(ŽŽãØC˜d[ÿÙnÛ “زˆ…™Á¯òXƒ‚U|joC˜¤ü¬]f|-
+XB@~n‹5Ú ‚i<œ“õÞDš>þáæxö%³šÒˆ ‡_÷Mdññsz¸ ÉÆ2­‘ë
+ˆdÞH9&OF^ãzÂÙÌQ¸”SÂxfþ{ŠX +ð#ãLNe1ÿÏß2?ôV†óeKàj•°&(å‚£™j^ʪ(+a2ªÿ‡endstream
endobj
-1325 0 obj <<
+1715 0 obj <<
/Type /Page
-/Contents 1326 0 R
-/Resources 1324 0 R
+/Contents 1716 0 R
+/Resources 1714 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1322 0 R
-/Annots [ 1328 0 R 1329 0 R ]
+/Parent 1712 0 R
+/Annots [ 1718 0 R 1719 0 R ]
>> endobj
-1328 0 obj <<
+1718 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [184.7318 214.5925 233.4785 225.3769]
+/Rect [213.0783 507.6843 261.825 518.4687]
/Subtype /Link
/A << /S /GoTo /D (dynamic_update_security) >>
>> endobj
-1329 0 obj <<
+1719 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [369.8158 92.1907 418.5625 104.2503]
+/Rect [398.1622 385.1227 446.9089 397.1824]
/Subtype /Link
/A << /S /GoTo /D (dynamic_update_security) >>
>> endobj
-1327 0 obj <<
-/D [1325 0 R /XYZ 56.6929 794.5015 null]
+1717 0 obj <<
+/D [1715 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1324 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F63 1065 0 R /F62 1062 0 R /F21 714 0 R /F48 953 0 R >>
-/XObject << /Im2 1051 0 R >>
+482 0 obj <<
+/D [1715 0 R /XYZ 85.0394 131.4374 null]
+>> endobj
+1720 0 obj <<
+/D [1715 0 R /XYZ 85.0394 107.8521 null]
+>> endobj
+1714 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F48 1228 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1333 0 obj <<
-/Length 2684
+1724 0 obj <<
+/Length 2819
/Filter /FlateDecode
>>
stream
-xÚ­]sÛ6òÝ¿B÷&ÏDñAHžÜœºsIS×{hú@I´¥‰D:"m×wsÿ½»ØER”ã›fô@p±Xì.ö”œ$ð“—ŠD{3±Þˆ4‘éd±=I&·0÷þD2Î,"ͺX?\Ÿ¼¾Ðvâ…ÏT6¹¾éÐr"qNN®—¿Oßýxöéúüêt¦Òdš‰ÓYš%Ó.?þ“ žï~þxqùþ·«³Sk¦×—?$ðÕùÅùÕùÇwç§3éR ëS8²àâò_ç4zuöáÃÙÕé×?œ_·²t啉FA¾žüþG2Y‚Ø?$B{—Ná%Ò{5Ùž˜T‹Ôh!›“_O~i vfÃÒ1ý¥Ú‰Ô);¢@¥:
-” ŒM6±©™V:(ð³R¦\Ï盳Ùt“Ï‹MPzo*|Úé|]滧.¨J;?ý±z,Š*êL;=­×å‚©Í«fE£³Œžy¹<FÆ@Kº)hVEIøËâŽ&yS,_¡æAü™”§©
-²4«uMÇSÝ5몤ñcÎÀ|SW4êÓBAd2½lh2Ò(«GÜ–¡/™â:H£ºÚq—]¹.oée[Ôu~[€Š†ö‘ˆ$Óµ26MŽø#ͺXtœrÌ"ª ßlªÇY³ËËú9Ø^/”rÏo‘F¶ïYSj„J¼îïÿë]±XNU€J§«õbEÃUU7
-VÏágÔ-¾ ½á“ϧX?0Öª’GQ:¦uP«-O®«.vl–áÊÓi*2ô”¤£¶`S3í½p™qÛê¨t  mÄ$Ϥ¶9µöÑÜ`4/èY·ÊY`]Ò™>äQ*-¤ÑŠ îHÞJÉHu½-Ê}ÑÈv>.òù1`Ø A*PÔn½Ä#{†ë„J]ÔyXEí¨/®­´Q}òêó‰5C¢WÞDod÷ì(ñA‘“[ßä÷›7UôþMtèŽ 0h õ¨ïf>½ÔÙó¾ÛÅ:î»-Š>ßä‹/«jS¸­B‹üÆÎidçžÛj#œQƒ­{n«•šæôجë†FÕ O,—äšuq›UÞÄQAv¾0~\£^qÎ0Y,Š;½/vëHjïËaO¦p_²:œ˜ƒjóPDvƒí)Íg¦ï¹¸ÁÓ©”rÊ&õKÜÏz¿#›RÍÆ4”â~´ÖçŒÍ¨wU¹ŒY¢©x¿ëcö|MÇÀŒM,;CyÜ屺 ¤±ð™Šg3 gÂkKÉ ™‰ê$ß*›bw“/ŠzdÈ­
-<SgäÀ$„LjÒ.‚wÅ &îª]SÓ,g›¸,ZŽYaqý¡­!àKçX
-mô±Nùé–ÿ„ÿ|#Ñ.|®—PI"ß,çîÍ›×Z½ßá%í„NҶР7¤vA­4˜%ÀøÚ XŸ"$X€ °/ÁÜЗ`#-}d Ä+2Ò‹k4ì'ºÀéÆ„¸Q(ñý>«Oz,!ÄŽ¼!Eœ\3$dÑ
-dæ §3ñÖÓtn=ìt¤K
-ª/!´¦Fã¹’ÏŒÐÖ?+âYâ¤{ÉM+G_“éCãg¥u/b?ޱƯv­„0Ž€
-ù§HÔå¼ýÿÂ!ëd¤$endstream
+xÚµ]sÛ¸ñÝ¿B}:¹!ø$€äÉ—8©o_Îu§Ó¹»Z¢-Ž%R'Jöe:ýïÝÅIÑŽÓkG‹Åb±ß¢˜pø‰‰ÉX楟X¯™áÂLæë>¹ƒ¹'"âÌÒ¬‹õýõÉëÊN<ó™Ì&×·ZŽqçÄäzñó4c’>}÷ã凋¿:;µzz}ñãåéL>ýpñ×s}¼:ûôéìêt&œÓw9û|}~ESY¤ñýÅå{‚xz<AôêüÃùÕùå»óÓ_¯89¿nÏÒ=¯à
+òÛÉÏ¿òÉŽýà gÊ;3y„΄÷r²>ÑF1£•JÕÉßN~j vfÃÒQù ΤÊäˆ
+NšSTùÍ
+`Õt·,XåëjŠíC±%(ò…0â !F䶎(-…‹Ï4“/$⦉KH¯ðÍOójñm:3Âê[‚äÕ4i1í>"Öu>_–U¼ä²¢gUìh
+£p]™<-»øü “xvÅö6Ÿ v–f-zÀŽ†_/ÇlRxÆ3}tØÙC6r^4x¡r½Ù•)…¯ütß ‚ìj‚iÜ~‰À Ý嘰H¥Z € 
+”>…é.¿àîsJ‡cA´s a?O¯%$ZQ°®ÂJBÅ£s„DjÑI°0‘ =QƳ,!-C…„!íž7Å2@_–¹>?±¡\@y3v°CØ¿MjϨ[>ÃÔP’ÑÂH„Ô! ü»r¾_
+’æo¾ s¡ xý“ÿe ñ¤×´¢E&¯™ ·Ø*R|ÿ¶Â[¦´r}MëñÓÍü;Ñþù¢]ø\!9o7îÍ›×J¾ßá%•„⦭$u
+%t+eMHjUÛðˆÈ,.©)·@hŒ:-͘”u‘­yJ³¦ÞoçÅÈg-z?ijU/%‹E”ÊLßq†â â¥õ8FqÍ>¤y0Û ð™±”J BÛUØ¡«€Ø5‰`1qV_RƒqÊÄIZ|H5¤{Ê®lƽ_j‡t½£+5U­w긡0´%Ë´'tL JmLÄøókŒk“8ÚƒnËæ>;¨Uð ^.ƒø¾.w;òÒ$.œì§ˆšœÙ°!
+?®(ÊÛÔF *UuP ¨v*ª:šÜ‚M×kBØ„"tG/Õ~}SD
+·A7Z\¾”ÿè=îö‡
+€î]ÑßSB‚· Ø~iUE  ›Øà•4`bKÕ§F‰·©¾yR‡»ÕF…./ñe‰¯ÐÙˆ¶Ó2hS ~¥ˆ(UB)F“Ô˒U
+–@„Túàö&I¹;mgSzÈê¬Y…-i›uQb&¬bÏŽÙÓŠiücøÿËÝ0‹‚¡“ö¨
+‹;F8ñM^ T´?F”E2)Ú
+%zž—Ó¤Þ&¤U¯”ñpY×£>Y¨(¨ÜÚ?b òóe1¿ÇaFÝjgR¿Õôºç0߶|aŠBZ]™7T‹‡rÜ›2! U©óQßmó5ýs†sXé@8 $Ôð$Ùm±å[<¤Éev`fý]Ü$z†¸œ+.£7òÓ0(6Ëby2Ô\ ·¾»ÐTÙ
+¿‡ù‚·Zý‡?»8|“‚>Ñ99þE…´Rg ™
+…ž;â<}ŸqÌú
endobj
-1332 0 obj <<
+1723 0 obj <<
/Type /Page
-/Contents 1333 0 R
-/Resources 1331 0 R
+/Contents 1724 0 R
+/Resources 1722 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1322 0 R
+/Parent 1712 0 R
>> endobj
-1334 0 obj <<
-/D [1332 0 R /XYZ 85.0394 794.5015 null]
+1725 0 obj <<
+/D [1723 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-370 0 obj <<
-/D [1332 0 R /XYZ 85.0394 625.1831 null]
+486 0 obj <<
+/D [1723 0 R /XYZ 56.6929 291.4983 null]
>> endobj
-1335 0 obj <<
-/D [1332 0 R /XYZ 85.0394 599.8772 null]
+1726 0 obj <<
+/D [1723 0 R /XYZ 56.6929 263.1273 null]
>> endobj
-1331 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F48 953 0 R /F41 939 0 R >>
+1722 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1338 0 obj <<
-/Length 2990
+1729 0 obj <<
+/Length 2567
/Filter /FlateDecode
>>
stream
-xÚµZßsã¶~÷_¡·È‹ß${ONâKiœÄufÚIò@IÍ9‰TDÊεÓÿ½»ØEÊ”ÎwiǤ `±Øýöh9ð''Ö%.Wù$ÍMb…´“ÅæBL í› É:³¨4ëk}yñçw:äIܯzce‰È29¹_þ<u‰J.a1ýêûÛw7ßütwu™šéýÍ÷·—3eÅôÝÍß®éí›»«ï¾»º»œÉÌÊéW½úáþúŽšñåÍí×$Ééqbлëw×w×·_]_þzÿíÅõ}·–þz¥Ð¸ß.~þUL–°ìo/D¢óÌNžá‡Hdž«ÉæÂXX£u”¬/þ~ñc7`¯5tõŸ‰ÒN8PÉ1Ú<qZéÎÀ-Bˆé{¿û@‹¼Z.w¾ip‰0ê $&3•'&•4ÄÍêr¦¡Cûèé¥ñ»'¿Ãw9]Ö¾©¾h©á}U?éUóLº ¬©OA?Ûû¦-ëê üLí´äAžËõºS@c±K ò(U±ØÑ$¼„¾/4xJ+›ÃZp a¤YSïw ?²àY§>“2É­U¡W³õ‹ò!”o`BçxUÎN ðݥ̦è¿ÐRTKzÙÖ»–tögÙªÞÑK³_<R#Tz0}æl:}XÌÚ¾â¡jr7Èn~xrè¯ÜNƒGÐÒ)£%±ó¶Ø­ñˆ«”/|3{r#îImâÒ4c_Ö[Ü´„¶
-wÖõ†¶—€B˜Ûø£ÚoæžGX…ðˆjÜsK13[ÔÈÞ~/I Æ}ðÃù·åâ=5gÓý–ǪXÀ.ÑÜóVdI®­î!N°‰–—N}ˆƒ"S ‹ƒÔ…²3½d¶¼¬”ìÂøn8}:S€›¢%Éy¶²Š*cp£
-øY(cMÑJ(&S´RŒŠ ÆΧþ÷Åz¿,«j¤º}‚ƒ܈èƨ=âF …<‹–Ou¹ü˜s©ÕùqÜYàáòt8lç.HªÐå(ÌÎù ’L‚¤_*Ð) £°ì¶|òëŒ4÷ÀE(ô\úU±_· ýªWô÷à\j¥|]áw€+";ë ™'Ú¦fd¼“ÅÒvØÉ {©¼ø¿P'ÓŸdÈœ
-¦R¹†Ý2 »Ôß$nW¯!"ë¨]–¥ùH/›äiêúÞÒîÈT'ÇQp쉗æd­ÿ_뎩œÌ¡ f*R…3•î\å±2“Ÿ„K¤½
-2-*Q2͇Øóú1ØfÀ«:¼Ã8×ÇT¤ÄË1†¥“L»ß\E`øÅ£_¼ÇW7-W$
-…/õÖo Ð…íÍ Tj¢¢V38€“›‡ÅS¹
-x¸*0²Qð¤$iw%4û§ØøÈ/ÁhÙ|Á“04p_€WìF¿©áÅoýÉò´X“$ìF8:Þ€LÎÑð*’—~™@“Ù^§Å°Upl)žŠr]Ì×~l›rÈÐÔÙoSª23Ü&˜‡æ ÍÉ¢ÞE­+ª/ØÞm¨tÁ†PoÞâî¥t„z.pœ‰pÞB‘ùJ
-UX?¤£æè\T?WC\ƒ´#ê÷"½^ü›̇ðUB¹¥7g­¶oéý?o‡;¢ÆÓë3Æ|yôíÃÆmÝ^mpÓMñãJ¤(ݹKdš";ÔvxŸ³¬Ù¯PóxQÂqnýäkª<"E*êûÅ~W¶ž–™é5AZaJì0ÔX¹ü—m[_-yçS±+ë= ·Ål̃“¢:Th#§ó=Æð—g V€k4Å´îE½Ùø@MA£ä@tÛ"Aø˜"4®=ÇH$Î ½ò^¡*ÉâyIÒœ
-<´‚Ã;¶há‘S¸°'<ͺ©é-Ó‘œ¥Ä‘Æ4
-c0»\ûEÂhùqô‘*í rw Ǫ„AôPµfZùgV‰fÐ\ÓbßÖ¨ ŽPsßb»]—«}5z\
-¼®é².œ¥‹ŠÞ„
-"ã FÆG<‚Ú¡¨•=ıVÀü*<ÜVX>µ›˜Röø\oB‘£K¤«-ý2^
+xÚµY_sÛF÷§ÐÛÑ3§íþ'Ù<¥‰“s§ur®2s3m(‘²9•HE$íúnî»°
+•¦z²>³Îgé)«³_Îþ¹8˜ KÇüçL"\¢ãj=æ@—
+o´ ,«¶Ø.³Eû‚½– ~]”Ýeå*›¯Š¿ãAJp±· %Tٺșk¨Îë¤çº/W+RÑ5éhoYé¢ÞnÏUͦ®ò²º¡ùæ¡i‹5±äÅ2ëV-Ml³ê¦xã$Žj²½/0~˨dž}eÛ ™“©Ò©0Ò&0R"uN ëûŠÎ–u5ßÓ¦ìpër2ÕZèD§a ÈžÞÙi—o¦›z ò§^Êè?ô fÒPImiä3î ÿû&Ø#í2ýëdh0Vh“Wu[|>µÚGëìfd5þJèhpô54ž3­é–Èú›”zQU»z ú* "nXâ²Þ2±è¶eûp®”Š Álb£·4•My®@ D3—ÿ.ú¹MQ嬻®è{—m˺câ&›Ž9p  AÝ`DXÍ; “F÷ ¬Šm¶B³‘Lû^Ôë5¨#Ž’W,êªÍÊŠ~d-M®Š¬áyåMbiÈG… ¿IÈA&ÏK¢¦Q½¤YpXÐXo€Q ÜŠgÂjVMM£öTì0òFyN¿¡R¦8N~[TD„ÈÊi´Îhr΢ں&B³ÎBâ
+ïcÇ 0,Fœ …ôÎ…úõ¼ øü¼( l` o‡BF v˜ãl¿KÀ@e„Ñq|˜Ncp†e`
+kRÓ‚,\W`¸*AÐW4Â& ”].yÏÝâ–û¯„(?p 4Úí#ÙhèüªÅªË - WªˆÊIÍئX”?ÄaC• &s¨·‹¶È± ÑlS´4…ÇŠ„¯]±} R°
+Ôø„7kèÐÈpQì/ðȼ
+¡ôšš««P¦½&J° Ç:ðvèÍ Hòê3Üä+À27Ö´âKz¸>…‘гÅxëÝ°LºÎæDÞíàQžÚ4Ìš SáuÙ…iìRŸN¦û?•¼:õš<îý[ÈŠ½ð1ÄÞËwÚ¯8…#)^C ðŸ†åbaµÖßF”‚~<Iô·‡‘¡ä'`Di‡ºƒþR‡ÖTQïoA(EÃðn‡ƒ‚y ‹¶DÉë‚ùCÓŽº¹ôy(EËï1?[*u±¤¡/ü±ƒ
+üI7òZÑÔ Ìø?ð¿¢å,=•!ƒC~]Øü_Äá;YbÇê¿Üã«ÿ
+ºy 3ŒŽÃç8éE¢Óš-²Ð×>=öìîÏ¥Ì50ý9”©
+endstream
endobj
-1337 0 obj <<
+1728 0 obj <<
/Type /Page
-/Contents 1338 0 R
-/Resources 1336 0 R
+/Contents 1729 0 R
+/Resources 1727 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1322 0 R
->> endobj
-1339 0 obj <<
-/D [1337 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-374 0 obj <<
-/D [1337 0 R /XYZ 56.6929 769.5949 null]
+/Parent 1712 0 R
>> endobj
-1340 0 obj <<
-/D [1337 0 R /XYZ 56.6929 748.5275 null]
+1730 0 obj <<
+/D [1728 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1336 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+1727 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R /F62 1352 0 R /F63 1355 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1343 0 obj <<
-/Length 2667
+1733 0 obj <<
+/Length 3302
/Filter /FlateDecode
>>
stream
-xÚÝZÝsÛ¸÷_¡·£f">Iâ1—8©ozvêè¦ÓÞÝ-Q'©ˆ”}¾¿¾»X€"eJN›tzÓÉL¸
-7òùâ—ßød Ûþñ‚3eS3y„gÂZ9Ù\h£˜ÑJ…™òâãÅß:½·né˜ÿ:°Œ)nÄ©’Ykô¸Z§¢X¬•=-‹ÖqåÉ°b(êp¼1PÆÈÃñJ9‚Y˜Ãóµœ%Ž51Î<¦ó½F;NËL¬2
-ÎŒ’`¹ã¸™ÎbÍá]ŸÈÔLK@Oª¤óÌäóD0®­UÄÔ£Ý^>pß_määm ;šô6Ïú’ݦbÙì ã‰6í,ž¯óéLKeËå.o¨¨Ùæ‹âWÎe¾¤·EEÏØbÕ—¬4‹ÁíÞ Ÿ÷ùPÌ£§YSïwSÉ£EXÖ7(N˜T:ø®Þ¶EíÕÞŽ} XMê îêvMÔÏo?gV-QÀŽƒ
-³|î*èùRš@³¥ã°ÖÃã*m!ªÏÑV¬^ªÏ€®Œ_q:<ú'üu ùöá1Ä¡äú
-È™mÖæ4õ‡3Å1uV¸!eZ eQ›¢õok¯„R(²oê}åë•_PgKÒÒ®³v,wöt¢7¼ÉH¢|RDóÔ´ù
-ô[¾$Ž°~ ï;¯éúãX0é‹Ú=—
-L®‰ÏwEVÎð7¹§Ù¿°£*æLÚØœÕß1=7`€©Ø0™@CÕ·àc™= ¿”<|˜€—!™Àôl¬—ÅÂ]ËÝ;g.½ÜdMëR•ýõ’î·ðtŽ–ÄP»ß8a²XÑ„OŠ¤»È¼Âj¿¹ó_6'3c˜R‡&‹Pµ&›SáwÌ{‡/-ãè/ûn¾Ù* 価Ÿ<­û¤
- Ø‰Ä‹?Kã-XŠðçÀc{"›#™W$Ý«{\ãuqᢇèÇ`d ߆pÐÐUV†»rS€økeþùÅHy÷³ËWÿ%Hï«zÂTšÊq¸+³TÚ$…î7êØr£RWõdÄôfŽ¢õendstream
+xÚÝZQoã6~ϯð[e fIJ”ÈÇm7ÛKqÍövs(îÚ>(¶ kK^ËÞ4ýõ7ÃÒ’-{³×îpRä3œùf8$­&þÔÄä"wÚM
+— #•™Ì×Wrò}ß_)¦™¢YŸêÛ»«oÞ¤ÅÄ —ë|r÷ЛË
+i­šÜ-~Ir¡ÅfÉwooßÜ|ÿ÷w¯¦E–Üݼ½Î´‘É››¿^Síûw¯~üñÕ»éLY£’ïþòꧻëwÔ•óßÞܾ¦GÅ™Iß]¿¹~w}ûÝõô·»®®ïâZúëU2Å…|¼úå79YÀ²¸’"uÖLžàC
+圞¬¯2“
+“¥ihY]½¿ú[œ°×뇎é/Ò€l"•F½ˆ­ÒÂ9“³•` %ò\eçç¢qæâj1œê`Þܤëj=QJ8c4š7×"-T>)Œ“çdÞ[T°§tÂä™BB%a ‚{Š·ÓY®’;ø¯“sÀœ²ÐH¦„M5rž|œ(!3çR¢éÕýJð ßܬõäu ë™ô–æõ&öKÊu°€S BîP±yîå}_U€¡Â&åªkiuyÚ”)XàžV·Û–M÷0U2©¶S-“Y×î}e^ñØ>ÃÌŸ[6‹‘ù•© Ó7í®~x¾<)¬ÕI°Ç*Îr'´uvÒ³îŸÃ "Ó¸
+ ©!‚`Q$«ö¾\QÓªîvTó†„Þ›Ÿ˜x±ØN•Mª®£ñ“ؤ)×Õºjû‰P¤Ùð4–FòÆ-OÐU ܾ½»yóª¯CùXy‡
+OIR|• W£En\1ÔGX2¸ L¹ÅªEƒ5ÔÈlÀòÕC¹_Òj„ä 4.]ró@0ìT*·Bk“¿T…–ŠiÉçqæº#–õ§Še«j*GxÂþ {ØÙ½WòÒ™&¨ÃÝg ~ÿ5M[3gÂ"¶´€ªm½¨HŸ©2È#º *lD…ÐJ†Ô$ni¦zê€-pL#’£N¤Ä´Þêäç%ª#Í䨬Y!]_ žéyõç yÂŒFá&ÍRÓî •];Æ6ƒm(‰ØPÔÞ1ºå)G˜ÔöLvÒzKÒ:¢ØÇ5f€
+o§¢IR¦_†ELÛõ‹89G'¨ÁPªÜ{¾:ìÐ÷ ¨ü¿Úm¶db´ 4s–rl‹‡uwX ×/8OBú;ÐCµÞì8·`×Ú¯`ц3°¡b×m^ÒVF½:›~
+IûP˜¤R •J9ˆTR"•T© ‰T0ÐG*°Ec}¤’„­)bˆ{8RI‚—Å*a€å¢€ø5Lòÿ­´ƒ¤[js`}ªó
+ð~U~B¥úp%¡ÓN y"¶‹zîä¾ÏKKë²Ûù`•ªþxM'[(ý•Ñ‚Ðo|cý@ ‰w]2Ãf¿¾ç+MP®O€-{€«%Él]‚˜a°§'×xÌ÷íÝ>Ô‚°PÝû»'¬•T鹉¯!µ¥Û+l££5N·Ši•ÓY‘%_ñlMµ{j·èã¾lOõb·½Û¸›: j`«÷·¢Xå l‹R@ÝK©A˜‘haxפµ
+F@ãzSvGszXÑìÌîi‰çÄ9OˆòW>ž$Ü
+áGG‡XÎ<HM.6r åÅ•úÌñ2.ãÂ9mõGp-à<ž›ÁqW­Tâ·D`T7»
+wJ°÷xŸ—|ˆ$‡à ®ˆ"{X»T|2ÄæM ëªyÛ,¼2¯:ÙÉTXcŽ¶ÓÑ°¦åù ¢@'ºø̮էºTÕ‘zk:”"Š²"ÿ w¦a>ˆ(:y†¥ÏýÍ£]
+²‡» Ã]ÿ 3gªâÈsãSÑa¹ø
+C!>">°¹ Y =‡,èsßÅ·¤sŒVPÉ—ÅÀ"+ì‘B΄K“²P—ÃIŸê|8‰Tý§6Ÿí=´ÛuyšþjÓô²‘jDŠa¦"E^dùP zúTÎô^üœã†€•{î'[aâ=µTYà5®MxA‘”Ö}=¶w¥…°. »È1ž`‚‘ É ŒlÔñ#ø‘_+]¸àÄœ›çu
+[Mt
+J*ü=‡ÊŽîµïÆaç ^FÎØòwJ˜ÜžÄXcy[+|B-¡‡}ÈRBSÄdÉ´T.*0m˜œœÓS³<ĈK|N¡g¢£u¥
+b{6aÕH‹P7C?k/HŠµŠ·é”!¦~YþùªH^ß¾§¾!¦VŸ `+‡Á–^Óü³yl /r4$¨žúckÒà öBd8‘©ø€²)çXvÿ¾ýiŽ®äñ'#x§>PÊ©ìZǯ‰ÔXr¹i»®¾_1)d`-÷SÁ:£8ÔÂZõRÔ[!U^Ejæ¾nÙi‘TÞýõxÍoB:Mîý!CqPÛøs ÔºýßÒªï¹5ô¢ûg:`§U¹ƒíØ?nJLôŸ¨“ϾJ§|ÑŸ;°ÝA†4[œ§‰[9ôYñ;Óý£ìõe CmóTÞv38dŒ»zêÄŠÌöUÌö§7æcêO!îÚ­è—˜twTÒ;¼–iO«¾õ‡%Ã(¦Ô?Ösº„èÚnúyj `hÑ>u4þ ¾ Ç”ÛÓ’kbdõ`Î"wÙ`õ…E|
+³¦p_S3§T”Žß€îïVèárQ5Ã_±”üûžþPahÙ…SÆýó “ ñ.5ñ¹‘§Q*ǯދæ™_¦FàO
+WPÈÓ´I
+Іý_ãe˜$endstream
endobj
-1342 0 obj <<
+1732 0 obj <<
/Type /Page
-/Contents 1343 0 R
-/Resources 1341 0 R
+/Contents 1733 0 R
+/Resources 1731 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1322 0 R
+/Parent 1712 0 R
>> endobj
-1344 0 obj <<
-/D [1342 0 R /XYZ 85.0394 794.5015 null]
+1734 0 obj <<
+/D [1732 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-378 0 obj <<
-/D [1342 0 R /XYZ 85.0394 460.4475 null]
+490 0 obj <<
+/D [1732 0 R /XYZ 56.6929 672.8271 null]
>> endobj
-1073 0 obj <<
-/D [1342 0 R /XYZ 85.0394 437.5053 null]
+1362 0 obj <<
+/D [1732 0 R /XYZ 56.6929 648.9121 null]
>> endobj
-1341 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F62 1062 0 R /F63 1065 0 R /F21 714 0 R >>
-/XObject << /Im2 1051 0 R >>
+1731 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F62 1352 0 R /F63 1355 0 R /F21 930 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1347 0 obj <<
-/Length 3382
+1737 0 obj <<
+/Length 3226
/Filter /FlateDecode
>>
stream
-xÚ­]oã6ò=¿Âoç
-d›ÿQn[êT‡í€ˆˆ,¢P¼¬)ª–†w®)–uµ¦*l£›ÍÀ‘Y ‚&¥ðÖª€äªXç‡MKŒ ¨ÀS%ℵR8)Ó™“VèL¹3¬  EŠ8!§D9BÈ‹w/e&ÒNg˜‰Ãû,’J‹ÔH=<ý#²Gù¨*›gÈ­ÏHFjE¢ev*ŒûèÐÔeŒØ-G쇑#ûa´c?LöÃ0wyØï¯e6'Þ‡mƒnÍ‚Yî¤@,ûiÅHk?Ï7›ú©XÑL[Óó® g}h›6¯VeuÏÐ-MäÕ35îËÇ¢¢¹¶ÜhPœej⼧Ǫ¦ó
-x!½íj¨»D‡€;ž'^a‹™=ÕÔX•k¼ _¨¥‹5o¦|—v"ó&z/Àc<Á§,³à7¥ ¨1Sz!²4ÁlAóy¿I¥°àj:¥$ÆÜ© ùvZì<ØË¡3¼Ëø÷4;±±6c·æ€°$÷`Ðx†u(ƒû€ªî „ü‘Úd ñ¹*`z[V NÊ :ˆŸÀËU#&î¥%2%ëñ„I“d(êv¨ágù¥!îÃøŠ¶k¡Q ×B
-H½ÿô#l‹¦Éïy48Êf°>„Ʋè.ÉH®hI$=Í­¦î¤@ÿ
-|ç…Ç’áˆ0+‡¹LüÁÀèY±qœ3 Kƒuõ”37ÀšÌŸQuí=Ø
-“õIÌü§?¥Sä×£N´:½Ä »¡g¾iõ‰îQ5L ýðÉbÔ…Ôß—Ë0T7õš‡þ{m-ÈЪ~jh«*"zöBî
-ÔA ‰Þi-Àç!›¾x|5qþPN¼pκ!AƒŒìeã؉dT˜†c€ «öH…°ÕS!'‰ BظcȾ
-!è"ÍÉ„t©rž’ŒÀÃhÕC¶€d­i›(ô,þXBÐÃü_ùO96ŸÊÍfhòiÏ5†Ò‚ým\7(%±sUéTƒµÕfw‘Õ«Tøœ§V/Haê‚F¨¡FOV¦T&ŒÑò2ÔÃ$R ™Ï¢°Lz¥!è+ƒ\’ÉÑœc‡d[=Y Ý
-ŒXqèŽ!Odo°~ÏF35SãàdM±âç)€W†°IÛnëPê€>FNÔb— µò|eß**F¨”Oe4ßjÊf ï\Úó
-:y•W
-‹±0Ñ\£Æ®¤ƒV¬@¬éèc¤å<_­¸âÁÈ%j¶™ød“ С²€åó£¡Öí»ÏÔ
-YRÂo݈®©œß¿šŸ|Ù‚µq¨„ÍᲡ7û}rd|ˆö’A;ÜõHƒ0ðÍÇ­š½¯áF³þ¥xãEçp©ôä«môLRY˜„òÇzƒVU†*ÄM~®„’šTž‡FÁ0›2ÄÀ0¯á¡E¯á¡Aqȇ@tx¤h[R=è±ÆQÒ): >{謯!Èa»:r-9Œ"–×*™ÿ†hè
-ß‘õ¹ü×GiSŸ€•?~Fô×Ä29`fn*`©^x- ê4¤ËãêêŒ![<¦'¡µÎðuZ:ëŸpZG¨ DBÉ‹önˆHWÞi([§ &räT@hþUf8E‰ïª¸oŽ¥©‘þ<)lM}å
-ñ¥3…C°®Âd° #…w°æTôùSÉSÔÿ%´)endstream
+xÚÅ]sÛ6òÝ¿Bo'ÍD ¾>¦©ÓsçšäR÷á®í%Q6§©Š”]÷×w ЄDÉɤ77™˜ `,û ñ ƒ|âtÆd®&6W™f\O–Û+6¹ƒ±ï®xÀ™G¤ùë›Û«×ï¤äYn„™Ü®k¹Œ9Ç'·«Ÿ§oÿùæãíõ§Ù\h65Ùl® ›~sóþ[êÉéóöÃûw7ßýôéÍ̪éí͇÷ÔýéúÝõ§ë÷o¯gsî4‡ù"¬pf»›]ôݧ7?üðæÓì×Ûﯮoû³ Ï˙ăü~õó¯l²‚cÅ2™;=y„Ëxž‹ÉöJi™i%eìÙ\ýxõï~ÁÁ¨Ÿ:Æ?¥]¦…2“¹T™3°Æ(—YÆ4pmnuž)dÏeÁǸ±Ëݾ¨Ûu¹oçU}|d.mf·“áº'»÷X#Û‹Áö\‰L;™n{_ÎæR¨é¶ø£Ú¶Ô¨ÛE¹'¸YÓ·ªÍ¡^QãϦózúCó¾èZ5‹€¹Ÿ¹é¡®«ú. 4õò°ßϸ›–u·yšqΧ($Rx²€Àv´ÂÑ8Ïr­…§yU®‹Ã·azúPl%U‹s^¿SC¦[ž9©,°
+§rF()cÂÚ„(Ì›zI¤-RL³† k9&M˜u|G[
+¤dÆs—·ï±FöOÈe\@WB€× Åóg ÂFÔ %˜¿4ìƒ
+a‹T¡
+!:©xB`0‡*„¨gTˆ4ˆµF¤7ÿ_¿©¿Ã°)µh‰ßeÛµQ è[þ±,ÛЇIï¿Ú‚¤yð±ÚIX”Ã5ׇ¶\e(žŒX…C½c#h°ßtLƒ%Øi–sñ%*|F
+a™`O.Jáë¼öX©îHgçu{"ŒÚdÖåæ2=Öɉ ϬeyJq˜³gaÄFFÁrºCΞÍ96HÈ¢ozYÄy^±k0Od/™¿Fs2×`€…ÊS9\ûy Ò—³iAŸ»ê¡¬ ¤e·MWR».¶jË=šE°Ðh¨EŽœ…*ªüŒP ¥2kxô bÌfg¹µfà$û,¯
+i¦Õš)î´ª¥ðùËêÆÍÓüX´Ý4d, Œû É wúȽhöëCmÒ'Ø  ;&bà@ ±"»ã #„:äÿ܆ŽÄc;ŒÔŒø¡*žâH(:ÀHôÌ>„(›ÃŠ¼3t£B¡2-¾”#<c¨c÷e‚厂ÛǪ»¯©ò)%ÊfV³ÈfâÓD…ÂFj›ýÈ:°«3:çù3º³y dà°~KS¼>Óƒ¢wwؤ
+W>ƒ›ü>IR¹øXûÓ>sÁw¼¾ÙŠÉ· œi2<V\y>\ÚŸË$É!œ&w (à9D>Œ"Ÿ› Vî+eEæS‘éŒèý eÀÙT>†žUS|ôvh»ª§é =eבöAƒì5ö’ZÑ`óÉÞCc=ƒ8'˜Ö#ïBaÅ@b9lúþA[Dˆ¡Ê-äNo/úëd2±ÌäLNæυᯓlÈæ2}Šs~!´Æè^@À®øåȺÇ:cÉææD,”Vîp\G¬BÃh•<¢¤¯ð´”°TŒùgm2.rþE–|´s}%÷Õsyj
+Iž·B݊º0ÞüÚ¶ 5ÍÑ!ª9›IÈ£Œ/¤EC¬ —±(6é染áñA>.Ò‘FèHï<·ë“òý±µHP¹¯ bY3(âà0¸Ç62ø%tòÑг© ¦]¬z,Uæ gƺ/uÇFÆ)ë¢Ú´èz5æg!ÊU4Ú(Ì‘ÛÁwç*s¹ÔãņÃ$i{¿[1xÖM
+¸{kùßã&VÔX:?ìÎ9/) TäÂò—¼¤
+sL%HÝ
+H#¤$Òç0$³2¥å—6tLؼ`A+©:YN¶Ée!Õ¶¬wL;&¡$ï³àól8¢Þ) ÉEêœ<áãÎ l¥evàœH/Xe'¬:~³=&“ÖõuåKÎ)†-\ŠÌ‚¼Ú .ÈP@:5@—ƒ¼wƒ÷~’é””D†r5åLBËOþUÛEûàòD˜œ
+“ËÂÔÒpÀ¤ùg'M@Áä½ Köa&ô
+94ÚQǹa)û›±?è‹e¤2P7cOŸ
+„5JQçÛƒoŠï©]òÞDatGÎdfEË OåØ“DlòGœ_˜f¡ä:üa‹Å„í®èªEµ©º'@ågÅÏå™\^¿Òyñ‹HĬ®Z?8J‚űK{÷H—7çÌ·‚ ôâîÇɌ̤6|ä}k~¡È‹¿äï Ø›ÄÞ0””Óýï?(‰ÔaÛ¾nŽsBÝ‘©|Œ£‹ðc/ZæcÏ Ò“Åo[R±ÀN߸½y÷êÝů#c±Òb/bR±‡b±×8*öš˜Jà6áÁÒôïs«¦ãõ^“ãO3ž_ÿÀÄ>ºIü=—G3ª§¥MZÝ]nŠƒ”“Šª‘R™Xs@†2Ü$eg…±æRµ‰öò?’ã‘y°Ý è뛾è‹Ðxe‘+ˆ™ó¾^ùb¶Ò 뽸¶¯÷"Ð?k*»’~ÙuæÇyRgø‹ºmb}BñÕ?Ü{þU#Äí&‰qG
endobj
-1346 0 obj <<
+1736 0 obj <<
/Type /Page
-/Contents 1347 0 R
-/Resources 1345 0 R
+/Contents 1737 0 R
+/Resources 1735 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1322 0 R
+/Parent 1712 0 R
>> endobj
-1348 0 obj <<
-/D [1346 0 R /XYZ 56.6929 794.5015 null]
+1738 0 obj <<
+/D [1736 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1345 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F41 939 0 R /F62 1062 0 R >>
-/XObject << /Im2 1051 0 R >>
+1735 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F62 1352 0 R /F63 1355 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1351 0 obj <<
-/Length 3017
+1741 0 obj <<
+/Length 3298
/Filter /FlateDecode
>>
stream
-xÚÅZÝ“›Fß¿BoÇV2ßÀùÉqÖ¾M9kßzýp•ä ´¢Œ@håêþ÷ëžžA !¯SÎÕ%U¦™izzzúã×£å3ÿóY¢#&S5‹SiÆõl±¾b³G˜{{ÅOè™Â!×÷Wß½‘ñ,R#Ììa9•D,Iøì!ÿ9xýWnî¯C¡Y`¢ëP|{÷¤ôxýþîÍíÛO÷¯®c<ܾ¿£áû›77÷7w¯o®Cžhß 'áÂonßÝõöþÕO?½º¿þõáÇ«›‡~/Ãýr&q#¿]ýü+›å°í¯X$ÓDÏöðÂ"ž¦b¶¾RZFZIéGª«Wÿìfí§SöS"‰Œ4ñ 4‹$Óük–•‰µb2½,ƒS‘‘Q2½,‹¾c Ë‘þ‹±¨38Cef¡ëh-ŽÇ+ÄŒó(…1<_Îud„Šg±Öpè†øMlYÓHÅ-'‹´
-Ä#ÇûëÐðàþÁÍé P)t2‹a¥D
-k›Ùo31•¦’¸´ÝíÑ
-và»Ûµ˜ýÐÀžfÃmyÉáP´Ý—·å¶˜0Ð@2`SVçÛåu( ׂÍŽ^òŸ<¨›Žöe»"ª[DdUWlу:ëÜX·½æ0S·ËkÉœF)m³Û.<GCϹ{ßµEþI3Ö ]5»*wtÑ‘éì†áÆÝ‘Á>@P*…ÝÖ.Ïíò 0ÄÕ‘
-¥±–ÓÙ›E £À'ñ1ºùDòî¹ìÁ÷žÆâ yÍ¢ŸÌY'öffÃEÎ4ñLªŒ¼/1‘‰c9Öå•õ`[øÚ«g߬Wƒ¢ ;˃ré¸VŽ½©Q•mWäD—µËaCƒ–D¼ÓÅÀe3œhŸ¨Hqå?[feÕ:ÅÁùÏ—Q*cæ# ÕâBARND¬Æá|á@¦ÔÀJcs&~W¶T!gœy:ùŸGU¹ìD@ ¹¾àEžë<)>v#8zƒGÿ%ez® mFŽ”‚¿©ÄŒÕùÔ¢ $>K$éÈ¥püèR0yt©–¦7‰-Âl¦m±À™§²Ø·N¤ýÆ l7Å¢ÄTdf»Ué„åÅ2ÛUû
-ò×¹‡„51zä u3qè@ ÷¾ÔÀþ¶P¡
-:ú²£ç`EͦW`Å"ÕNÐv>±V)©<Ï/L³¥µŒ»„‹f½Éºr^Vew
-ºè4‚ºçcŠÖ² ÷ƃåÚ2Õº¨;÷ZtnÍ4Ì
-àsj¼!¾Â !e&¾|ù=fÖ3€@YçÒà%;§Ã"shÌ€XZŽÑÜÜ¡±Nl[æyá
-Ÿ˜k¬K»m†éq¤*ÎR´o¶Î©RI#Ô­¿\û/.5±
-
-“<y®‰UPMRÛ¯þ…M¬’ZÈÿA {ü…V©$ŠS`G…?6UæZ6›dÓ@D:âDRY
-¦¶qüƒ) ”ºÜ” ùÛüæÿÜ”ÉTD\%_2Ž‰Ÿg¬©N Šˆ`²ú¯&±Œç
-‡lÚ@°'`è‘ïÊÏSÙN
-wù&Dx5;b€Ï&IûíOt†éK²§¦ÌŸ“ ®¬ ÷üZ™VKó§´ …L/4²X¼u¢ï—¥'
-—b´¬°l–lœ
-Bëÿ¥c†ŽŠõI¿w»ÎbÕ4-Å!¬fS,Œ–6Þa
-”Hã1šecEÙ˜(,(* ¸
-
-îš®€œ ¹pÁ|^´%i䤹ŒŠ¤ $²ªmˆ}î¦è˜
-ýçM]¹•íQL'“_éžK ÚÖ‰]€`&þxg¯zìQðKWJD‰ã<3æ°=Žhº}lIn_¶ñÅ™}Wç™õc²‰ž{Œ†#`Û¶xéŽwUÆr(kÐ+IDZAGÓ<•y‘ûRï@Á<[|Þ“„|â’ú$Áû¬¾iÚ¶œWnº-WôI'6}ƒÐ_üSh_(MGꚎ÷›AˆG&mW¬ÝßF¾Ý¦Vd]NñIgò°r w|êpoöèf-Ú4»Îêƒã÷Kí~ôà SÂé
-•"<†hw‘U=?eÕÎvDqø‚œ¸Ò`¿*œD× !&Rà©>¸ž Õj+c â¯î=œ¨ Pš¸îo|øÛ©_=ÊÄrX2q­¹[ÓÝŒUÖ`¯Ì½€9§~e‘<^÷qËXñD¨©‹a :棉þZ@;&|É»¦­Z|„«×N»Çò1›ºó«½”ëÿ”eß³þí›ÿbæøçD*Žd’ˆéFA2è½±À;¥pãZ_nNÎTÿ/`å÷endstream
+xÚ¥Z_sÛ6÷§ÐÛÉ3Šÿ.OiâäÜiœã>õú@I´Í‰Dª"eÕ½¹ï~»X€¤$ÊI&íL‚‹ÝÅb÷·»Å„Ãÿbb,³^úIæ53\˜Éb}Á'ðíý…ˆ4³D4Rýtwñã;•M<óVÚÉÝý€—cÜ91¹[þ>µL²KàÀ§o>ܼ»~ÿÛíëËLOï®?Ü\ΤáÓw׿\Ñèýíë_}}{9Έé›½þxwuKŸläñÓõÍ[šñô8ÃôöêÝÕíÕÍ›«Ë?î~¾¸ºëö2ܯà
+7òçÅïðɶýógÊ;3Ùà gÂ{9Y_h£˜ÑJ¥™Õŧ‹w _ÃÒQû Τ²rÄ€R è3Þ›If<³Jª`Ày[ÊÜ´~*¶Ûr¹,ªøžÙ4§×M±½n:û»®Ò‚íá—§²ØÓ’yÞ” }œ?Ó³¬«Ý²¬è5G»vb ÌÀdFg°'Ô«ªÛòþyÖÔ»í¢ˆäÃÍXŸç&R7mÞë¢j‰ÿ¾l˸ö±‘6S*cR0ŸÌ#Ÿ°½SaR3žy…ÁÎOgŽ$Á£|¬Ì’ÒóU½øL”…'*‹ºúçòa·ÍÛ²Ž_qfU°c§ëÎU†qñN§\ˆ!7ît< 9¥Ïò¢uxÅaZqÈj–”›Yå™äN}³3=8'Gæ€ —Ìnƒ…n64V‹`hÎŒ’ÉÐ.gVLïà_9=‰Fg™‡˜Xã˜6ìfòçD0®½WD4‡½ö6?^¯åäm ;š 7φœÃ¦ìð¸…ThZMlÆ™v 4ªü©^å;ÂL1J”õSÉ 4Ì«% ŠH³*!¾Â̲."=Ä šÝfƒq¨ÁsâLѶ!Ìð%xS˜¥(" Ëå¶h"§ûKÅ£?ã©CáîÍG
+¦¦^\J>ýŒÿms J¸ ¶p¸Î»Éð”¿Ïqx„õ€¡³ú¾Ï­gÒC|dh µTî š²L g+4SΊÞaÅH6ê¨N@ködÍ$g@bÈúDD4¢Às)ˆveÔ¡¿”ŸÇàN¦¾[Á¶R%ê|æ»–ùfNÙDÀªéI,i¼÷ÊEC¨< ½þ–!Và‹˜<`AÑ°1˜V0i‡Ò¸]Ûe}a™ƒáœO{û‘ø}¬·QÖ/e®ÝZ8«¸t×ÀÁèÙn¹™AèÍÑö³Œië|·ýSµ@ëd$ÈŸêrù%žàÌZ ýµ<ƒ–ö›´œIEð1rú¾œ>Ò÷eîγÌó”ñšM± ãU6TðX…qd¦õ=ÍÀ¹ê`r€üçúQ¶Ié’HO¦H0ló–Fûrµ"ºP¥À Ø%òå<"Iÿ)ŒÐ¿Ñ»Q dܧåÉi¡T\M?Å ÆiŲ ÂÂhÈõÞg—ôqû3Æí Ž;úÙpÁi Ÿò Y¢XÄÄÊE?Á“®òJx¡>|Y‘ipÒkmèÐæu
+üÇzT¥äOy¹Êç«øš Œ_(®éeY´Åv]VÅ­+ (æ‡/Å_ùz³*"Ä`Ùv$á¾^­ê=Ž#eQp\=ôuwÀOÍ…¤™Àø/=¶yõPÐPÉÌ:Zc”yEãÿ½:Lâ\ ÙjÀ$þêD„Áé(b@A"ŽŽâhÁK•ì,¬¤Q‡SL8Óã.Îîâü}8‹z=VµBò…¼p©Ê×ÅrDÀ^ᬊT–(Ã%`ùŠï¡9*GêП#γ4ÿ„ÊZ±h{$Ãß•‡ÿ~ 0‘à¾:3Ù!˜ ‘Åa^Ñ´ˆü/`!SÑ…Ë6xÌpÚÊo
+rìäÂôcþ BxÓ,èò‡¼¬vqzzS·`‚2jß—ES’F‘[DT†°ÀA¾jj"ŸÇO´$BaZ^W«(9Å8 Üö+êEÇ¡«ï‚ëL †!a³ï(ï”Òñ(ĹK -™“ÒàÌX˜Ãö´H¬ëMpmâÛ¥m|‰fßUË<ø1L ©FðmS¼ŠÇûX<ò!
+•¢z «ÝE¾JÕóS¾Ú¥e}‡/˜Á‰ÊO÷Eä{4Ä8ëƒò$IÇR[[KÅ ‚dÒƒ#R“0Ý­x?bN¥Lv2QÖ<Ê$ÇQY½òøæÇ%Sý…Ÿà½µpRˆEç–<ES@8`ÛuLø’vM[ õJ¯¢våC>n‹Ñ&Xqͬæòд»*âˆR:ch•¢C
+HÏš.àœKåœ ÆÍôCìqDò
+éªÞcá“Â|Ap"<ôeï
+*°Ìgæ› )«cØé%Ëœ•G7kHd cìªß—
endobj
-1350 0 obj <<
+1740 0 obj <<
/Type /Page
-/Contents 1351 0 R
-/Resources 1349 0 R
+/Contents 1741 0 R
+/Resources 1739 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
-/Annots [ 1354 0 R ]
+/Parent 1747 0 R
+/Annots [ 1744 0 R 1746 0 R ]
>> endobj
-1354 0 obj <<
+1744 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [471.1233 313.2012 539.579 325.2608]
+/Rect [442.7768 538.094 511.2325 550.1536]
/Subtype /Link
/A << /S /GoTo /D (query_address) >>
>> endobj
-1352 0 obj <<
-/D [1350 0 R /XYZ 85.0394 794.5015 null]
+1746 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [361.118 266.807 409.8647 278.8666]
+/Subtype /Link
+/A << /S /GoTo /D (configuration_file_elements) >>
>> endobj
-382 0 obj <<
-/D [1350 0 R /XYZ 85.0394 371.6561 null]
+1742 0 obj <<
+/D [1740 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1353 0 obj <<
-/D [1350 0 R /XYZ 85.0394 347.7805 null]
+494 0 obj <<
+/D [1740 0 R /XYZ 56.6929 595.1873 null]
>> endobj
-386 0 obj <<
-/D [1350 0 R /XYZ 85.0394 119.9702 null]
+1743 0 obj <<
+/D [1740 0 R /XYZ 56.6929 572.1218 null]
>> endobj
-1355 0 obj <<
-/D [1350 0 R /XYZ 85.0394 93.6238 null]
+498 0 obj <<
+/D [1740 0 R /XYZ 56.6929 347.8106 null]
>> endobj
-1349 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F62 1062 0 R /F63 1065 0 R /F21 714 0 R /F41 939 0 R >>
-/XObject << /Im2 1051 0 R >>
+1745 0 obj <<
+/D [1740 0 R /XYZ 56.6929 322.2744 null]
+>> endobj
+1739 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F62 1352 0 R /F41 1208 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1359 0 obj <<
-/Length 3265
+1750 0 obj <<
+/Length 3299
/Filter /FlateDecode
>>
stream
-xÚ¥ZKsã6¾ûWè¹jĈÉÚÓÌÄ3;©d’µµ•C6Š‚lîP¤"Rvœ_Ÿn4@‚%e²år&ºtý øŒÁŸ)é,ÎfI&#ŸšÛ6{„¹7ÜÑ,<Ñ"¤z·¼ùÇ‘̲(Ó±ž-7ÁZiÄҔϖë_æ:Š£[XÍßÿøùçÿ¹{›ÈùòÓŸo±b󟾿£ÖÇû·?üðöþvÁSÅçïÿõö§åÝ=Mi·Æ»OŸ¿¥‘Œg½¿ûpw÷ùýÝí¯Ëïnî–ý^Âýr&p#¿Ýüò+›­aÛßÝ°Hd©š½@‡E<ËâÙöF*))„©nnþÝ/ÌÚW'ϳ(:ž8À˜O Ê"-baðPWå¶ìÌ·/ÄÁ 2‰Îà‚”û[žÎÍoÓv-ƒPÁ»ÔmÍl¥ófO#Ý“¡Æ6ÿ½Ü¶ÔÉŸó²ÊW•›Ë·Í¡î"Ç?8Ö<JµTN€µÙ䇪›TÈ(KSOr´Gü­œ~,w­—Ü‘•5®9[ ǧAéœG™R±]nÓ؆îþåÉÔÔ¢Õ¡Ñšý³Ù»i»(vùŽ4Kp60æ襵i‹}¹ëÊÆ-×l¦Ž@±H‰Äo­-ÿ0Ç:'b$<™%p_:Iø_Ѻ,Ö¹E¿â"\òT¡DœF*fjàleÜ™bâŽâ8’Len#tä£mè8â\ŠÑ6hrÿ8£Æ} õ=ý„#Ý8Yù?˜b8yñci$KAõR9’æÄòzª+2œ®†2DNë˜(Z—EŠsš\’ê
-P¿ªj^Êú‘ºÕ«¸¯ó£fŸw=QûÚvfKm2Û¶9 Z oZƒh=‡=5:ϳηÆspª £;»BS˜¶E­frþÐxºA
-ƒE‘1Ú5ºsçÛ¨íÇöt‰¦z¥>¨Ýæ€Ø­Å<w49=^rGcý…vn‚0_{ïäÎBREŽÅš¬àj_©yƸc‚ìÀ†¾Ù|upÑ%Å›z^ä55p1CMâ€-{œ@½ÏËÖMzú‘OWO×Þ^¡å 6 quâjrGô6£ßæVMPžWšsFh]ºF}Ÿ¸»×æ
-J€³!h¾è“Bªó>©§B)þËX\™ö˜oq?ƒÄð"_O4Á7ÜvÊ"™
-=æë¢Ú$L“y}Ø®(ÈLH]àé%´Î¿6„£‰4È6Ÿ½ðåÍÍ U45ÜAGÝx@\=·*®!i•ˆH¢ÿeW“e…ž-× Åà>T¦¯\i@uáJ=•E¢./¾LÆr€Ï¼ÌÙMp7ÉYi߈õtô׃@ÿY!­Çƒs™4Ý/ÅÒ_
-Á¢”©ôGÇ Yä¹Z+´}ȥݗž8¤ŽìvÁÃýÞ&\¾dð=%[§¼eã$ŠƒSqf|aˆs6ãÆOà,EMc_Á# è7îÅ> /Ôg‚8–ÒB
-Ôãv6;ÿÙ–ˆQBä3'HÑdÌ#-!<g°;WlÃP=ñA4°ÀZâ6ˆÆ¸;Œ–Sáªh8h]nøZS­MÛ¹Á}^·yáCQ±F’÷cÇ%—ÐZ¹éüÐ5[
-ÎÁF©½t4í>AB+§ÉM^îi`Uvá®ú’+†UÄÓþ`¸Ãðt¬ÙäS¸ýÊŠåM<eÁ ðq8fÔÿRVÍêµ3øDø¡8ñœW¿Ä††¦k+<Å`”é“BÈùbG’@¤g£b±²@Œ¼(]Ç!4nY¹þÚt®9UàpSî(b é–j¬$"­×±î)øã­>8ܳ֎Ûdq&.[{HuÞÚ{*{SÅî¬C ‘0ˆ˜/2ï©&¸Óò4Òi¢Æì—¾–Ôÿõ`çЦ³>¶sé•ÚË÷?¹Á¦®M4d}¡q¨'£ºñP’¦Ä}ð„”—¥GJý±Ž!1êÀ'M™'QIëµb —2Ò,¹R_ ©.ܼ§"S±ç°^´MñÅLÃ|¦.ów4ì!>\ŒùÛã„
-ºn^&2ª¾ráoÞ&Pþ´ÿ÷Oë†ßÊ®%§Ž?d/”Õc}êQÜoðNEÿ˜"0Ûendstream
+xÚ¥]sÛÆñ]¿‚o¥fBä¾
+Ö>lýa•’÷(é%ÚÄ5›–_\ÓtÕônß”uýLãå3%%èIJê1y»ûÐûpýes¢íÎ…—€ó¹ëÝ6yaÌl1™‰²Ö^6«!Õy³ŠTÈ:(ô¢ú¶ñ§^ÔíýbÒÄ2™äV—ÙˆT|ŒL,Ë’<Ôˆ‘»‡
+¯±Ð¬ «yÄ-»¶v½ûëõÂdf^õãérµr»Þ_Žš5Oß7tŸa¯×äž‘ÆbÕnwp˪®úçk)%Ê"×Ö«,^9øäÄÊLožy}iRZ&Z¨`t(僽€&EŸH%·`xlèPàuÛ±£a{¨KV©Í¡Y‘œ¼‡àç ìœÕ¥‚—RÆ\Ö¥!Õy]ŠTçNyªFF(s™ƒH5Á©i«í˜‡/Î{ ã…†è±qà¹òi
+Wûj×·ûŽÜ,ð' ×|I€S¨ ŠýïhØõëªE8Íç®_Ë´"ãäËoíÜšA´u|.-¹¬îÙû§‰Ö§>Î5íáíÙJ Ö¡¤Yˆòê@Ôf˜÷Ú 8ߘؔ+×Mº4•EZCM¹L*µNŒAU é‰óJË·Íwëš,ɲ;N ÿ´~(cD`¡äuŸœ·8HÀÐÁÍœKÇj툀Æí–+ ¡„[”¿2¥áÊý}KAJcà?ÇY |[
+âxfNÚRÙ©/ PVáÚH &¸33t渳IÏd²ÀD&¬ö¿ìX»® [ú>í܆c½øÂå%nÎÅ L…øJ¯=°dÞ!ªæx:Î/hN~’ym=õ]ë: ¶4£¨Mwl²<”]¾}_³/w\e!c\fýz‚›uût¾¦RøA毸æ!ÕyשB'f…Uõt{ô…Î/ï©&iu
+³y*ÇP§×Øaÿ¥ˆsœðYp›ç}®8Ÿ‹"ÀmšÐ÷ÌißPþ¤˜ÿåÚ_?â|Nª”‰…NEqT
+w­
+yÒýüLq§æë²/ òŠO®þmK 'tÜÆÈ$y‚)Ÿ¨aÊ›¥ÇWc0'~AÊÁã‚+N~y)*ÕÜ}ÛU¡mãATzºW±¤„S^’’š9u¥ÓùÇÛ_ˆ4ÂÞ¾ìÝý3MP[Á„l( ‡ÀŸfÉj $¶Lä¾­ :RsD™ù" >9ÙÐSŒð5wY£ÜR°zW6è¯'[モoäK‘!òØÞ7 §øaàÞgÞ€¢Æw»%jV2®Á¶ñ½€žX<]µ§îî>òVÇ[ñ 2=Rð_
+Š©£®6¤ól¨‰
+ªË¥Õbºé‡¦«îê•KŸaÜ»=/ˆþY|#_wù?ôá˜-©$Vùæªçã™jBC#ð>®u¨l²¡©@WnºZ£;Ƨ ‡¯Á,ü«‡
+®ºq]Xªä7ºÃn×îy°m£rØð‰!­è¹¤O–:þàªp©$_ø@¸éÉÏB»¶«úŠê@MÂǥለÔsÒ›!ÔOo xBþÑ-à€
+Gsò5Cê˜Âö¼TKhX%!ÌMC˜’†Áë Š*IÄbUTíêÀe垨–Ñ[ž+Ú»ÀnMù•ï4îJtuøæÙž|ò
+sÐ{á^@¸ñ5èÇkmTÿgCª´&QJ¾Ò¦R©‘*d»”"/ «<¸©ž–ÌEq™ƒH5ÁÂiOK¦Axà Zp®N0q³Ð^V»þÁ={¤ôØ f›šÅŠHÍïÞlFA·
+v8ÉÉ4’S2 f†(“ð23U åÙ™OeÕa`žø9€2I!²lú×
+‹Š÷Ù“€2RX}qÿHô’±æ‰±E6â€?c[5,Ј±ÇÁg€ä¯Ûàó)¢dóϤ.U{èêØ6õ-Š‹Çá§öP¯ <D¼aLKÖ1î¦FgSß±ð'ñwi1‘Rr2¥ÁE
+cþ†ôh¼K
+OœëSÎSm“Ôª|‚õÿÿ²½)endstream
endobj
-1358 0 obj <<
+1749 0 obj <<
/Type /Page
-/Contents 1359 0 R
-/Resources 1357 0 R
+/Contents 1750 0 R
+/Resources 1748 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
-/Annots [ 1361 0 R 1363 0 R ]
->> endobj
-1361 0 obj <<
-/Type /Annot
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [361.118 743.8714 409.8647 755.9311]
-/Subtype /Link
-/A << /S /GoTo /D (configuration_file_elements) >>
+/Parent 1747 0 R
+/Annots [ 1753 0 R ]
>> endobj
-1363 0 obj <<
+1753 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [347.1258 350.3535 404.2417 362.4131]
+/Rect [375.4723 594.4187 432.5882 606.4783]
/Subtype /Link
/A << /S /GoTo /D (journal) >>
>> endobj
-1360 0 obj <<
-/D [1358 0 R /XYZ 56.6929 794.5015 null]
+1751 0 obj <<
+/D [1749 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-390 0 obj <<
-/D [1358 0 R /XYZ 56.6929 484.9636 null]
+502 0 obj <<
+/D [1749 0 R /XYZ 85.0394 722.9644 null]
>> endobj
-1362 0 obj <<
-/D [1358 0 R /XYZ 56.6929 460.3339 null]
+1752 0 obj <<
+/D [1749 0 R /XYZ 85.0394 700.3281 null]
>> endobj
-1357 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+506 0 obj <<
+/D [1749 0 R /XYZ 85.0394 132.4925 null]
+>> endobj
+1754 0 obj <<
+/D [1749 0 R /XYZ 85.0394 107.2061 null]
+>> endobj
+1748 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1366 0 obj <<
-/Length 3380
+1757 0 obj <<
+/Length 2635
/Filter /FlateDecode
>>
stream
-xÚ­Ërã6òî¯Ðm媃'G'ñdJ&³Ž³{Èæ@KÅŠÔˆ”=Ê×o7ºÁ‡DiR•-W™F£Ñhô €äLÀŸœ¥6:3³$3‘ÒΖÛ1{¾n$Ó,ÑbHõíÓÍ7ïu2Ë¢,Vñìi=à•F"Måìiõûü»Þ}|º¼](+æqt»°±˜ûðá{Âdôùî—ï~øíñî61ó§‡_>úñþýýãý‡ïîo2µÆ+æpaÀû‡Ÿî úáñîçŸïoÿxúñæþ©[Ëp½Rh\Èç›ßÿ³,ûÇé,µ³7hˆHf™šmoŒÕ‘5ZLyóëÍ¿:†ƒ^?tJƦ‘U&ž-´‰ÒxLjYD‚։͢X+ÝiYÉ)-*Ôò6ÿ²XæË[4ÅŸîtÑdìÕóÙüÕ„
-ñe2åPJØ7£ÐX±Ü9ŽÄMû`}´ØMþŠ¦‚W
-ú Qãw ›WÀVW® ¬rÑv»zÏmÝñx­è za^Y8"„*dµË—¸Ó‰°ÓÇ)ÛÜÕMÑ~AR“ò‘¡4óÒ5 µÔÏ õ󷼡ü°ñìè {ïˆ#5×2«šÐÀ%"ÌCE˜œš!ê ê­h7„ÝʶؕAʽ5Kµè¢å‰Avþ;°Û•…yÐhÜ.ÇQ©íÕ!Pˆ.`ZÁn/|Ì$'¾ûð¢ ʈ_¹uR£à©Dt–È9[ÆÆD‰òzJR]N©•4ËÝ¢,šÖU‹Ïw˜HªY$‘]— £ša”Tc¨G,äÒ‘ œT³9 B0I³Ð^W»vã“^ÚÓv
-ô ¸Z°-*Ž ¬VDjû°%Ý Ö¾r%ÁìC í2ª5‘±>ɨË%ˆ„“@ªl½ýaK)ƒ¹•3çêˆê¢Ü‰P^bÚAhYW-…ê’û6õÛ¼:ôôÝÇŽº‚(QÔUXæ,e[„¼[¥)éoE8ÈñV¯¤$·'ð-ä¾Pñõ–û¹t
-¦Zw±{ž]7n—7”qö_Òì…Ê’ù¿Ñ)8t`'…Oî#Bš¢JÂOÈÂ¥«Úr2:íó¢ÁÄLYehÿ e¢LÄXŸ&T׉§Çb[Æ‘”P| zݾ¨WÅ’<òéV¢äÍ'j>@òØCÄk.ù©Õ*26Ö×ýtHuÙO;*sYR±°(X„3GZR}]„ŽjB†±£&‘I³x,Ä›°šwRP‹±}&ƒôàë @ÖÏM]B0—sÊ+ñü#ÍkQ B cf•6dǾ’Dø­>”+¹"¬_™¬/NV]ö…cJ|b”Pj*’–>ªd… …“ €P8è@®ã„uÉÄFʘŒ‹–Éý:Qr*#abÊœ¢:pq¯>;â„}*
-3Iòs’ ƒàûã}3³\ƒ@W_ƒ@#ŒŽµþ c]ÞÔUþ\òЮl¸?ÍÁpX
-Ø34… /§jƒ±aWd{@ tØåòpÝqÇU¦¿r5¤ºì‰Êèc ÕÒOÔQ,ÍuÑ„ã<œF6³z,Ÿ"²Á…K¯À.é$  ²‡káhþ‰(»%PVÝ]ÊmJ H«P ˆ+*8OnÒ¦g¹Mkªá}ÊÒ‰ˆ´³±Mw^%³ØÛ'~Ñ«ðÛsRP@zExt0o µ%›÷p8š7~ɼ˜÷€/›7òFóÆoÞ y#{oÞž|>í4‰=¨øó6´=iÆW/* fì‘t ƒí
-1ÀÓÁÉ;ÙžÝKÁ3ñ©pj-”¼µå{L
-´_‰yª+1/Pá²›–‹•as5è EˆŽjBŠÓ°'dr"ƺ2Ôî„Ãvw†žg¦.ëºéåò=ƒ:'S!`]XñDk{äLª¹H}‘@O›Èª$9ñ'6€Xœ^õiï’ÂýrcäÓ6^‘PÚ¶b”¶‘Á8mï‡u¨qÛñ…–x7®’‡Š[ö3KAŠ=³G)@E&ž©ÄDq&ì_y~BišN??Aü‚4ñ^4N
-„´Q¬L2S±ŒL,h§> ¬ÀÆFzJHŽZ¶‚_ Þ“ó'ø¯æ÷gš¦ZAZT*Wû¬?û<Ã`–i¢À~±½<⛇­š}_Ã’fÃU΋!k¿®xü¬KLH  öÂвüÃT›Ç[Ç#nÛ]鶮òÇA¨èË›
-‡ú×»5=µÄšoð ²r“3qhHŲú‘º–%.¬ ýLß6®\ãÑÊtåäi²`56 ÷1íå 2vy÷½Éó|øŠñɱty51§‰“àýùjÁ/±:ƒú79¹8^íñšs"\Ì RêHÿWàÅWÍÛp–éYžÛ·”*‚NÛÏL¯ìírs&¤à(Bý… ¿&¤“RœÉ±Þ<Ï÷b_¢U¸R£++P¥Åé¯ø׆>üÆþN šý‹&4ú’ka9¿÷Ï:Øæ´(¡–(i,9 v¸2˜²æ©ò¦{Ä} nñ L÷]‹$Ž 0JÇõ懺ZTî…/ä” ì‘/êÿF¦¼Ïb;°$$?z#è+r%º^@Ñ+^èðJPá©XQÉêßËüѤ+¸UxÁZï™û$‹f*ZxÖ)
+xÚ­YÝsÛ6÷_¡{:y&bðE˜<¹©“sçêܹ¾§¶´IœP¤"Òqtûßo P D)í$“q,‹ðÛ/ˆOüã“4K2#Ì$7*IO'óÍ›¬`ìý÷<³À4‹¹~x¼zýN擘Ld“Çe$K'Lk>y\ü:Í‘\ƒ6}ûáþÝÝûÿ<Ü\çjúx÷áþz&R6}w÷Ï[j½¸ùù盇ë×)Ÿ¾ýÇÍ¿oh(ó2~¸»ÿ‘(†>g„>ܾ»}¸½{{ýûãOW·ý^âýr&q#Ÿ®~ýM°íŸ®X"N'/Ða 7FL6W*•Iª¤ ”êê—«÷£Q7uôü8K„ÌÄÈ
+ æIjL:ÉS“dRHw€»ivûë™LÍ´¼æÓšš}`ìšë©Åžž¶Ív]¶]9/:»ð E]Û µ'.Û©n:"‘˜jOäƯҭ½ä­Ý•Í¢œy^Ù¢.ëU»*“à©ÃÖgœ'&M…ÛÇ/[;/—{7 ¯¨M©Õl»$ª%Ë~cH^ž·nèk—8º´óÎË8̧FkwŸqß
+a:l€Ôièˉ¼(öC» ù‡ ,)ò4, DËJ“ªn¨øRnž7ØÉhq¢;3’ÐÔ‡u<E+&ÅÙÙônIŒ­íˆUF{_-ÈÜ€NPÀ‘
+#VîÐà ±õ¦èñ€MBš3Øùüù²%f©
+pìˆèŒ¨EWySÿƘX=ï
+ã`
+R*ÏàŒ¾US,ìÔVBOo–ÝIB½@iÉXD ÈÁÅ{Ýžìªô+!*l=s;½eJ‹OÏãC“Š
+\nžˆ\ °®<Ñ©!F H3År 4J¡<>@¾Ç§ð¿˜ž:K Tq•Ë$n/“O8$eà”OÔv;=œ€#¼¾ÛˆÉ ìgoÉËE‚ÝŽ²Q •¡’¥Y’g>©¿o\ú¦§ûk¥‘ï”›me7¶v¥ #ÔôõE4´Ìɽ«Ì$Dô$>Ùo»,HbÁA­=;”Èߥáý3­äeG¨D
+ •ö<K¸€xÏ š>:‡Ül°„ýˆƒ
+•Å•›~㪜áJUh
+¬;êUKä'ëb’í§ç¢ƒT)÷¹1[âì+0 Î×MÓZ/¢ Oí\%Ž8¹³t¤a´ÞiIqvÍ>!tŠ.‰âäd$½ÅäÂði‰µ
+Ï\:Ær}OCó
+7Ö…qÏßµ¶Zb]¥úLò8Ð3@Mæ-²;=J%Lù|‡y¿¤wÅGëµ+ê‘u
+sxš_,(Yš)ˆ^"×QZ»³m;â*™æb"ó,Ñê’Åð-sÝNà,–xŠn ;Ï«ºðUtóõIXçJl©¿Ÿ‚½Ä¯hÈ9dí’™§‰¯Rðpî©Jæ”`y0v­§ua ¿™{ ƒn‹/L®æ‡Î!Ó‚<…Oo 87
endobj
-1365 0 obj <<
+1756 0 obj <<
/Type /Page
-/Contents 1366 0 R
-/Resources 1364 0 R
+/Contents 1757 0 R
+/Resources 1755 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
->> endobj
-1367 0 obj <<
-/D [1365 0 R /XYZ 85.0394 794.5015 null]
->> endobj
-394 0 obj <<
-/D [1365 0 R /XYZ 85.0394 590.4054 null]
+/Parent 1747 0 R
>> endobj
-1368 0 obj <<
-/D [1365 0 R /XYZ 85.0394 563.4931 null]
+1758 0 obj <<
+/D [1756 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-398 0 obj <<
-/D [1365 0 R /XYZ 85.0394 179.4044 null]
+510 0 obj <<
+/D [1756 0 R /XYZ 56.6929 439.8265 null]
>> endobj
-1369 0 obj <<
-/D [1365 0 R /XYZ 85.0394 153.6629 null]
+1759 0 obj <<
+/D [1756 0 R /XYZ 56.6929 416.0359 null]
>> endobj
-1364 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F48 953 0 R /F62 1062 0 R >>
-/XObject << /Im2 1051 0 R >>
+1755 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F62 1352 0 R /F41 1208 0 R /F63 1355 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1372 0 obj <<
-/Length 3131
-/Filter /FlateDecode
->>
-stream
-xÚ­]sÛ6òÝ¿B÷tôLDŸ'Oiâ¤î´NëøæÚ>Ðes"‘ŽHÅñdúßo P Ù¹I&ãàk±Xì.ö‹b³ þ±™Ò©.x1Ë ™ªŒ©Ùbs’ÍnaíÝ s0s4¡~º>9{+òY‘šëÙõ*ÀeÒÌ6»^þ™è”§§€!K^¿¿|{ñî?W¯Ns™\_¼¿<s•%o/~=§Þ»«W¿ýöêêtÎŒbÉëŸ_ý~}~EKÚáøéâò ÍÔAzuþöüêüòõùéß׿œœ_w ïË2ùtòçßÙl ×þå$KEaÔìYÊŠ‚Ï6'R‰TI!üÌúäÃÉÂ`Õnòe)šG(YŒªHµàÂ2°oïÛu{ûx:×Y–|Š͸H –ÉÙœ±´PŠ[@–™—v9/ü‹ Ä—“UÐWB 0gL¿¤@L¶÷í™GO¤Å³·œ—@ôyZn,ÌC½^ƒL Kî·§Ì$ÕªÚÒ¸«¶Ÿ«m‡ž´ M6UÿÐn?Ò€eÔöwAmÚ®Ý"YµëuûP- âæ‘Ú;
-]¿`”–PAÝ1™
-K®ážX;À™å :%ÀHe™Á£gŸf,ÍdQ
-úö®{؉³‹ Ÿ½iáF³àRñ<Äl/¥C[
-ÞoYõÞÄI³î^@NĽá}nvˆ/ËêŠ:½³cõb©QÊÛ¡í蘷[‡x¢2
- Ƹƒíå²èîÉ3Ûj]¨™
- ³
-N‹Û[g›®‚
-èäMÙyàÖá€éÿîhH­"G?Sw~«åñjúiW;X‡iàq <ÅšÔ¨A¶¹Ä r^$_
-c]„꽑٠nÍZKoæ/yhã¤vÌèC'ÀÍ¢aµö7¤.Î5 ¼ò#ÞWÊ&F
-©Ü”=$#XVˆFÌ£qÀø Ä(s¡ÇD‘$(…Ђy~cʇ©!–Ü:ÓÔ;Õ=ÉìMC3›Ö[u÷Õ¢Fu^XOO†×
-ƒiÅ7¥Ùw‹J ‹<#¨—"Çóµ€{ÙÚgÉjä¡ßÍ d4 C
-E
-øžó»~nˆùÝ)ޱ߼ßå‡zÍArW‡GDü®ƒzŽ’lß1Ÿ—6‡F1´÷ÔYƒp×Ä´ 7ë'%Æ$èQ1d+O›&¤Üì:¿ïªõŠ´Ff€-“z¬5hËEÎmÌécR}¹_׋º£e
- ÚŠ0H”lEHˆÎåw¿Ðã<DyøB™‚7Wùþä£f„™Ò@0ˆ?ŽHñ9"±ÄÀyÌŒH’‡@µ!”UÛT$,Œ#p¢h©SQÆŠ>SçŠb@D²E¥€üŠÊ\Ý×l6…·“ô‚'¿“1ÅS,kŒc¾½·* °ÛTÛlë¬Òñeòêõ¯Ô¡t{ö^ЖØ@J^u=Už¦Žƒc)C=ãØ 8NµR<ðà4Æyˆ2æ4TŠ2 Ž;60º…
-!]:‚!ù˜°<
-w8rø®t@7•  gé©–øX4¤æãÍÜñWÎÅ’„Œ0„8¸GƹãmÔŒ[Ñ|D’gð@î‚xÁ€=‹~‡iƒ`˜VÕ›º¯?W4Ü–¹Ì§å4ðŒøÃØ„?Œ‘B
-¬¾ÚÒ¤\—Õ—žà6örøáÒì+n8XÎcvtLlf_Úu%P“°sM“²3.iÉQ„¦ši§×
+1762 0 obj <<
+/Length 3018
+/Filter /FlateDecode
+>>
+stream
+xÚÅ]oÜ6òÝ¿bßN²
+?%
+yJS;qÑ:­ãÃ=´}we[ˆVr$m£è¿©¥´ZÛwñá`’Ãáp8œ/-_0øã £c&3µH3kÆõbµ9b‹˜{ÄÎÒ#-C¬.^ŸÊt‘ÅY"’Ååu@ËÄ̾¸\ÿ½ûðö×Ë“‹ã¥Ð,Jâã¥NXôÃÙù4’QóîãùéÙû^¼=NUtyöñœ†/NNO.NÎß/¹ÑÖ GáÀ‚Ó³ŸOzñö—_Þ^ÿyùÓÑÉåp–ð¼œI<È—£ßÿd‹5û§#ËÌèÅ=tX̳L,6GJËX+)ýHuôéè·`0k—ÎÉOKk#Ò
+>'@ʼnÒ
+ÏÌ“˜Kc,º¼-è„]ÓöUÙõÔûÔç}±)êO tE@—-–ÂÄ™I´¥H¤ŠÚcn¢¢»kêΎȨoh&§î矨ÿe[´nòš\Á2ÚF›kÜl«¾¼«Æ4[ ¬F£«Æ¶ëŽþÁ4»¸è á„uÝ´›²¾¡Ùü?¡À#sgZ {ä®@>3å·)zÜtI)éä“u¾qPW´_‹–àû²ªÜ<°”WÕõhÛ~ÛÖÔŽ€¾_Ùß–ãYÙÝ ôsyM ËcÕë¢/ðäp4êÎìŒFÏ ÏsµEz,® p3RƒP½àÀFkÐT»²meÓ:•Ñ,œ{ÜnP.Køž<+¡dÌx²HY§R[ý¦¹öfAÀEð <ú2ħ÷2±GyùT¬ú²©‰ÿ8Ô”!ÉU,”s´÷0¬'Ù§æd*$²Ä©0´ªÊAL^[+R%œmÖ¯»m¶Õ:ÄËÛ6¯o‚ ´
+ß$Ž–I'»€N^åGn­™ÎðŽzÁ­ IèdÊÎ/µò1^M¿lK‡ë( R# „»X{:k‘U«’à¹è~ û ÷.ŽØ¦ÁâÄ$jðbû6ŽƒçL”òvË»È}'ÁCL±oà$øX´ªÖ˜b窨š{ç—2¸¼ü3žgòzŽpö&ËGe rÝ·O6¤&]$€.„QωDøpcæãå@q’Ü2$ØK¤z·3²¹ÉûÕí“JÅFrñ‚LzŠO1©ÒØÆÇL¸JžÆ2‘Ü ¼^Óí”58Rg›zwceO—§¦‘MãÍöº»bU¢>¯¬Ÿ'Ëkà,Jš±ƒmÅG•ðε@e©cªo¹y˜á}œ
+ó‹òU¿Å¬Ar̪ÊMÙ—_ êî, g.±ÃaÇ9u:#ùp>‘礀¸í†µ µàÄÀÏûm®¯çNE—/²iaId” B»i¾NF†EWÅMY×”ERóÑ|HÔæf2:›â„>_Þc›Sãªe!ñ{Ç…·æ¯¨¤ÔSÒçHÏ$¥]7nEg«1N²&ê]Vß“€S/LHúÈö”{ÜùĘ8UL>aqY ÐÚ…–Ë;/`Ì<ÅeHr.‘
+a0#‡·u¬öÏœ¢F×)çë 8ÞÝ6÷5W@¢)£Î¡PV!y(o­eôÛ ˜€?QLÀz95NÃ$Uq-u«|@a$͹R«?®Ô©×I€‚ƒÙ¾+è"8UyMwˆS.HÑ阬 4´÷‡zz–¨õ¬zz!”ŸxùÌ\ÄNZ:›JKžñ.áqÒ¸º¦ÇX6ì®Üî>YšAÑSiÚ‹Ðøˆp—ž9afN˜3§™¾e4ˆõ`Ë–Àu9ªccÑ4xÁX^ %öúTñɇÁÀzî¾(&ŒEY¦„Œ3üP:bíõkB9;¥ÖÊWõFÐ
+vFÇüÚË'ç]—­ßóºt
+ÙÚWâ
+SiÔ•›²Ê[´E í™Ó#æ¡G K0=©“%ÖÅ]›nÁˆÿ-T©8‹¿9..‚X—QÎp0¤,Hkˆl%WLz9"èCÄ!B‘å_mxƒ”áHWj”ÙŽÆX´8DØ ã×4 ³t K±¡v—yA' g‰‹™gàM`äp÷F¸/ÜôC!h&*
+¿_?ü*¨V:÷Ó6©c5ÿÝ þÝÎßý³·ÝoñÙ1âÀ<–€¡ÌRÏž8ÕS·ßÇí³þoòÒ!endstream
endobj
-1371 0 obj <<
+1761 0 obj <<
/Type /Page
-/Contents 1372 0 R
-/Resources 1370 0 R
+/Contents 1762 0 R
+/Resources 1760 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
-/Annots [ 1375 0 R 1376 0 R ]
+/Parent 1747 0 R
+/Annots [ 1765 0 R 1766 0 R ]
>> endobj
-1375 0 obj <<
+1765 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [213.6732 432.1255 286.8984 444.1851]
+/Rect [242.0197 702.9298 315.2448 714.9895]
/Subtype /Link
/A << /S /GoTo /D (rrset_ordering) >>
>> endobj
-1376 0 obj <<
+1766 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [209.702 354.4169 283.4678 366.4765]
+/Rect [238.0484 622.4676 311.8142 634.5272]
/Subtype /Link
/A << /S /GoTo /D (topology) >>
>> endobj
-1373 0 obj <<
-/D [1371 0 R /XYZ 56.6929 794.5015 null]
+1763 0 obj <<
+/D [1761 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-402 0 obj <<
-/D [1371 0 R /XYZ 56.6929 498.9148 null]
+514 0 obj <<
+/D [1761 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1374 0 obj <<
-/D [1371 0 R /XYZ 56.6929 477.595 null]
+1764 0 obj <<
+/D [1761 0 R /XYZ 85.0394 751.153 null]
>> endobj
-1370 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R /F62 1062 0 R /F63 1065 0 R /F21 714 0 R >>
-/XObject << /Im2 1051 0 R >>
+1760 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1379 0 obj <<
-/Length 2398
+1769 0 obj <<
+/Length 2587
/Filter /FlateDecode
>>
stream
-xÚÅÛrã¶õÝ_¡Ù'¹Á¸Ø<9[{ãLãmµÎd:›} %Êæ„"‘Z¯Òé¿÷àF‚e«u2† xpn887˜L0ü‘‰3Í'‰æH`"&‹õž<À·÷gÄÃÌÐ,†úîîìâš%´¤rr·Šp)„•"“»å§é»ï/ÿ~w5?ŸQ§Ï„ÄÓïnnÿêf´{¼ûp{}óþ§ùåy§w7nÝôüêúj~uûîê|F” °žz G\ßüíÊÞÏ/üñr~þù«»V–X^‚™ä·³OŸñd bÿp†ÓJLžà#¢5¬Ï¸`HpÆÂLqöñì-Âè«]:¦?ÁŠ&#
-ä$R % î„F’Qf5ø¯ó™ÄxJ4ED*D/(ÿ¶?ź©>A“O¢8 i!è3˜á&/.ÜÇ›k£{T¥›Xi]»á»ÁzKŠ2¤ Èp
-%©"Jwß_ݺѮÎÜ
-¢ý³º†)G‰úSffêtõ°‚ð÷÷>‚ÈψÑ;ÚRx‚QY5npŸ¹§±¡l‰Ü1íÅÒö˜&·,òº È—%‚{\k!F©ßFï SÝ÷sxÔužlÌ€{™JÂ\
-`ò"—G0 œÏëÌkâÃv ª¯3ê©($N¸Eòócf½‚˜®wE“·ÎÉ›GeŸËÚ¤n6†hvÛÒÚ |ÎËà{<xY?Ù½3ß¼_Z§{7qïÑ@xZí
-7gÏ.<ÁÁ˜>ìbzÞ߉©ç)ó~Ðú³øñë#[²)Ò…åš3àÚ’åÜc€)oÒÖ8¿[5ýpG#œüív ;0«ŒòG4/0 Õ¶nÒ&[;·$7ÙvÛÃ
-Œtò§MnÏ@X9áÙrÙêÁ…Xw
-H@„a=ÃÎÝbë àY¼õñÄs’ž~Ì<|ZÔ•5ãzS äÇ\]„sx¨4Ɔ‰Î¾fðLp$1á&©š˜TÚ}Û>LÜ`åÞ|ÃÛÔ»O|ˆÕ0ñ¼¤Û[»¸3Ȇ q*cBõ8:¨Z¨9Äf8An?#Ô’÷SËrLïÒ:‰Wgk¨1ã„0
-N1‚e'UCi¥Ôx-4k1Îb”NÈsTÃ^óŽ°ÝòM¶1 JÇ"œ»ÜÇ„efŽóGÆ
-ý´KÂê·Þß‚*5æýHðÉ%â–`1!‰ ²$žP ÕÓ§PÙaŠ¤fòõ g1J«±sĆ޶隉¶#ó¹¬ä³Ó̧f¿ÉF¤·F$ v€b¡)iÜé&t‹ñ¡)MäL¿Bê¸/µ€!úͲZ§yyàiÀJµÐú¼Åø‚àŒh3&¹FJ%º/y:G¤§ˆ*%cß0žAWoÌS÷ÎÉ…d¸&s*”¶f*?'S?4ç97§4[BeÆ”ëfÁ2[¥uü’zÔ}÷“I8ö—·ÿw Ró`»È¡sÌ)Ϥ×{`i“µ´ìÇ£¼é˜7u„·„!NÛöoòyÞ¬uF„@á.™"²ŸÄôÙ ÁÖ;BÏ®y Þñ8acŒc–Òž‘¿Œ°ÍA2ÈP€EãbÓº;©…1ññˆ†fÉXI «Šì!õ™û—´Øe­“ÞŽ0§`ìe£„˜è6¹ò‰êÛWÍÄxL¨ŸP‚µ:åð2®
-²ž H\Þg è«+ü*…ÂÄÚšSé¼W pœ ‹ølóIl@â´ÝÍïõC8,`ÁÓß«2Ëèͪ"Ci˜HI'±j^§n³±P¨.}>eXq|1ìçì¥Ä°€aíªŽ´\ºÖƱ"Ö{›Í·(p[ÔÕ:À8BƒH’ðé3jäyŽ:µ‡.âé(Ê£j‡RÏ(ðŽ«jx"\ʸØ/Š|ñ§©Ý×ažJ\íÊåÌîìáf ǯ }3Í”½öÓa­í‹â§¼yÔ’ÆïÃOf¶59ó~cfk^LQº +¦£ÍÕEµÞ䶰dp®Mj°ÎLüb¶
-aBe_§iñ”îë~‹ø¸ß}&ÈÙ×eh;GéC5žîçcÄGFnýxÜž;L™¹p~rKRš³7h¯ 6›,µ¼tõÅ~D¸¶û
-1)H;˜ |'XT3p¸@¤È³»“‡¢Ü\¤tÏðäÅìÔûú©´=Ò Í3e”&ôóöbÿõÿ
+xÚÅksÛ¸ñ»'Ÿ¨Î Á›Àå“/g§¾é9­£N§“ËF¢cN)R'Rq|7ýï]¼(ð!;©¯ÓÉ$„€Åbw±o„$þDH$5ÕI¦9˜ˆd½=ÃÉ'X{sF<Ì2
+|zóx9:Ð]­[|yIc
+:ض˻b[Ô;rWì·e×:BŽüç]ÙÔÂò ßžÊ^æ¢í¾ Èœ(À¤¨Î†g/T'wŸHà×O<wÁé»ÂÃçUÛ¸Q7/7•esdìp*4Ɔ‰‘̾ûF%b|„¤)N”ñnqÿ)qƒ›ÈmôðËxƒuÃã'x ¿ë?² M:CZi6 iâÀz¨§(™`3” w¥Œƒjiœ@Ávñ¼ž½Dpy‰öº'I¥²DýÀúk9Ú”šwãË€o!t ÃÉ,ý±öÆwÅzF+(E‹`JeënbS«qîÈ(¡Ÿ¾mªª¹o¿÷î.Tc$•Y ï×UÞ¶î Áâƒ$‚ØHüA=T,-BÊ°'4C:“ìÙòê1.c”VbâÜeFAb=˜!²Î·ÅœÈ
+a¹.»Ò†
+†Çµ.,ÛZ7†í˜»/«ÊMnón}7'–>VâtýO‡÷уþÖÃ>åob¥zž¢uÿØûD,"5b$ŸP:#%é 7)ji¦Àló"PÀsÁæ‹ÚЕc¦e¨¸ói—ÍÞI¹ø’ow• ã£vž¹MHp%V“ÆKÔË ùéàæ}bj ®®Ý×8vtî>.3£¦Ý‡<%4ø…›Îr®ñÕœÆGPÎœ}Ïo–°¾ç7j×A1¦ˆpñÚk¶”é:?´Eè·=Ä/×’±-»ÌæU®}fy4£ó“>Ù·ð¼ÌÐÉ`êîrßûË?{TÇœrp;TSPò¶±gØ„P!MKrcÖ<¹û´‡[C­õ@ÆsdÄô }’¬6áf Ó¼ºÏ¼ûýø¤ç}$ÈÙþÖyå3×|Â~®5ömž>vñ'<¹UòìèÉãÖÜ4_æÕŽì“íHÉ´·Ö»]‘[ZŽÅÅà suãË ¸WˆJC¸Álä=A£º‘Ë…Cª²hÑ©—È¡2ÙW=%(²µà'nÅ@Řþ—vŒ\rÿd”A>lØõÊÙ€5 U¸p%\îpÝ„
+08:ù5!àcµf([^2°/¯¶4ù±Ž’ˆ©€xc¶LÉ*ÓqÊŠ@ù‡ˆ+PgNLÞ¤f´/ª"7îÉü0‘Ú|]bFtŠs}lËAƒ‡c„©Ô½/`‹ÓäÅÇîÅ€0Á!)îK먹nÎÛ4…'̪«´‡ÝθFS]¸›åDz€ ¢Ø×flpĬk'æÙä$R§ yn %¸ÁcÊpã< ˜¹,=f0³íN´Ñ©I¸ Î*lrXG™üèÊm1%À¦3·¾\§?qJçNXF¼R» òÍÚ}-ÃÀ,ÓÇâ „mÁ‰ºøswÓ< ’ ª´Jb zžQó”æò¤Ç]ÆÐÎ…yu›- ŽÁôos¿ͭ²ÑCí¯càìh.¸‰,C4“äÄ+§ƒYF@§) @†
+2™e×U“?Ø»†xìÔ
endobj
-1378 0 obj <<
+1768 0 obj <<
/Type /Page
-/Contents 1379 0 R
-/Resources 1377 0 R
+/Contents 1769 0 R
+/Resources 1767 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
-/Annots [ 1381 0 R ]
+/Parent 1747 0 R
+/Annots [ 1771 0 R ]
>> endobj
-1381 0 obj <<
+1771 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [353.6787 434.7534 427.332 446.813]
+/Rect [325.3322 626.0361 398.9856 638.0957]
/Subtype /Link
/A << /S /GoTo /D (the_sortlist_statement) >>
>> endobj
-1380 0 obj <<
-/D [1378 0 R /XYZ 85.0394 794.5015 null]
+1770 0 obj <<
+/D [1768 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-406 0 obj <<
-/D [1378 0 R /XYZ 85.0394 505.3435 null]
+518 0 obj <<
+/D [1768 0 R /XYZ 56.6929 696.6262 null]
>> endobj
-1022 0 obj <<
-/D [1378 0 R /XYZ 85.0394 477.7522 null]
+1294 0 obj <<
+/D [1768 0 R /XYZ 56.6929 669.0349 null]
>> endobj
-1382 0 obj <<
-/D [1378 0 R /XYZ 85.0394 352.0635 null]
+1772 0 obj <<
+/D [1768 0 R /XYZ 56.6929 543.3462 null]
>> endobj
-1383 0 obj <<
-/D [1378 0 R /XYZ 85.0394 340.1083 null]
+1773 0 obj <<
+/D [1768 0 R /XYZ 56.6929 531.391 null]
>> endobj
-1377 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R /F21 714 0 R /F53 1029 0 R >>
+522 0 obj <<
+/D [1768 0 R /XYZ 56.6929 132.8855 null]
+>> endobj
+1774 0 obj <<
+/D [1768 0 R /XYZ 56.6929 106.4421 null]
+>> endobj
+1767 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F21 930 0 R /F22 953 0 R /F53 1303 0 R /F62 1352 0 R /F63 1355 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1386 0 obj <<
-/Length 3099
+1777 0 obj <<
+/Length 3335
/Filter /FlateDecode
>>
stream
-xÚ­ZÝsÜ6÷_±Ú™Já—HñÑMœ{=çÎöÝÌMÛy—v4Ù•6’6Žû×H€úØ·½Ôž±(@ø€Ì ~ù"×™¶Â.ŒUYÎx¾Xm/Øâ ÆÞ_p¢I#Q:¥úþþâÍ;i6³ZèÅýã„W‘±¢à‹ûõωÎD¶,yûáæÝõûß^.Jî¯?Ü,S‘³äÝõOWØz{ù\Þ.S^ä<yû·ËÞ_Ýâ&ß_ßü€=g˜Þ^½»º½ºy{µüõþÇ‹«ûa-Óõr&ýB>_üü+[¬aÙ?^°LÚ"_<à ˸µb±½P¹Ìr%eìÙ\Ü]ük`8 SOíß@ºe’åü‰å"³6W§Å²EZÈL+iÏóÂy xQ3Θ³Wy–çb<^!œgúüùj‘IÃõÂä9œ¹Æó½ñ;(m–kÅ=!gY.h(>,SÍ“{ø+’£ó
-
-_×ËTñ<é?V¶Z·qeçð¥yÄ'Ú¢oÙïà©,Lp¸ZNDpÅ2&´¥íhÛ%Lé\Ÿ6íR°díZš4Õ+W™áJÓœ®/{·uuòÖ#ÅꆺºýnüRÅêùEõ câëR²Ä­ý«—³H9˜¾
-hųMëIabU?i›<xõ^°½vžO¹ßôàŠRñä]Eœ‘àÄüUY#‡OW—ç&N*{¢l¶»jCT}µuÇ
-t;·ª_<s¿
-µG+ ‹BÒÉÚÓ¶…ý;
-S$MO^¡á‡VMí§<í[7R‚bÛ²^ã˦ª?»ìЈ•¶™(l±˜:зù¤÷þ܂Ѥ#®|bÌÝœÙàåüˆkNÎß#ˆs “à€càÌ\Ød_ÓiÌ
-«¸
-|NçòÀó`t‘i> G°!“}¬Pí%ê9‚ô¡Æ=X%ú”Ÿ‡ž­Ç¦¥®®£>Z¾Tõ0eÅýˆƒjfþ&F­gk%P5¨oä|Äò?²96|Üœc<´™.”‰hÈNᄹQìÄå ‚#6?6ûvDÆÍ Q˜ÿŸæP†€×Kq_W!Æ$†ö«|!m¼ý"*CÔÂü=6»Ðž« ÊAMÑgÝo^GÚeÑ \ć fèº#I#h¡R‰'rŸ>B¼˜Îâ‘Ò
-À„¿G¢óh‰â6ŸÇ"Ø"k!cyMö@t,|ŽD€ŒžI§¸)×ÙõôªÎ£‹A7º4ž?V«³9tñãt€z¼Lt‚€³®ê²}Áo”»¦«ú
-B¥/.zÄŸTŠp¢µ@¢&MÁçî8†6Ý“ðlj/´È“gç>a—f°éÍ
-º×aöox 7Ø»-_°±*÷Q–a¡@úyï誄ޞf`íÛßï®n—°Uÿyç«!—×?}‡sr<‘8yM¤„ܦézß²¸£öâ¨ôûݺuvŒ#··]8Vßö+ïöþÀ<mI½7wø w‰x
-Ë÷]—ðóæÛ1¸Äã
-•Iuè„åjåv=F¯¿Ÿw³ýÒY‘›‚®qâ’ɳàÈp
-‰8\z2„õÅÉÄe* ÅÙÚ¦Æò?Q'ÀGI}ÔüœÃMW˜3µ»Ò‰,8XÉÿŠÚ]w‚dQؘËü/«ÝEÆé”óqíÎÇÇZ*p,& ™c÷Þ+3`ÄÛÝ&ÍÕo**ûPZö|)gºŸßvDö^[&ÿL)çu‚}ÉŠÂØPOVpżfp{f‚öu0¨BlW=¥!½¬ú—4 ?¼›2^ºYL[¤:¡Çì4Á¿ ùŸëqç«~>1 7Ÿ‰á€1#¶AgÀ63€Ð*7ØG ¸Ø÷û!å5>Æp5’ 95ôÂÂ벟dÑ0^îûf Ù fÄ©aY!äAùtµ¿½•Nž\íZ
-áµìè‰⌠¥Hwx®_êr[­ðe¿ƒ¼ÞÑD½n=X; š3U2¾Ú
-ò€Àopšgʘhû4+Üý†>­çªÿ8ªÝ36 püûÕ—œ‡q¾çO|˜Z.†’ëIð6™•¢8—šuÈäɳcCøÍÿè2~?†[ò“3ŸN!­ÊTLH)üØwlö l²¹cÕÿ¿íîendstream
+xÚ½]sä¶íÝ¿bß*Ïœt")Šâ£sçK&¾Öv:ÓIó Ý¥mÍi¥=IkŸóë ¾Vk§s3µ‚ ‚
+ÇT?ܽÿ$ÔJG:åéêî~4WÅYÆVwÛß‚¿øçÝåÍyÈe¤Ñy(Ó8øáêú#b4~>|¾þtõã¯7ç* î®>_#úæòÓåÍåõ‡Ëóe’ÁxN3œðéêçK„~¼¹øå—‹›óßï~:»¼ë÷2Þ/‹…ÝÈ׳ß~W[ØöOgq$t&WÏЈ#¦5_íÎ)"™á1åÙíÙ¿ú G½nè’ü¤È"™qµ @ÎGd1ÀIºRRG©à ðç|g®+a[Iäe[#´©«®9gYP—­ÅÈ {4D´«U‡p}ß®ØQïÇëÛÛË?åe±Í»¢®pŠû¼(nVÓÒ\Ø¢5óÍ£Ùˆ8 î͸¯ðp¦]Q¡•>ˆ d,ÒRr·ŸÝa‡'ä8ƒ¯ˆñÛØÒ¶ÅF¾ß—…Ùb£«ñ»Î áø@Ѐ
+C£
+š²ó½å <ÛÝú•ºéÄ¥i[?2¯ÙŠŽ4)Žb J®Xi.Õ²åQ8¦ÂƒgK–ã©œ òoaåvêv0[žI%\ë××縉hžL£„11åàî\óÀŠˆË
+ôGÆÁÇúдÐfK'œñHÇ ÿß8gD¾É«ªîpómcÐ˨@‘¼òâƪ°°
+õ\”äWÖämÚ¢„ƒ/_È•4çYp
+Û·´¨þýÉFXW?¿Ã±kƒ3Nnvt9–!² ¬ÛÎB%Ú"{5¸1ÐâÙ ÍØssÓºcµ°Ýy{°fisÂ^ßâ×]*¶ãÁmߢ.àïý¸… ^‹g„k"S
+¿”̤<Ñ
+2¹T¬Æ"ý¾SL©!u ‡Œóût(wa;­¹(%^ @† 2êvÚ›õT.Ä+B—hÝKèÜ?´ŽÎ_ÉHe_8ölžjÉY»*… sÂÈíÞl
+›£¸»Où€@©Á»Òy7Õ‚€žkÄÑ
+¦d“‚÷
+¶¤_Ä÷úÅÀÛ'IüÆãÙ˜ê´~õTsýê^öæøùLC*§¯sÐS-°0Ùmš@¢Ã§, ª¥ñU>û¦xBM€ÆÍG|½vVD9V²JK|[€6½CD§EÏ]%ÁC«b®d^µU"†BµLlMäTú”$°Qðát¾ë¹ ®°Ð×Ëè¹
+´GĉœFWv1FEq&íMi":ãÄ›•ƒ<Å>oòÁX›ù‚7
+øL2xè¶UD¼Ÿ™­ÉoŒ_ÐŒ©põ~’¶ƒ»#PZÅžàiu d¡Þ(©^QwOÕŒÍ=¸ÐÇÐïðèì{ÍÚQwÍË1­G%噶ohÙë[è©ö0IÊ5¤"áÓMÜá«(åÖ-6F¿t@„»ñ-àßqÀ€þFá>Ï`jW!+ôÚ<æO… Ñ„Ü) ÿX{ï½=ZŒÀ‡]ø#øóõ`C…æ…¨Šø€£I
+Hà†D=À¬¥uÙ
+,Ðv‡5¢,S--OÝ`-e¾ÛŸú}–‘ýQÕ‚“‰ûØâ»»5ü°-Qdü„·²Ï>\+Ï”½RsÎûy³þ'oPÑÂendstream
endobj
-1385 0 obj <<
+1776 0 obj <<
/Type /Page
-/Contents 1386 0 R
-/Resources 1384 0 R
+/Contents 1777 0 R
+/Resources 1775 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1356 0 R
-/Annots [ 1389 0 R ]
+/Parent 1747 0 R
+/Annots [ 1779 0 R ]
>> endobj
-1389 0 obj <<
+1779 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [289.8576 239.4581 338.5646 251.5177]
+/Rect [315.1789 427.0782 363.5077 439.1379]
/Subtype /Link
/A << /S /GoTo /D (dynamic_update) >>
>> endobj
-1387 0 obj <<
-/D [1385 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-410 0 obj <<
-/D [1385 0 R /XYZ 56.6929 661.3973 null]
->> endobj
-1388 0 obj <<
-/D [1385 0 R /XYZ 56.6929 635.5371 null]
+1778 0 obj <<
+/D [1776 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1384 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F62 1062 0 R /F63 1065 0 R /F21 714 0 R /F41 939 0 R /F48 953 0 R >>
-/XObject << /Im2 1051 0 R >>
+1775 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R /F48 1228 0 R /F62 1352 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1392 0 obj <<
-/Length 3978
-/Filter /FlateDecode
->>
-stream
-xÚ¥ksã¶ñ»…¿Už91xò1ÓéÌ%çK¯m.©ÏéL'ÉZ¤dö(R'Rö9¿¾»ØDR”œNçƧ°
-,˜Í‹GX3gªÐeÚ¨ñ!@#;`3ܶE»ëA5VmÓ“µ¬©£d´®Ü?¡ÀýùSGÊ¥RX:MÕXŸÊÇü©jQW´^8)Ã/ víÍ<]èÏé‡-¨6‹_…_7rQî_ È/÷éÇ·¬ófSv€-y£ýp£>LÖ‹u^ÕN1î÷yÓ­Aýàfja?w¸!5
-Ú ëÔ…Du¼=Ãe©óínNê½AH³8á–‹eÜBaÔqËɸÅÚâ\¨Ç;ôÈ¿
-¡JžKú}F7' œµÁi°±÷Œ æ»]à y¿¡©–ÚF&•)»¿©‘žñ—à àöñ’‚¶éÀ{7°ðtÑÑùú-&n Q›’<A™©É6dHµµQb¦Á'ZBÃaeY~v¶nŽ,aúøáɇ¾eBTœEƤžQ ròòç?Ý)Ì‘Ç'^l²S^VÄ]*‘œݨU“ƒžõëVšH
-Ý{ ¨ó¹B/^SãwèÀÿ7½óí¸yñŸC‡ç) R4w)äc8nØfÍù·u*­ä Í+@ß¡;ä5tμsQ´Éˆ
-± Mf QH
-cƒ¯0‚´e4£ß´$Êl‘Z$l;‹„À‹¤’(M@yĬ6N ’‰¬MìÀ"áê9ýŒ,vøãpº¿~Š³HNá"l‘FhÎö8™BtOÒÑ‘EBÿ5´HJ˜S‹„H\At².-Î F½EÍ1ÞOë1òqù£ ä¡ šq:ç-pë‰UªHôÛån ÐÌiÛz¥Œà;çÎ à ŽÕftÂç(ƒ õG½Vð¼×ºîiGVëì²Qb7ª‹Ôsg~].álÉGŒlk¬£Xéô2k†ŠqÙÒ¢‘ñ)¤IN¯¹Š€
-¿ð—¤í2øauÓ Ávd¶$wœ–Ã}Α¿x¸Ô,ÞW$}\·¡ß–Ê’ît´3!§ÕÞéDůœ4‰B\zt•HêË®Z¹‡k–_—>¯£8=¼É-…js•÷„+ïI¨²Ó°¥ŠWêq'9¿ƒŸŒâ‡åªÝî€îvœ!³‘z§¶Fã™êÅÇÖ½$áA) Åÿ„^‹ ƒ {Ðá/'öVc¤¢
-9Ôô>‚N#›™l¬þb«DŸ“ \°,É+¢FkíSmgÿaÅºÍ ¬9ÎÔ ÀKC)ãlä¥ñEÇÿB˶ۊ9ÔµÛ’ûÖþÌ•Õc¹úÌt°â;ž¶Xp­Yü<{Wî‘^+0(!—‹(QÉ$JÃÜLE`8Õåë4ÃA¥2”-ÎsPã¹pnøWßåà*W‡:ç’ë)[3é£Áp,X"s»9(ÁyélˆÛÑ>EK§jÚž:¨ôåÀµ¯)ÎU*‰yš¿ûüyî¨"Ò:™;© !èê&pe“*q™»:¥¥Â½UáéSå°“‡Õçˆ6Jc“½F¤±ÂŽ¨¤E·˜¾»Íx»¡Õ€¦„õe èêò-CŽÑÖåSYbÞy‚ý.Ãú%é¢Ó;)Ò‘æé3
--¦Íâׯ™‘6hBÛඛÃ>'ŠËsCé¸âb1x¾ÜRxg\u¼»DŽLñ9P x³!ÐLSÄuáÚ3UYÆgz×ÀŠs΄?ð˧V„¥‡ˆ¯ûª(œ™Õ ?¥ô(”Ž
-팰¸z»yÈ;*¥ä4 «jVõ¡àg \tF>6‰ {RÿC Ե‹k(Øu¯âcÌ a v:&‘ã«uÆa)‰$hÙÅ©T%Ü&민cÉì:±
-ŽÏ'(.G˜¤§úgEп3Q:–‡2 fçb”>Ä:¥,wê
-_”–^à_åþeðŠ:;>¥RÅÀ‚^&3`ÍÐ9Ž‚¸0Ü#BýsŽˆù½NX_TÇU_¹š )/öc¬Î/Xü)ü« Œ†W,lðç0ì‚8™„Îc5”R¸Ã¾£$Î@·óæMÙøŽ0ßh˜_W3Øú…€ Lm$Ž†r,©–]"Ðg›„2Οç^¢äøäðíà›/øzÿæ˪æü}²h
-Æ6Ê_έ™ rH®"“×þ™Tž?áà®CÉ€‡Á‡ñqMpµ*w΀!)×í±D˜-
-ªìvüýØ”¢¨ð’8ÙÚÀÖÙ*8Q|´½|CÍŸ4áN=X"Œ+å_†ë5Aý¡a"¹,nCvãfÓ^æŸÍ}H* k’“"˜ß“ëçøÜn6Xëç*ÃÜWK¡JoŸ¬*Åä Q
-1ÿHŸ{Äl
-{&øáëÙÿûcïã—ð’?ü:n¾n*â(U®béˆr_vÊ)åC«T%3¤ÿšY$Vendstream
+1782 0 obj <<
+/Length 3921
+/Filter /FlateDecode
+>>
+stream
+xÚ¥ksÛ6ò»…?Ê3‹'s77“¦I››kÚKÜûÒö-B6/©ŠT÷×ß.v‘e·sO„Çb±Xì”×þÉk›&i¡Šë¬0‰Ò^ovWâúæ¾»’ ³@ë1Ô7·W_¿ÕÙu‘©J¯o·#\y"ò\^ßV¿¬ÒD%7€A¬^ÿøþí»ï~þðê&3«Ûw?¾¿Y++Voßýë µ¾ûðê‡^}¸YËÜÊÕëï_ýtûæM¥Œã›wï¿¥‘‚~. ýðæí›oÞ¿~sóÛí?¯ÞÜƳŒÏ+…ƃü~õËo⺂cÿóJ$ºÈíõ#tD"‹B]ﮌՉ5Z‡‘æêãÕ¿#ÂѬ_ºÈ?)¥SµÀ@¥F Ìeb‹Â^g¶HR­´gàðàèL|EÃÌWnK?ý –m5žOÔêë¹ÙñoÀØïݦþUåxíç²9º>A¦åp‰ÉÒ“q‹‹´ÈVÛ®iºÇº½ÇnºªÜ¶<6CO“å~ß<ÝH)W œOŽÎ'µML. À(wu»>À9à k$“WL8"«ŒäZÚ¦w›®­ú¯ö°y’ZkÂå—· ¬*l›j¶gÇZ[›dF`‹L
+k•‡ÿUXaˆyÎ}ê¡/—È2i’ c&'‡;ºDTZ$Æä9ƒ[$È_X8w¼òó2ØÉœxìðÌN™H„H3—Jél7êàAÕì É™vÉ$“2òó$KÁ,k­ÇP¤ rÁšD(¤ÏUm¿>Vûu_ÿáæ»ñIžÉâùí#ÔÂþcÆHe“Üj5%à£CQWB±A£¬>»ÃP÷^‰ ÿæÛ÷©õó·?Qãî¸E­ÜºöõÊSïgê–!žwô ̼2wÍlÇÓònK÷åæS¤Œ,ÀÆÕŸ]Eº¼6&QŒõDvÿsS
+¼c×–ÍɼÒCéŒR±¹£¡ œÃÂE
+ý{׺CÉÓÛ3؃[,liðU™‡>ëM·Û?¼vœ¡
+;¡’î ʧÍïx»±Ù€îc=<
+M¦-Ò—õÌH%¡kqÛ{ˆ´È‰"zb®¿¥<©0 ncp;
+M±KÁñErd®A>£¸-”êOµj–?¸B%ÀÇ ì#S²)™ð;Çò‚Èg® ƒðïPW•·³:[ùÓêÜËüìɆ®YÆà0ù\»Gš¹+{Ϙô^†êvÓ+
+z=Ò…û±dë©úk 0ÝŠp]ã+€MQöj>Æò%¬ÁP'Âd³Êá¥L"²(Adç·*A›âã‹gÉ"žTEÏ’+ŸßÌ"ósù³"Êß…0Ÿià†ŸÒG@—ƒô
+. úIÄD=Tðw0¹;î0L¥yzM„Y¬ ùÂvÚãîÎE‡¨à®³™UöÎW‡rÝæxàœÆ²ÞÂݲuݱ§‘ ¸_âõI¡¡Q¶OÔ¸‡Õ-5‰£¾yJZåDƒ@˜m&ƒ`ý}é±+ÉL¬|üŽFð«ß!d„ÿ7 fHs°´i OþñNæ .‚ùÖß
+‰ÊâZ(­Tà—ÌØŽy ¿$é’žà'È94ÛrLòƒ:NñÎCùÉ1¹þ."}}×|^,Œ‡¨Bú</ÕêÝ–†ØðÊ è£"“ÉJ__§GŽJ8žeKÁ(ªfžG›ÿ\ôQħø
+SÝiÃD=3¬g:Mƒû0ÜŸÕÁ„ù¼hçØê|ÄÔU,ØÒ(Y…½ÂM`ÕèåàÏòX
+ƒ_@xlTN<6Š¾+ÀM¦‚è©|ÌcìmGë{Ï(ºëŽÈlré‰Ö—-Ö»}çëãøi)*–Ò‚?R³×¤Cg¡—bmó"°‹1ªL}œœ>¤Ž¡.G©ŠßuëíÓºrMùtþ¸¨[€v<»{„ZØ~r¡2ƒ` réÉþä”3üP)ÀïÀP]rNótüSŽU—áѹ8ÕrŠ”e!„ÕsR>ñs$? “7…á’~ÐxûbZ1&(D Љ•›Ù¼6ŠùEx.ÁHÓrLwú j)¬‚ 3)DŠ¹4t®ãÇ2…¿›5Äbõͱn†uÈsb<èsJòbšãsÙ=Uø!šÈG‚ù ¾šRu¶û\WŽßz©<†­×ì·Ç†
+?‹óg¾œú¡ÅT)§Æ
endobj
-1391 0 obj <<
+1781 0 obj <<
/Type /Page
-/Contents 1392 0 R
-/Resources 1390 0 R
+/Contents 1782 0 R
+/Resources 1780 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
-/Annots [ 1394 0 R ]
+/Parent 1787 0 R
+/Annots [ 1784 0 R 1786 0 R ]
>> endobj
-1394 0 obj <<
+1784 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [353.2799 352.7282 410.176 364.7879]
+/Rect [324.9335 477.5927 381.8296 489.6523]
/Subtype /Link
/A << /S /GoTo /D (zonefile_format) >>
>> endobj
-1393 0 obj <<
-/D [1391 0 R /XYZ 85.0394 794.5015 null]
+1786 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [55.6967 61.5153 116.59 73.5749]
+/Subtype /Link
+/A << /S /GoTo /D (view_statement_grammar) >>
>> endobj
-1390 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F11 1397 0 R >>
+1783 0 obj <<
+/D [1781 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+526 0 obj <<
+/D [1781 0 R /XYZ 56.6929 131.3071 null]
+>> endobj
+1785 0 obj <<
+/D [1781 0 R /XYZ 56.6929 107.529 null]
+>> endobj
+1780 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R /F11 1442 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1402 0 obj <<
-/Length 3086
+1792 0 obj <<
+/Length 2818
/Filter /FlateDecode
>>
stream
-xÚ­Z_sã¶÷§Ð[陈%þ’hžœ³/U¦ñ]mµ“išZ¤-NhR);î§ï.  š’ÜIÇç°XìbØ Ù,6S:Ö†›Yjd¬¦f«ç‹dö}ß_0Ç3÷Lóë»åÅŸ?‹tfb£¹ž-YYœd›-‹Ÿ#óø$$ѧ/·Ÿßÿãîê2•ÑrñåörÎU}^üí†jßß]ýøãÕÝåœeŠEŸþzõuysG]ÚÉønq{MCÅ¡w7Ÿoînn?Ý\þ²üáâf9ØÚˆüvñó/ɬ
-Ÿ€*˜¶’ÇE¶&2m¶—,‹Ú—ª@ÙÞöÙñ­Ëz󸫉±¨ò§¦íújE³@B¿&Q»§5ȉÞìž¼6\ ¤= Æa‹æovM¼èñäÐÕ½¼H£MWîŠvÞ·›y]¾”õ¼hŸsdÍ—¡Ÿ™à±Vi¢PÂCÕNâiÌS&“hAuïWŽ›˜~+ Í—û 2‰M–y®UwBQÊq:g…7YdQnÝæ­Ë·=Õ¬«°›šÇ õR•¯ÔÛ®+Ëc ¥¥ˆS-,|PßöiF•»)¸ùßGò;©há}¹r[‘»‹¹x'
-øCñxâ¸ÎÌâ½4ŠEz0‹PZ×O¬¢0±H3}f+c\:®×uµZ“ت£²+a±òß'Ñ#mþgê³»+{,­Ú0EulŠ<Éb {×i_ÜNLЗ¥’;–oÅ´è°Dôä:Ê›7bxªÛ‡¼ö˜–Å©`©4:~¨1`Ï—¶£F·³.0
-’LûØ눎g´-é¾. ’é1t+8NVëª xé¼ YühÜ}”Kcfó ’­Lzæ±…«¸T¦ö4åÒã(žÊÞO Óo—yÇã®±¹0˜ø% Øl«çÜnl춛Öf2Òa4]n%3…D®\iÓè„$¢qW[ ú¤”ä\š(•Ã½óxr³ 5­N(!'\å]O ò ªK2R‹«~çó›çï^an?  ×–jp@6uà`oñŒ«Ñ'9ˆpßN9æ«ÌÃû€l”Ã'2IWïÿ‚wRJ8·åi¸ ˜Ž£g
-Òk˜Þ¼*Þå:6 òSª=Ï{Õ|œCý˜¥ÑâšÊÞ”úG¹l„rî8û3ô¬Êꅜѓ
-·´žP»¤.ìÎÅtÔS0tnï×.|€B˜é_‚ %Ï$Ù®5Obnöíq´ÌÐë3n…‘ph9óع¸Žïoîþys7uMQ°€ú0ÙAÁÇ’Ó!ÿ¸¢¸£yMŠ{ûcàª÷àŠ"—äƒd=H°{È]ÌaR<ö·µŒ¹4£ÌBv ¤¡Ü#¶"aÕÂ4”9ôz ÂÆ€AV°+÷Düa“0k{ ’ú ^–
-ž[¡u÷ù ã,scìjïûT$ÜUè
-”ª¾ls¶©ð Ž¢„¼nk¿í¿ .u~€a ¾€:#zç윊rùÎbûЯŒU…<ªœtþÒ/Þj·% RW]x9érû êþrìÃT#5ìô_„\ö®§^V±X È¢ï9pŽ”¦ ÁEð¤RÏô^éáó œåƨC¥I¼¸_]_ßÅWw_ñÿê¨Ý)äæJŸùë‡ë„Ýžë¬Ý§”îí+¶;TÊà¦ñaËU7JaÎXp°Üsµü”Ò½åc¥Ó–‡J¹‚ÄO›[o¿ 2qÆú€ë„õžë¬õ§”î­+¶>TÊcü þqë!føqû´õ× ë=×YëO)Ý[?V:m}¨_Ž!Ge&û¸+¼(v@Àužë¬N)Ý;`¬tÚ¡RØ°x">l?Üú´ùÓqë=Ó9ãOilkœ4=ÔÈ•ŠÃßÚ¯U,ø™Õßó·Þñœ3þ„ºÁö‘ºIÓuIüÇ~_õY/á}VL¢üºÔóÿÝÞápYƧ]ÀS|Ý!nRöŽÍß¿ùBÍ'¦þ_å/*endstream
+xÚ½]oã¸ñ=¿"ou€3ËO‰jŸ²›äêC7»MÒâÐÛ{Ple#¬#û,ysé¯ï ‡”)E–²¸¢’£á|q¾ÈDœrø§Ö0®2}šfš.Ìéòé„Ÿ~o?ž3HóëÝÝÉŸ¯Tzš±,‘ÉéÝCDË2n­8½[ý2{ÿ·óOw—7gsiø,ags“ðÙ»ÅõA2Þ¼¾ZüøÏ›ó³TÏî¯ |syuysyýþòl.¬°_z
+G6\-þ~I³oÎ?|8¿9ûõ˻V—X_Á*òÛÉ/¿òÓ¨ýÓ g*³æôœ‰,“§O'Ú(f´R²>¹=ùGK0úê¶ÙÏ(ËŒ•é€¥2 ÉX¢¤r¬‹Ý·bJev¶Ù6妪iQï—8Kgyj1\0+­L¾^ožç¿í‹Ý‹GŽ9Ë·™Ç]mˆCµih’o·ëâÕ<ƒIí§ÿÙTE ¶˜-ö²ÙÓä¡(Öí¢QÅʃ<§UYç÷ëeòt.0ºJÁrB°Ìéäsü~8›«ÄÎö(„Òš¨ã¤5’Òfv_€Úg™œ9ôt¶Ùü±\õ÷ÝïËu3/«[J©YªD°%øôÇÛ+jÁ¸IÖ·²xö”_ˆéªø̹¬Êê ÁóŠÆâ÷íº\– ­Â>3Û<d¹Îë¡#žËÄ°ÔfI×<GÅ[ŠLyñšÇ¼¡PyÊ›%˜œà'4Y®Ë¢jàXûÄAIî”&u¢†3†GšÇXäðbÈá–³[±«á
+­`:MB]  C°7y'‘ÉpΕ…h²FuÃéMÑ{ÍÑÀSœe’«ï< yG!b“y5Á±L»Ñ…žÁ.Ÿ T”åcYE¸Tòb”°ûpž¥N<×2mu×2›}…G­SWP¥Y
+TOÌ,¼›×ÜÙ©L1®y¯LüO²Áª˜@ˆŽf»ëx¶k±¢&$œ—«×)ZèßÇÙ·Xü»I3©2Ó€Ó¦³ÅM
+ÓÐM¦‘”©‘ãRJÎÔÖÎ!C4¿•Yë¶ë5mYæûúH› ´¢{ÖH}¨Ž*:ø°ó„LûKr¦‚¶:.à
+Q§Á &ß=ù:û‚FÊ ŽüŠ ëÍ2 ’¡¡Ê’¨ëÊ¢>æþUê@¼†4G3zN2á¥)™-ª¦ØUEó'O‡A à“&&hØÐq:6H°«ã²Ä»¦T*jÍ”neørCEU©öy ¦2õ6_~Ù¡Ùï*ú~ýóÅÇç‹kZÑ×z»©jÚ H-¥cš‡l¥¸5 a›ïšr9:—ý:w7^,ßV¶¤RÓ
+»Á„„@= Õ— yÂóÕÊ LÒèŒüD«›«÷´Ê™õ{Üi¾™™RÐÑm
+L­Šh¡ÔŸ9ÔÀþ-‰Cë‘@eåÚb½fÛmÅ9ÌuÒeËÙâz~~qqÃÎo>á£þùQÍye;±šGX#š¬iÍǸFš÷Ùk³pÝx«îp+ƒ{屇ù {Œu\÷kR÷Q®Ý_±Ô½ÃVèÿ’ìíú.‡örBÿkDÿ€5­ÿ×Hÿ>Ûaýc¶’áåÛõ7ò‹ÑúGX#ú¬iýǸFú÷Ùë³…VZ{0}» Oü1;B1€GšÖ„e¤~ç°öOWMÎ$Wo×vh dÆ•°F´XÓêqôï³6@ÌV|W;ü¾Õ"sLŸb¬ãvh±&í0Êõ`‡WlíÐaËÙûY|J¦m–&Lk•NØ,±YÀš¶Ù×Èf}¶Ã6‹ÙŠÿ‡ÍLÊ2Ù ›EX#6 XÓ6ãÙ¬ÏvØf1[ËÞ± ,9Îòm6PÓ\N´[1Öˆ Ö´ ƸF6賶AÌö‚]¡¾oÓ]rf­œh·b¬ÝÖ´îc\#Ýûl‡uÙZvù=ÚsÉT"&š­kDû€5­ý×Hû>Ûaíc¶Ùwio³ZLtZÒqÝÒ¤êc,š÷y*ó<ÿ.½Ôœ¨¬œãZ{œI¥Gøtî1T9bøî»4V†á?ù H
+"rX¼Z™¥A(Ô&Íú’·ÿtøZôÿÃóîendstream
endobj
-1401 0 obj <<
+1791 0 obj <<
/Type /Page
-/Contents 1402 0 R
-/Resources 1400 0 R
+/Contents 1792 0 R
+/Resources 1790 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
-/Annots [ 1405 0 R ]
+/Parent 1787 0 R
>> endobj
-1405 0 obj <<
-/Type /Annot
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [55.6967 639.9582 116.59 652.0178]
-/Subtype /Link
-/A << /S /GoTo /D (view_statement_grammar) >>
+1793 0 obj <<
+/D [1791 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1403 0 obj <<
-/D [1401 0 R /XYZ 56.6929 794.5015 null]
+530 0 obj <<
+/D [1791 0 R /XYZ 85.0394 496.0455 null]
>> endobj
-414 0 obj <<
-/D [1401 0 R /XYZ 56.6929 710.1097 null]
+1794 0 obj <<
+/D [1791 0 R /XYZ 85.0394 467.7701 null]
>> endobj
-1404 0 obj <<
-/D [1401 0 R /XYZ 56.6929 686.1175 null]
+1790 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R /F14 956 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-418 0 obj <<
-/D [1401 0 R /XYZ 56.6929 367.6759 null]
+1797 0 obj <<
+/Length 3233
+/Filter /FlateDecode
+>>
+stream
+xÚ¥]sÛ6òÝ¿BÓ—£f"” ’¸{J§u§uîßô¡íEQ6ç(R);]ì‚%Êé]&3¸X,‹ý†å"„r¡‘˜È,R J½(vWáâæ~¸’Œ³rH+ë»û«oß«ta„I¢dq¿õhe"Ì2¹¸ßü$"K ß¸}óÿïÞ.Ó8¸¿ùp»\E: Þßü|M£îÞþòËÛ»åJfZßÿøöŸ÷×w4•0ïnnßÄÐÏ¢w×ï¯ï®o¿¿^þqÿÓÕõýpÿ¼2TxOW¿ý.6p쟮B¡L¦Ïð
+iL´Ø]ÅZ +å õÕÇ« ½Y»tV~2‘J¢FÑœ
+xŸö©<ªÍì‰ ¨æx
+ø¨«®gð–~=^áË2ø†Æ/í‘EÞLpécØ€dÖö#åý "ÙÀñ6Ûö@ƒòs¾Û×åßñ4ß¾¥§¨©©ÅV¡HCðx@ffeÅ»¢m“0 ¾ßüƒHLt}5¥‘Y7(“ðQðq\Ê «šú¢c ÎfCXV-pÈ›‡’ÇÞ‰ÝÀ©Ë¼¾tÜ©{l5ãä5áäÔ£ƒÇü‰7£  Ù1À©ÛkÂߌxÜâ:¥câÇ®­J"Ü4Ùò¢¯Š’¾úÇŠ—€©–ù?ÐXñ·Á;ÇÁÚâ³ê" È;=Wý#vyóB£OG`Û1³.í cSú;èó3‘¯ší!ïúÃ2 ŽEî,…û*(,ú Õ‚A“ïJ†U ýéέÙÃEçEÙ¡‰¥*øØœ8ömA:nyΣ./Ö‹*¯g˜x.}þš²ÜXÕ@íÜ…­ÙZ6å¾n_œaZ‰¶ø˜7õ©¾e¡D_Ø´Úœ—äÏ9Ã<·æ¯º$F˜âˆKá, ¡ô_Œg2Æèx>žÁé3ˆh)ØûEZ´.Z<¤§¤Æ¼AG‘HS€^Ød¼]$‘P©LÚ(!Iê·žËÐ 0hEµŠ€o‹ñ,E‚û{ ÎÂ<P Ó(]è8&Kpßŧ…alŒ"ol:
+À¾½ÙE‹w-gáÈÑ]y„íß·AþH°{’
+#3:ѽ½æ4 %é¥ öù¡lz‚ £G
+ž–„(RÖ,Ø.DVcFÉ‚?—6r—Œ68/À²~x¡S§É¼®ià ¹õ4ql6冼ÖÀi¦ýµ¹Øì…¾¦§@D´á$ÞÉ\H…‹G°ÎH€ €†¦,eÿ‡Hî—ΖÛB&ŽUݯ¬oÈÆ0ïqÜC3ìž(ƒ
+ÛǺ,ìëB¥w&ìDd²¶Wy°f˜˜
+[Š,…È3áâÝ X…Á¦zª6G›NÀ÷PãËQ¾aLò˜'_Û&h˜Œ×=C%n×*—"¨+x09(âé“ÊqX°¦Ôi•†"Jµ™fÓþ\ߨöCõ^íJJïOn
+9ë×Dzè‰Aì‘åÅ#uçE8dAPQ,†UÅ‹ÔœŠcˆrL' gËçsË®%”tŽv~
+FhìQŒ¶…*ˆˆIé“\f0“§‹ü$ éü$¤j¬Œ€ MЉÿt­×¼Ïg•óCÃo3íú©jÝøܳycÏÜôœ¤
+…‰#õ¢P¤ÂÈB*q–ˆ/QüKwõéX±["èîhc%ŽÚ1»Äßü Eö®’ñ­É‹mðe9ãg©Q+™(!Óñr\Ÿñˆ/F
+’|#SIèÞÎbLM­3Šva@pk½µû„C#Î:þ¥;îö¬” ÅM‹doi ‡· À÷U1¾¹ôR6s[‰ÐFFá²-kLl‡­péÒš[nÞ[|­¹7zÙHÈì³ØL™ðêÍ^’DÄa¬^õ"RÄI¨_õ"Xó$ŽŠ ½á®1u- çáÙ·]W­‡žeËg^B :;µîã~ïR•ºÚU'F>è­>¹÷ÉÛaîYïúÅuæ¥Ay§±„æKË?¯X²]õçœ\S%B¥ÓA"t¨“tbÔåtÊKB(ÚÌ°•‹¬Š¢/|惘ì3öâ?¿H7“ŒDSÆD°iÂd³Œfò¢Ÿ¤HÚqÇÉɯK .¿\Í>™ûYiª²ÿµÔ:'ù¹L\ü+^Šº*æèdBÃ9ÍÏBC>
+~lŸñÿ¦Ä–ÉIlóIûŠ3˜i~¶Þ_;Å
+¦µ36odr5—·œ?G%£RÇe‘QAGýJs¦Á&vE¨¡'füý­pdµé‹¢,m ì–ùa§ã ö@—MÍ÷1ù™‘ŸxpÇnö ¨Òÿ
+g¦ÏO_ýÇ>ã‹&$X*Ë¢ù†8Yg@„™Â+ÈÂó>ÿUÐ9ëÿ ù«_endstream
+endobj
+1796 0 obj <<
+/Type /Page
+/Contents 1797 0 R
+/Resources 1795 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1787 0 R
>> endobj
-1406 0 obj <<
-/D [1401 0 R /XYZ 56.6929 339.2505 null]
+1798 0 obj <<
+/D [1796 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1400 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F14 740 0 R >>
+534 0 obj <<
+/D [1796 0 R /XYZ 56.6929 349.7668 null]
+>> endobj
+1271 0 obj <<
+/D [1796 0 R /XYZ 56.6929 323.7864 null]
+>> endobj
+1795 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F41 1208 0 R /F62 1352 0 R /F21 930 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1410 0 obj <<
-/Length 2656
+1801 0 obj <<
+/Length 3598
/Filter /FlateDecode
>>
stream
-xÚ¥]sÛ¸ñÝ¿Bs/¥f"„ @lŸœØN}ÓsRÇ>\˜3©ˆ”}¾_ß],@‚%%Ídæ´\,°ØÅ~øø,„|¦bŠLÎÒL²8äñ¬X_„³¯°öá‚[š…#ZøTï.ÞÞˆt–±,‰’ÙÃÊ;K±P)>{Xþ¼ÿç姇ëûù"ŠÃ aóEœ„Á»Û»+ÂdôóþãÝÍí‡ÿÜ_ÎS<Ü~¼#ôýõÍõýõÝûëù‚«˜ÃþÈžpdÃÍí¿® úpùÛo—÷ó?~½¸~èuñõå¡@E¾]üþG8[‚Ú¿^„Ld*ž½ÀGÈx–E³õ…Œ‹¥S]|¾øw ·j¶NÙ¯§YÉTgœ¶rœ±DD¢·2—ž•3
-t'ÛEßgƒhc~ÆÑ X¢ó8ÁÒÓç´úÏ+vƒš~ŸÖ!Ø' ŵ=ªz;ªóŠŸâêi¾ÏvZuŸ­b×? }¢B&“,=­½Ou\ûžê¬ö'¹Ú°Ô~Ä6û1í“%ivÆå}ªÚ;ªóÚŸâêi¿ÏvZ{Ÿíåi/C¦”’g´÷¨Nhï¨ÎkŠ«§ý>Ûií}¶ïŽj?[Dpn˜$À!c)@fÃõzÓ½B"çqðWSëAäÛ9W&|«».¬ìWÞI÷dÏ¥~!¨ÒϺ²ÔKÂ5ueÏ7ao3lm-ÝŠ–Š*o-êöŽpU¶ÈIzB⸗5 AEβ8ŽŒŠVeý¤·egNI°2{š5-6›®lê––Ê!AËÞ€ìkuCÈå `x°àÄl»ÑEù% #ÇÛ˜‘šQX3‚ê"Œƒ¼?˧yÖÛm¹ÜÓ‘¼žŽjlÐ>ª²í,zE¿ž¬ðe|Cðk³# Èë-}ô ÈfM7œ@PÞíZ…P TȲY5[ôŸùzSé¿£6oo$÷<;å, ~eœ­0 cÞ±MÂ0ø…ýò:b‹ñÊœq‹FÈ«jæ_g»¶¬¿žt@‚å’HŒOb›×_µ… ¼³º$„ó•7xwéÀ¦}jv•¥É+¢É—¯Äö)¶ÌhÎl-Âùã5’o <iqŸˆ%É€À®ÕàRI$‚Ûš0›m^te¡é«{*íˆSoíF*þÖxá<zë·ˆ(òÖB/e÷DÐ:¯_ ú¶±0Úh@Kísˆu¢à-ëÕ6o»í\»¢Ûõ–rx—¶h,ú ¿ Î×ÚâÊš~áèÖíÙÌyºÅøJEð¹!<IìoZuÜöÜBm^lMe^Mñ¢}ùj­—Æ5ðŒfJ¹G*K½©šW•æuÄ@|ÊëÚ<¨~X¡E_m\5¹Ý’¿äç½iþ®cf„%«;–"e"Y¢2õ]X–Årºƒíôg©ŒŽŸEûB8Ë‚nÇø¨!7 Åçñ¨1èm É9d)WØ=ro eÉ;ïňx{L:e±ˆ@rCñb…Ãë \ï[ΔD“aÊD›ü<û6ƒ>Cf™ "6º60ˆ··ëhvÕ€F3O)wðÂ?Ù(•Œ2”²m"#èÓã”2ùƒ¹ëT[MΙ›|«ëŽ°pÍø,Ïó’y¬
-Vs@QèdCœ¨à¯¹ÉÝÚ’õ/P™—xá³N‹yUàR¹ý´°«—zKà‘0ï%U±¿WÑ»
-W ˆ;xèQ ‰§OjÇaÃ#N‹ÄMã½×w<_€ë[ƒ
-<êBD4AÄ¿þð„q5_ðšìËå²Ä±Bnýë³.:ÿ¢”OØ×6áPA¥š¤¡W 
-cŸÚ'¤„gÃÅŽ3t‚•eÛI¾ ª*À•d<RÂÖí¹Ù>!K9+…G•Èìù¦åEjâRÖÞZ±¬$´`šT@•ë õWÏV•ÎQØÆ{ÓÔ­]‚JlEïèÂÎ߸da•üèæ ó,4ÍfH£ú?Ú&CïÈTð_z!a mîÑ߆
-óáŽÂÞ†YAÊ–@ζÐõ8ÐË¡Ó‘¹=s0‹a÷Ôl»E±ë&çPX‰F©Í5
+xÚ­Z[wÛ6~÷¯ÐÙ—ÊçD@€ Øì席Óu7I»Ž»ûÐö)›ŠTEʲ»gÿûÎ`
+”(;mb?àB\ƒ¹|3˜pø3.S5IRÅb.âÉbuÆ'·ðíÛ3áÆÌü Y8ê«›³—¯e2IYª#=¹YkÆ“›ü§é׿øáæòú|Å|ªÙù,Ö|úÕÕ»o¨'¥âëïß½¾úöÇë‹óDMo®¾GÝ×—¯/¯/ß}}y>&0?r+œ˜ðúêÍ%Õ¾½¾xûöâúü—›ïÎ.oú³„ç\âA~=ûé>ÉáØßq&SOvÐàL¤i4Y©X²XIé{ª³÷gÿì ¾Ú©cü‹¥a±‰’FbŒqÊ´Œ¤eàfÓݬÙäÅS¢`Š2L(c`‹Ìáéôæ®8ŸI¡§Åò\˜é²XtØN¦Í’ú»»²¥žö®ÙV9õÎݬUY7äë hK9½kvÅ}ö´e½(h¬¦I××@&UËš>užŒ,ÏË®lꬢv AÓz\Ïð`“™?ËL–ÆqdT.²ªz„¡ȯ}mÑÔ]VÖ-µ2*Ú ¥j½]Íbšµ¤(¤ÊÏ<æYSà å*«ýÚY[¸‘e÷q—õmUø]`yñb¸øî®\ÜÙCòáép/’WË,¬
+° :f°ûÕr„o):ÖŽpÕÇ,Š¥Jz–½p×h•½G¯UØÀc]8:g¨x|/y±Ì¶•“¬û¬Úý´‘[Ö‚¡RGKÝŒ‘+ÔÔ³7ÇLƒ¾?}ÃûAOÜ°Üð¢*²80+kÐ8ÕÑe§1¨ŠÔO’Ñ:¦c ÒœÃG`JHñ7Jáb6÷VY¡¾+ÑDa”jÕÜûQ]†6$’ty®·¨»MY´xå`wç`.rú`/ÊÌ•o®¤ÉÁ˜¬ºm6ew·zA6å,‘&š 4í£Í Wñ@›Ç¹ztû3‘ð3Á›l»¢¡‹Rçš"ð{¡`:5§öpÎÕ’¾ZƒŸÁüØŽl‰
+¡m¯Áh6y¹ QžV:»)
+¥?;飻 ´w‹ÅÖz¸ÓÒÊBégÄ5õ„¼úQ–AÙÃ̱·-;6J1 ©$~†€~ÔƒËÑ(Õ$`ài)WÛ5²U³­;ª“… ±›Gª“w©|ìÈaJ{3Xn[·à²Ù¸/~ ¯ Àë/Ü,:=ܶÒéôßwE½ŸbïL©\ åÖSÅÊy-5ͳ.£ZYSéܪòîÈÖIõ°ÝúQ¥«Uåªì¬÷s{†ºEòEÕ9m¿Õí-5Û¶¼/ªG·Hã÷ʺ=mL@BiIÀÂîÈû}1-E‘;®¦W5ugTì錀ÎîŽzW fåÚÚhÝ—ÅΚã(Â-³õº*‰/¸à:Û€Û§3D¤xÐßOÜs5ÂKA8ÈfçY`çó4š>é~¼ÏQb`Q“‘ˆœEúí˜ÙIX*£¬8Ð>P
+˜uR‘t X5õ‘'nsB
+L‹6‘údõïWœ…K«¿R€¼ÀØ~ØS꟰(N½úU±?ßÚŒ¢±QFÀÐb1ˆbGµØ>CF¥pñF”¦*ñtP*
+í˜c"Špõ1  Ú çŒ†Wÿ;Î šrÛ‹í±®Íü—ñ$·¿Ûí˜;'
+´Uõè>½eéOí•—íÂá¿?J
+ÎýË
+ƒ€¹÷¥Ko)Ã|±è€cþWskª6Ò™'ï™t¥bè˜^Û¥eÆe–.©$‡*¤mŠ ;´û(U’É©! `.QÞ1ЊnÇ@je`$pô–ÙÒ½+ËÔç¿á›3ÒhÚÆ„Q
+ä_y{ç˜dcÈåãÇ~¢²97ÓmU´_ŽÀ§`ì
+Xù'?åÕØ¡»»xöãV:;%gZ˶X]¬©Ü¿í†z‹…­ªèZ×O…5¼X^ì(Ýr$ v2Ù%¬ö‚@ý«m×CRH lO莬ÕqTÛlsàtÙAxübô½i¨<Á1vZ0pT{Ÿ— úwì©Êý/®Ê§å‹Õ“3’X¸Ê—x>›`µŠÂŠ7“ƒw3mÌô½û]8š`¢}…“î]Ž¾[xÕ¿ ùÔõaz¿_nÏ=Ê»Ë$ ²|á¶ÃÌ$tüSàŸØÇîä‡Âû±Ÿpʘáï.G~ Á'ž˜Oþyçþ·¯*aÒ˜hüg’kÑMâ‰B&qHyÿ;ÐcÒÿbTü,endstream
endobj
-1409 0 obj <<
+1800 0 obj <<
/Type /Page
-/Contents 1410 0 R
-/Resources 1408 0 R
+/Contents 1801 0 R
+/Resources 1799 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
+/Parent 1787 0 R
+/Annots [ 1804 0 R ]
>> endobj
-1411 0 obj <<
-/D [1409 0 R /XYZ 85.0394 794.5015 null]
+1804 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[0 1 1]
+/Rect [91.7919 217.2504 93.7844 226.8901]
+/Subtype/Link/A<</Type/Action/S/URI/URI()>>
>> endobj
-422 0 obj <<
-/D [1409 0 R /XYZ 85.0394 201.4944 null]
+1802 0 obj <<
+/D [1800 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-997 0 obj <<
-/D [1409 0 R /XYZ 85.0394 173.9833 null]
+538 0 obj <<
+/D [1800 0 R /XYZ 85.0394 548.0867 null]
>> endobj
-1408 0 obj <<
-/Font << /F37 802 0 R /F14 740 0 R /F22 737 0 R /F41 939 0 R /F62 1062 0 R /F21 714 0 R >>
-/XObject << /Im2 1051 0 R >>
+1803 0 obj <<
+/D [1800 0 R /XYZ 85.0394 519.5161 null]
+>> endobj
+1799 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F11 1442 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1414 0 obj <<
-/Length 2658
+1807 0 obj <<
+/Length 3771
/Filter /FlateDecode
>>
stream
-xÚµËrÜ6ò®¯˜Ûr¶D„x‘Dåä8²£TlïÊJåà¨\Ô FÃ
->$MvóïÛ@rDI–][:h4ýîFtÁ]ȘĊ©E¢‘•‹Uy-n`íí u8¡G
-ÇX?\ž|÷†' ETÌâÅåfD+%QšÒÅåúSF–@!
-^xÿæüí¯¯–‰.Ï?¼_†LFÁ›ó_ÎpôöâÕ»w¯.–!M% ^ÿôê_—g¸;?œ¿ÿ!
-?½8{svqöþõÙòêò瓳ËA–±¼4âF?O>]E‹5ˆýóID¸Jåâ&¡J±Ey"$'Rpî!ÅÉÇ“G«vë¬þhDÙŒ›S T$æŒ[žW˃pu³¤i°Ö N»Ú¯»,w(ÝVã Ìîó²/q²ÓͦnʬZ¹Õ¼ÜYZõ­.uÕ!pƒ ·'[¯ó.¯«¬0s´zÕåKÔÎWÙj›W7§ËPDfµë`ft Ñ‘DÑ"¤”()™•å@6Ü4u2Úm+‚F‚Ä‚+Øo¶¬ISFbªR‡RÕsd$‘2õ(y ¼+XAõª.Aøµ^8 Úõ£¼sÕ7ˆl•
-
-šˆ˜œê±ÝÖM®ú½X°ß±ÕÌÜZÍði&ye½à
-oi ÂÛ 8Ê*+N½QÇtƒ&ÖŠ‰T”}±bIV©WÛ¬Ê[ãcI
-j4®—¨àZ#À8Êua5 ³ë=®>žNh‘T¨)¡® ‘^☈Hð'³%"Žä“Y„y*ô¼Cž­7ÏYÑÖÙÕm›~쬫L;½Ê7{DÍ-B)"ÓƒaPõ»±¶ ¼"/ó£ üVÙÝÆtí6f£è½vØ};¯U&)‘œÇÞhÙ}è4ÛæÍé5á$â24‚²0(m±â>A /½§$.F)‰UWœ¼ÍZÂy™WŸ"ÐãÄ ‚KHIø¸•ÁÅx†‚9‘»sö´Ì™DZ1”µß–R~· 炤î»Y%IÂÓç‚„)’&‰G;!$IBc_ÿVûU‘¯æè¤D‚mÜ!D
-s
-~¤v²‹ŽÒ.Š)÷S“–Ú;0¦(3è;(Ty·h¢*Ô’TQ5u{s^kTÏxðS}§o´"§Æyã£Ú6v$9v$Xù=ŠØ½ÍþÒ; y,ÝmµÛŽ!†;›¶;ÐÔÐò´8µ© p¼ƒÈÛèÃ䬷 œ«óSt2«,滦xÐf¥FÐÏ
-êèü‘Â1^éÌpÀšísƧS7O&èÓÇX3çOš& d1eà|.ꡱôMà >Ó: hðù¡Î=KeòƒÙQð5ÁR38ÉZo²¾pþu›½¶ÍØ:†šC…zI§÷ˆE›«'ÚÎc¬Çí<`ì¼*44ÍÕMh/! Ø“Ç þ‹=ÍÉ€5ÃÊDê„ÎS9åµÌLÕnnmàÂØ•æ/2e}뱺̶¼üpo(Ü”›ÜV9øRǬ¹™Âª
-ß_.~ÅÍ#œ¬¸1ÍöÄKJ¨"­•š¦#“æ÷³æ&i$äô¢0«Ø>ÀH欧 •¥ï´iK˜reŠA=8¸Ôë¦
-M8tÁ³fŸðø¼2–ù?(“*JXÊ’YeB"k¦ºt †Gûp3 M—¶ÇÜ3F¡LDs^ëœeÿjrÞA–Éa°SOˆH…xñaSð”Kñ¬NÛ½\-ÐWC›ó=ï0³Î÷-j‘/>lªED¨”Îú4´®¡U9<ÜÕuqT¿¾ ñO÷‡f4© /'Ñï ·Õíë1ZálCñ÷÷ýˆÏ%1¿¼ÏÜ(¢ÁѾùþÃ?ÈSiÊæ¯&,IÁ¸@Ä1e{3ñð:æþà!ëÿ:šš¡endstream
+xÚ¥]sÛ6òÝ¿ÂôMÄ’
+Û~weB‡ÃHDê›$Έ8K=(YÞœ›0S>ÈÍWŒg$©<e‡gÕÞ±¬*î-
+nóå²ØuD¹R^[ÖK9iPÍLÕ^oø öj„µÜ퀋itϪUä«D§@,ÒX|AJfûf;q P=ű[Û¢îPµTJÄ 3’ãL§¡ŸèÀŒåéPè÷òvXtÓt…[Žì2ô¬©HÝt®Ôóªzá¼fxÞuùò‰ûMmÑæ7Ÿ²#Ž’"€Lux×2÷1_Ò±X}x—W$lzµ<²Ñ'®n¯%‡YÃÖB™Ðt–ªÿ„Š«“ˆ”¿·ùn‡ª03ÞKsØsñYKdÁã¼ë;ÍW+±™–Íž'¬šm^Ö ³[GÞ#d+„l„âŽïØJ=rû\¬€`©ñ®»ñáؽoËõE§ êÝAgl
+öe†9ÖšqÚöÐ
+âݶݗ¨Iø¹<"<7HfBÉ­$6.$¡ǪÊeÞ•ä)’Þõ@ïÐ2¿ÙL:‚®X*i(ŒT9m½.Ú–kgämšcñìÈ=¹ÀÓî,ý
+"4 ù#Ôò
+/'D➟¸ÔÒ²í|š<–>¡¢'ù),ÔÆÏtªû‹bÿpÿ ý¾ÝîÀõÂýßšZ Qp÷4¡ÜûŠã¢œn2g‡Œ81AJûñ¥’d¼4h‘º^V‡jñ°Ørí'V嶤”Ç·Ånae»åOJã`ζÿÂ0N² ã^rZžGf2Œ-û¶Dw3€þ<m7™©´@†&p¯F|räýU “-gí.ßò'+LYTà”ª°¢*EÚ›W²âäc¶"|‡u_ï­ BFDú»b8YulÞº‘ÀÍ!úÉ^všÉ&¯E6ëWŒÁàgßØß(oå ‚u–ÛÆ&ôý¬uÕ,¬¿e|ö*òøöõ
+±ß¢
+­É$xQP’IA
+Òö×"Û´2Ì«-g»}¹´#›†ÍO ¼Å ›ÜÃØao©ðY•O“æ4¦h *gˆQL-4n ó-s'ЯNa O¨Ñ?L hžFi$³Öo¡±ûü0UŠ€0Ðûˆf?yŸ&£cqiÂ(ã'IÝÅ[GV™ÄAúGNÀ6-ûl¢NÛ(_›P}ëØæ/Ž­|“¶
+ &½_næŸ.Ç#{ #à™ÕÔŨ ëø–˜#©W“7ÓFìÔ^¼¬áÒY ý $~dHs`ÛTÏDa(4(ñÄØ‘ Î’ (n¾tt½ãèW¸>ÜS s]ã”·ÀAÕsºÂeþ û·Rv[Õ󺵲É(ù\~ew¥„mÎR¹Ï½‡Íháˆ]J˜£,ic9%ÐñÂŽsÃù»©´}ÿÞr»+–¥¾$ËVfpv6Û”û3•Ü$Àv/;qIÓÖþ
+Û\^>„U5>´ÂÍe&ï*NEÖ E#²¹‚Ù”À¬ˆ8…#Þ‚¨[û6pÛÉ—&’9NP¢R®íRdÈü¤Ç¸ÀŒÒ䞙صNM*0¢˜éiYp`C=öúk`ëDÒjy¨ FU~XB ?Û™´8²F`¾éˆ3# Xf8Ë"yr^ ð…ÛA§23ºG-a2s¥ héf†o®Ô#?ô'Û /MÈÌ8(dÌœ‹BŸrPÀ•ÝT‰|~€‹6ä¸xpqÀ­’g¬mkHp°öЈ‰ âÜ|_öåb-†‚Æ(Wy—'°¦`yØ[cè·oe_9L—6
endobj
-1413 0 obj <<
+1806 0 obj <<
/Type /Page
-/Contents 1414 0 R
-/Resources 1412 0 R
+/Contents 1807 0 R
+/Resources 1805 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
+/Parent 1787 0 R
>> endobj
-1415 0 obj <<
-/D [1413 0 R /XYZ 56.6929 794.5015 null]
+1808 0 obj <<
+/D [1806 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-426 0 obj <<
-/D [1413 0 R /XYZ 56.6929 362.9244 null]
+542 0 obj <<
+/D [1806 0 R /XYZ 56.6929 511.0366 null]
>> endobj
-1416 0 obj <<
-/D [1413 0 R /XYZ 56.6929 327.7284 null]
+1809 0 obj <<
+/D [1806 0 R /XYZ 56.6929 485.4552 null]
>> endobj
-1412 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F41 939 0 R >>
+1805 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F41 1208 0 R /F21 930 0 R /F14 956 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1419 0 obj <<
-/Length 4207
-/Filter /FlateDecode
->>
-stream
-xÚ¥;]wÛ¸±ïù~”ωXâ‹
-4žxPs\Ó “(z“8á§ÊЋ¥RÞ[ÐÑr_7ƒÖj›†ÃhÀC Ö—Æm8¢n–øc-Og^ÁŸÌ;¹Ä%,í ™ìm¾–ЉtZþÖµøvgËà–¸©À2€Svn‹]~®º6é OÐz: µY=5gjlË–ÌcøêîQQ•Î0¶þøm!¶Ñ¼âï¾|(ë=µ›3Ï¿Ë·¼@Þåȹ̯ùéK?²ìè7g,wÍþÌÍDzª¨Å.ä!h¢ÝO w§%›ú¯3xº`ŽÁ’‚A Ú+Ò`î„ÙCyuŽ–x·¨RS¤–χh\<E‘eqTÙ.`¿-zûÓ‹§œˆL-5³Ý€R¿ÆvË4Ѻïã©y
-Rúi%?zó°f¢ôÌŒƒµžQF©9>Âî-w§qÜùxlNÜ; fQX~îšä1 ”|êÕŽL´îò°¡Ñºï
-Å4–w¼7ßt”ë~ÔDÆÚûæ\!•„æÕcþÔRû±9}AÍÉ2Žv<ŸŽ”ödž$óÏ™s'­”yµ9×VÆ ¹¶h(î•èe³ÞOì$ï«äßpÒ!ðþ6äBÔvɽGѤɠ33Ç)BNC]<=hôV™\^/óÐ*È9ÅñŽºkB] `l´B›dÁúÒHØIyàÅîí%>Jò¿bµkKñ5?`èi,™"2ÀNõ$ò1ÎUeò‘A¹;ï÷O³
-ßæ”·÷1ňVjÓœN×nu>vܵxûÐbæÌ Ö¢QzÖ…:-¢-.¶uûLaA÷òØõ¡Â4¸NLb‡ˆ^8Ž…#z€õ‰´9NÇÜ·ƒüôØñ´†~y»zÿãÇÏ<ƒâlåŒÃá\ƒÑ Ž—ü€†œÊÌÜ
-‹°«{É&”±Å¡ÙØ‚c”Há>|U$Eû ¢PÀÿ¾DÆ­È!ÿúMýæ[¨™~§>ê·Hc]ô×òp>ÐG4¤)+;öm¸^¢ùÂӌ[&Bû²>§¶×z–û@U*­ÎM•1ÊÈEG0rNÎSÄþ`¥$•’/›
- ƒŠ"tª¢°'ÁJÐÇŒDòÅüF¥Ä~S€>£_êæq.jß/Ñ¿]LYÉbò¸pü†*ÓלŸ=þ4ñ^eS/§Ò,QÚ.ÜA^9TVÔŒ¡
-HZ„zFK«ô4‘Br¢ÁÇ‘+É`àU"¬XrYmsMˆ•ãE߆/î–ö;î¯+,‡„Ãéïw!õzâM-"™KtŸU@fØÒÒ!³…åt½Òómg“Ç‘?–3(G K[ÄMüYÚˆ^$Îr«—·"û»Ë òö—Xð%!­ÅpáZ‚6£ÛÐãM¦I2ÞK5±&` ^s‘¾ÏõèèšfËð'‚ó[€xÆ?@\ò•aèÃðcÞmîcQŒ·0Ù5æ TÀ‚(æøK8±‘db@æ3¯WÿÆ48z藣ط̻'úàÔ9TɃ¾P;øq#lh‹œ‘D½D\/wÏ•sø#Où,z-Þ¯ïìÒBBÝÏš¨Sv7‹é:VñÒï[ÌÊ$uý½h]ROôBÓJêg6ê<æÿÅÊ£…ˆ”¢è­/׳
-4[뉟_¼%²‰ò=ÿG×¾¸Dðm\ÂO!*·³kŽ»b–6Έ˜%‘CÉñ’ 6SI7ÖIÛÐ,{m€Tå!” lŒ¿ QŸwTbç7àzs> ñ(ÂÊú®9m‚X ÓJh:©„Ž™ð§M3?º ¦T’·2ÎåË_0]²Øð{”Jݼþ<òس§)ãø4òl<º`@¾‰&¹÷öñšrY°$ä“C…§§y}dq^”2«©{Å‹ŠÊ¡›HRî‹_“Ê
-##¿¾OÏÔLšÉy½ACÚ³Q µYz6áT¢Za‘ùC2‰M4„4Âò
-¨„LÜpLñÖ–¶L‡~®‚®Å)3cÀœÉ)Ú&77hùR,¬ÃŒçWÐ"_K£ààÍGH?4ú ¯ ¦bõÄ×>Ó§^ÎJ2 ß~¾ùéíüT„È „̲pŸ¥¬·ÈBê<í¯¨ñiô2¯¿O žOoçx‘ŒÏE$ÝYð«æ‚šÌ$B¨ 1ã —(˜ãb>Zw—­º¼â§ x ×ð/·vZìpÙÔ~Y™®þ—ÙàÈû|ϤønŽ¦ÖÝ7WÁ›z^ÈN.ŠÂÉ:8X«²©Ä5Ÿ­i0­Ü×ywî«-¦/ý0øÝuq¢÷‚øyn‰ &V`Ê1!œ8R
-¹jóØR;lÎUW+‚81ÙRøB +ïOIv£LŒ†R½õ2±]rUAd:±/ÃFaEÅ\äìó¢vþBÕF@b¿bê´Y*Þ@ª¤w/ÝÖ(°YÏã]?d ¨!¢ßÍ/nðyUL
-¤Ž7Ã
-üQ’:g¦Þd[tyYµo£ñ,fæu[´›SyÌ/¿´Ã7tø¿ß«¤Ãƒ×ç•ÔXõ”T
-QÓ†qÔÆ+‘NÙ+ˆ,øí¨½†_Fsœ“è‡þ³C‚éHì1N™’#b." ~Ì·I˜aêK„KÿÞ¡ ^/­–öÿoñ_ÿëÇð1qçä2áXÀt"6&*üOÇE¬ØÿÈ%éÿ*[h”endstream
+1812 0 obj <<
+/Length 2026
+/Filter /FlateDecode
+>>
+stream
+xÚµY[oÛ¸~÷¯0çÁ9X±"© Õ¾¬7MÚ,Ú¤ëø
+Ù¦m¡²¤•ä$Înÿû9¤,9jšlpàñ23œùæ‘L‡.üèPøÄå‘7 #ø.õ‡óÍÀ®`ïÝ€Ç9mª_§ƒW§<F$
+X0œ.[²q… Ãéâjtü~üiz29r˜ïŽräø;úõìü-®Dø8¾8?={÷ŸÉø(ôFÓ³‹s\žœœžLNÎOŽ*|
+üÌHøÃéÙ‡½›Œ?~OŽ®§¿ N¦-m{©Ë•! ®®ÝáÌþmà x —Ð(bÃÍÀó9ñ=ÎíJ:¸üÞlíjÖ>ü|.ˆ/XØ c}
+±ÔVØ}žYIY¼±ú¤q-ëµTˆƒ]´e”.ÄŠ«-*eUäY%­ãÎ0´p‡Rù>ÓŒyQ'yÀ©;š®%zúü¹ø„C#P“
+Ÿò®Ð&Ë
+„¥™!‰Mð?š¨¹Mêug¯¶xÕ8ŸƒâIU'Ù
+çùÒÐYmnâ2‰g©™qY?$ƒŠ®i·™Æ’3ðÏjŒªí\©Ãù(®pS9ZÞÅ›"•džoˆq<ì ‹)Î7VÁJy$F[­¬çå^e‚Pâ²°‘Å­,6Š3\8û„s#I¹Àõ´ zÛ£K#ãmD·ÇÇ ëEãBÁÑ…‚Ù€BY¤<Z¤ñ\š ?ÐN&•¬+\Ô˜7Ôt ºçŠÑwâÌÇGÔ®¶e ÿÍ)›¼ªñÀ~“gB@Ïå6m4íqó<.êm#Q…Yf¢ô&Iq´È7qbVíÓãmœ¦6†W¨ØBf?› ÞÖVäΆbšêJ„acb+SŠ¼ª’™ò®Õ\/b¾Ö|œ*ýÜ%À‡A«ÒÀL«ìhÌ'Ÿþ‡ƒ¹]™¾üF–e²
+¾ÒÛt‡TÀ˜tYi«ztƒ aT ŒúðêÀMÝ9ˆÛ¿õŽ…> †­ub2”QBÕu×Ñr/:ç¥ Àê1…Œ‹œ@ƒðy]þ±js¦¸€ƒ¾f¯_#¹sH¦å_;ÇEîý=8œ‘7LQÁÖ‘ï‰ùpA{ÐŽ ØçmÕªî]Cy[&س›Ü1ƒ¬º•¥!Ò=¯Ž0¾8”wsYÔÍr ߃ðÄmÚè¤0Žy$r zÚa èP<âç—o÷A®‹®vÁè‹ûªíÁ²¸w²jEŸŠ§D?\î÷÷ðZ®âÉð+KtD>`Öwes¼®%Àqʨ×{ƒŠ³J–7ÒÜ—M…Åwû2Þl Ãé-NÌ'aÀ1ú¬ AR|‰‹òêUQÊer—ÊìÚÞ :G ¨t®b–¯¶&Jv²ú’—_²§þë>d sQæ7Ð:Éݲ|†ŒŽ¥„J_Õ/’!Ù?¶Añ:ÛEáTɽ¹“²íff¡}Âé›øîeê²uÙdë¹i·Y¾‰ëýí‚#(Dœÿe•ÎvN§H蛦sèc:•»ªÓTuÙT!#àêû;„k£ßž“SåÛr.÷–&…§ÀZ¨o‰0"œ©BªK³wX²ýak}oûU‘—u“UjrÝ£Ÿúd]68âQ žÎMÐV5x¨jh[Ÿv‰>[U¯fÐ'G½Â;V²Ü= Ðý5Ú hð2@Cõ>òc æÞ3ÿ5#
+ïà,ìõ»nY;Xš ¥£~[í¦¦)Ûmí[½Ña(XdzcÁªçEÄãQЋãÞÂŽ
+ûe ô8~èõhmîEðú0ì"͡׫J©Æ£Ï‹GêC·÷lMûÁ¢/ëéþjƒÕ÷ŸûD}yïùäî6’_üÿ-ëÿvÏÝ€…V)ÝòCÍ›ªþ7öNl¤endstream
endobj
-1418 0 obj <<
+1811 0 obj <<
/Type /Page
-/Contents 1419 0 R
-/Resources 1417 0 R
+/Contents 1812 0 R
+/Resources 1810 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
-/Annots [ 1421 0 R 1422 0 R ]
+/Parent 1787 0 R
>> endobj
-1421 0 obj <<
+1813 0 obj <<
+/D [1811 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+546 0 obj <<
+/D [1811 0 R /XYZ 85.0394 314.8075 null]
+>> endobj
+1814 0 obj <<
+/D [1811 0 R /XYZ 85.0394 286.8362 null]
+>> endobj
+1810 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1817 0 obj <<
+/Length 3838
+/Filter /FlateDecode
+>>
+stream
+xÚ¥:Ûr㸱ïþ
+?ÒU#‚
+çäåÍæ—$OUzDòýOÞ_ÿøóÇ·W6Kn®úpµRF$ï¯ÿðŽZ?~|ûÇ?¾ýxµ’ÎÈäûß½ýÓÍ»4”3Žß^ø žþžAúñÝûwß}øþÝÕ¯7¿¿xwÓŸe|^)4ä_¿ü*.7pìß_ˆT{g. #R齺<\dF§&Ó:BöŸ.þ¯G8 Kù'Eªt®˜ÉHs¨¬ñi®• üåj• ‘œÛrõ¯syz<6§nulš=ÁËöÍéuóõÅö+)SoŒ㘮_a«¥‘ú|¸-Oߎâ|Ü]YÕ]yº/öÏâZ)z)²ˆ’Dãÿ¿ÃÁß¼Wò²ßi‹û‘z¯³^~¤™€­…mÊ]ñ§v>”uGÝÊ¿ ¡êª«šš E½¡ÆÏm±+y+5b7ì¤@òœNxsWöô “¤Ks'r˜Œs˜€§¸ܘáài#Ú„L6D[ÙRw}WœŠ5°¬j»jÍÀ®¡ÿÛ’þ‹¶mÖ ÙPÿ¡êîx„þNWÒ%å¡é•ÔÅ—2‘  5Êëäz;Yy¤¥HÓZ»/¯dRï`‡p[™Kµñn*
+­NÖEMf½>Ÿ¨Yð$¦kŽÙ—÷åžço'“
+€ÉËâÕe"uÖ¼æîT&Ÿlߢ’[Í€½º»¦åíQÒ#´!K°£SÒ,2„<©9®è‚I½IôS.5Á^iBÂg ZíêfÐÙÌŠpaM¸¯À–àÖØ؆3êf‰?Ö‚éÏù2rïÔ´´t6Üdr¶ù^2K•ËÔ»×?ÀêlÜ75Ø0ŸrjY6å¶8ï»6íÍ*½ cƒ™I›356UK¶1ôº;TSåÅ
+-=³Ü&€N¿Ær+‘fY/ÝÇSsqU}Ù.Ƀå&î}š¹MÙ¡«L©%€îÊÀõÐ j¯­KöÍ1„ q
+dâ4X¨×,¤ $‘'ÿf[Dí6Ð. ¤føO
+ôub?füÄKT’Îê,¬î¨‡F:=‹‚¢fÃÓ»åØÊšÔHã_©¢à­ŒŽúÜ9
+£Ív aÁ2
+šêâíA£·Êäòz™‡VI†ÌiŽ·pÖmŠJ
+F*‚’øù"¯œ ·É·Oþ.Œ£hÎÕq°»«Ìåc²#šHbµ‡ýc bóÏ3® `–éRýᆰfb¸Jí“%Ùž÷c”Ë0`)ªöŽñ21Ü`Kð‚À0nÀŒ-{~ª‹@ðæâ:ìE|ÐÞ‘GhÁÄ‘te}$’´`#{rÆ¡ðFBÿ†`Ûhƒ=Þ—oæFpˆW&–%VuiøÂ"ê^² Ulqh6¶à%R¸½=IÑn‚(Tï¿Í
+[ã£9_¾ªßü
+Vv/Ûð¶Dë‡ §·JefìËú,†'–û@U
+­ÎM•QDeäš#9§æ)b±J‘Š*Å/M
+H™ õŒ–véi"…
+äD=‚Α+É`àu*­\rYmsuˆ•ã+ßš_í&ú÷¯ –CÁåÓ[Žú‘µˆä.Íú¬2Ö¶™-lw ×•ž˜¯“8[<Žü±œA9½Ø"nâÏÒ@4ðq–[½|È0†ÊxHû7,è)Hk±^[+ÐftdÄø’€“i‘ŠÏR
+ôaú±èÖw±(ÆG˜Ì¨QÌ/ðŸpb "ÉÔ€Ìç>Kþ†Æ48zO£ØOÌÛGêpêªäA_¨ü¸64‚‹ÅFÁH¢^"®—»çÊ9ü„§|½–ïW€÷
+endobj
+1816 0 obj <<
+/Type /Page
+/Contents 1817 0 R
+/Resources 1815 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1820 0 R
+/Annots [ 1819 0 R ]
+>> endobj
+1819 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [116.0003 171.5741 166.1092 183.6337]
+/Rect [87.6538 85.4256 137.7628 97.4853]
/Subtype /Link
/A << /S /GoTo /D (tsig) >>
>> endobj
-1422 0 obj <<
+1818 0 obj <<
+/D [1816 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+550 0 obj <<
+/D [1816 0 R /XYZ 56.6929 693.8729 null]
+>> endobj
+1690 0 obj <<
+/D [1816 0 R /XYZ 56.6929 662.0342 null]
+>> endobj
+1815 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F21 930 0 R /F22 953 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1823 0 obj <<
+/Length 2987
+/Filter /FlateDecode
+>>
+stream
+xÚÅÉrÛFö®¯àm¨©°§÷%>9Žœ(•8™99®DB*$@ ÍLþ}^÷ëÐ2NÕ”ìõõÛ7ˆÍ(ü±™U„
+'gÆI¢(S³ÕöŒÎnaï»3Ï,Ò¡E÷Ô7˳¼fæˆÓ\Ï–7X–PkÙl¹~?õýË·Ë‹«óWt®ÉùBi:ÿæòÍ·¸âðçÕÏo^_~÷ËÕËs#çËËŸßàòÕÅë‹«‹7¯.ÎÌ*÷y„0qáõå8úîêåO?½¼:ÿ°üáìbÙÒÒ¥—Qá ùxöþ­ìÎ(ΪÙg˜PÂœã³í™T‚()DZÙœ½;ûg °³®ŽñO K”åf„œ1P9¢/7Í]u¸½;_HJçÍ]ŽƒÛ}¶Ýf{œT7Ç] À²X&1Zi@Æü=¿¯ã©îãgZÄC«Mv¨ãSÙfS}®q|SÅ'·‡MSì6ñˆ‡ù …Wå9›oîý:›g¸]åmç(vyUçûOi\Ôf ¦%1–91â”âˆÕa¿?gvž—Á˹>ìvÕ¾É×$\¤³§„jƒÌ[Ž3ÄÆx$µÙge}“À‹º:ìWù{ È—;ïdåz®`LOÃ]|Ò# -¨¢6¶Çy`7—j^ïòUqãI•eïW/ß~’¸äñHK:^—ü“«<Y¯‘gu„ÙT¸q¡ÁkëÈtljLö™D.¨œÿ«*s?RGÒÂú碹‹ëw9.á‹Ûª‰¢ˆÁVAKìE”€¼¦ø”ƒ0cs°miÄü5>¨€:„†ôú•>\9„[•
+øDŽ7•Ðžn˜
+úÛ6kVw¿m€ò¸ñgû¢ žö5q@7!äEÀ.ÓÇæÏcÂØsª\+dNŸ)äos¯Meq̱0ìÃà„GT´/ýÉÌÇX‘Ìt ™‘¼‘¦s'â ÑRið¶Ñ3áʪÚne±Êu(GçGJýàíà7xOøÅ\ÄŸ»¾Ç•ú¾†7pœ­·E Hî³EUÄ*{¢MµŒ ÙüÞæ‘•Ùj…yPgóH9΋œÌ6ëUýš¡Ì¶3Qð(Ó]VùiQ6y¹Ž{fÐÀ¤-ò?ŠëMÞÝש¹€“cÇÃÏNí—vAUS­ªM^
+ýj}¿\¾ÅQËhñ·ÓñÅìü2äŒ)Ô}<­îøÓÍ]Öà(öç`äð'0
+~ê]± Ù+Ì°ð÷£MqýÇvÃÁh¹µm(ɨ/ ÔPýc”Jû=ßð€iHA¸älhÜjd…8ß› .y횀<läŸò2½‰¿ îàUŸ‡b—<¥Õ!‚FaÂ*P½ÏöÇhéT'ìeå=žŽŠï×u˜°ºb9å»HOOô‘Çø›c¬š6‚—å˜óÃåÚ¶,è¥à¡œemaT• ¾åqå. ÃO,² 3œ._½Åy]­~Öcò²(oñL—‘ƒ°Ð‰Ücy‚ÔDѤ0Åî´ÀP4 %íL
+}!¬ùŠÊÿ¢/ нË6c È~­íÆPb!Æ´94öÚ~ {Õu’áÙêø|û½F{>ô\Q<g#yþ#.Îc‰“]¾ß Rè €ÊP½œÅ¼–š‰&%%†Ë¤g±]0Hè àB:!ò}y>—
+˜ø6îI2ˆ><Ä: Σ-ÇÝ,Z¶q/Tb~ÐÍ6°ÕQ”ᣠl¢Â o Ôà¾}³ÉŠø X¾ì§S!oØa3ô3&‹yltÄXSœD£»âö.ýk"ë y¹N^<õPºþæ¤YÒûÕé¦ô˜Ö‚øx
+endobj
+1822 0 obj <<
+/Type /Page
+/Contents 1823 0 R
+/Resources 1821 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1820 0 R
+/Annots [ 1825 0 R ]
+>> endobj
+1825 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [399.2874 61.5153 467.9594 73.5749]
+/Rect [399.2874 687.9386 467.9594 699.9982]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1420 0 obj <<
-/D [1418 0 R /XYZ 85.0394 794.5015 null]
+1824 0 obj <<
+/D [1822 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-430 0 obj <<
-/D [1418 0 R /XYZ 85.0394 769.5949 null]
+554 0 obj <<
+/D [1822 0 R /XYZ 85.0394 580.7887 null]
>> endobj
-1304 0 obj <<
-/D [1418 0 R /XYZ 85.0394 748.8663 null]
+1826 0 obj <<
+/D [1822 0 R /XYZ 85.0394 553.3134 null]
>> endobj
-1417 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R >>
+558 0 obj <<
+/D [1822 0 R /XYZ 85.0394 453.4945 null]
+>> endobj
+1827 0 obj <<
+/D [1822 0 R /XYZ 85.0394 420.245 null]
+>> endobj
+562 0 obj <<
+/D [1822 0 R /XYZ 85.0394 160.4691 null]
+>> endobj
+1828 0 obj <<
+/D [1822 0 R /XYZ 85.0394 130.029 null]
+>> endobj
+1821 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1425 0 obj <<
-/Length 3036
+1831 0 obj <<
+/Length 3468
/Filter /FlateDecode
>>
stream
-xÚÅËrÛFò®¯àm©-;/`fâ“cˉS‰í•™“ír$$¢L4
-´F¯&¬|€Ç(ŠNÎyј¡ÿùxêe™KP"m™j_T°o|Ñg™S"oò²Š¾ÁÁï.àN¨ãÉSŸMs´$“U‡1b^_·Š^w„J.æ› \+¹!\Y—ûý±È×)Ò.Áh;V€wmðõ®¾˜x8¸Õ®Ôw5Üãt³Ï ²Jô,ŽLlN^°)+’¤O=à{›‘,Óõ“žÞfÇ9Îó<Ê>íÄ]ÞÐ-Ùs‘îGã";‡¹CÊ“¾¨Ü4/š¬ØО'„kt0‡ç–Ùùj—õ÷Çñ€fà&ûã®ÉäDÐnéà_¢lÊu¹«Ã­„Ð37ÞŒe™ó‡ÞáØàÎ×-W=ù≢ÙùÄ/F'êG?/—¯qÔ
-Æ9}‰~ôærVŸ †¸ö阷ºã ›mÚàˆ
-YüxAÁ¸>ä;ŸªÂìKÞlq´ËWìw¬Vã¹k¿‚ºÁ&2«?…¤°?°ò{LCÉH(ÁǦ!L‚"0Ô›|·Ã%'¡C㉇ìsVè }ÜÁ£+ùŽ–§å‘PãcÂ*p]¥UmLÏ {iq‡ÐôBt]„ª›4ß…äù<=ɸl³
-õì¼<)¦œ®HBÂéíX¤€ÅÞVAeÑà]ŽVaÃc¸‰A1ÁbŠÓåÓ×8¯ËõGoý0v!+òâaRZF ÂB/NO%*ú2(L~8-¥²càŒ\6£$dÓ_Q
-½¯ UðˆÙàõ½³øzh8kÚœo,C寵ùëDÐb|@*ÖO=ÏH¦E ƒ¥:S‘rþe›¯·!åðÐÊ U³:ð'Þû;s*FaÅ'¢¸’à¨W€ÓS">c pîYÁº„ÔHÇ‘ÒIòÝ‚m1.ú(Ç‚íˆ çqwó}‚•P¼© Yˆ›ã,Dš@ºK9¡êrÂÓL;Ó³”Ë5S0à*¯?b²è$ŒîÑúˆZaÌËÈ«‚øë.x¨ðVƹ¼Í³• ½g÷VQ ‚"ÈäDJð:kh} “÷”àÿ°â‹{¾]úøˆ»Þ û…üR½S’ó·áBõ9hÔdN£æËK+æ%î£CÃSxKi¨Xã!¯ƒ€Î»×Äk¨.‚<¬uócuM@%´>ï ¹O©…Ic îKäwkk‹qÑG9ÖVõSœpÝÝ|¿¶Æ= ­Bé¦~øa*H‘ $
-¥ÐaåI{ä%’ež”͹œ³UŠNa ÂR“®_St‡QHT¨p^†Ô5ÎÞ ¡&¸–P¸©„ÙqávÚT¬†ª¾_Å9ŒHP6ÃBxHòX±,¸Ñü||Ñ:’pB‚
-Áù÷‡B¸ècœˆ.03kº‹ï °\·b¨J÷” ÷Ë|ôI°ÿCƒ_oH0òCHV~Å
-Ì»ä´HÆÜTù]!¬¹zÊ}ÑzìÎ…¥»©Þä¾ÆÊÐ`ÃJ{Â~t¤u›Ac[ÍéSó§}é¯-»ë±(Mñú¤t°g ±wÉç;œSy‰“CVíó9´P>¥¨]Ö`ZKÍ™~$‹´hÃu F!×
-ðrÞ\B½/ }wÈ }”!×BrìÆ-˜#Ó75F9'd;\$ê¯#²Åø
-ùØïUI›ËȘÈì\žcâ©n›oBß©ƒé³—oÞ\=Åq­UÞÜá M·l|ñËø
-Z&â5£ÿJh¡¢a„-HД'A¤‹îW2ÁlrÒ’ ò–¼•7Î0äísùLÍ¿l½3‘!ÂÀàp\íò5ŽA!p€U Rüe±HͶ„ûR
-4°ü¯²Èq¸ïcQ~ñÑD†$,¶å
-JUcÄ´#.“5€„ˆòa'QþYjLú­£Éendstream
+xÚµZÝsã¶÷_¡·Ò3C
+!<TPÂzˆèˆpVK¼²vÌ<Ð
+#‡Lm½®KîÊÊGte›­m‡ŒbÒ9 ¾ÍÀ÷Æ!5èŒv|«a7ŒAøeÍ$<—‘Å |Aø»]¶6Nž6[9²2Dz°×g¢3عÎöûc¿^¶‡½²Þ^í«ºóCøkÅÑ¡0D^0øÕ“A½ß í6{_³+ ¶ÇÃÎ-×2¯)@ËîÒŸ±È‰Ù¾n’Z’M’
+Sžtc€°ˆ:C‚Ž¶ÞQš'S 'gWG7D®$³z´´Üu<ÌHCd¦ÂÁÊžØÁ®¬ÖQz<æx®¥Ç·ÿæº –ÖOCñiºöVu»¡ž]Éd7³1ÏŒ4¡ÕõØ`&½,Ï ŒØ¾F îqNŽBÃP±Ê¤S™t*“½Êä˜sQAàU0LKoõÌŒJŒ»&‘Ç‚@¼°¾ä=KRM>YSvÏ„‹ŒÓ,YýÖž3¶Ïþœ ò6à¥ÀSÑç¼RqƶÍ*¸z¿“±½ßgÛ-ÈxjJ.1K5[ëS ¼ÿiw"Úôĉ6
+pz¬FwÜé!IB ™ÔeÞs³¢¶•`ÆÖTúIFo®`¥Q8¹Z©êƒ[zeèpUŒ‰ŒŸRe+Œ_–KjzöÑ¿íÝؤº«„ •UÏD”uõhöß î%åÔÐéwÐ/GÛeô¸»º="ïï×h…—7? gafÙð‚ë:Ǥ:ŠB¸ÑNZg.˜„p½¨.}€Fùöë`[ö(é‚rÀM?=6©
+Z@Mv@«KG±žTÑsÎLE, zTñ›F„s…V» ,™å½„¼ìŒ¬|Ù‘\“}Yùò| (hEBò—¤b’*IÂÊU¾\=#=Éܨ^ö™+ùiÏ%cYþ”Ëðg“tå $Ã`zF`$
+s8ÅWY7mÝ2º´0õœÀ½°Î „‚ý>ô»bç`"$}E••ýDRMûQyÅèþ[ø•q8€ÈübÎ… _ê4~}“±ŒâÉ&»õ|ð$°AÊ*=†£Þg³ÿ‚þf Þ{c‹Ý(F$è:ÄáŸÁgy7-uÖÌʦîm]ƒÿùÍð²ìîKÂ=
+åØbºD—\&.ã塇+˜]ê̺Ðû\{m²†Yò~0•ÝeŸHSÑ
+;àk³å.iÃ\·¼n‹ß˜M—Ž'6l9ü›BaŸ òÞ‘£dÌîra0RÏ—ç.ð•êj.¯AÄ›aW©z®8p¥–†Z=J[ÈCÊV"bÞ ,Û®šž+~ÃR îÒ¬¡¶j‹Ê"UTÏl]¡×[aheí" ü¿±:V1\t™t¹F>Ý5†nk¸ ><9í
+ï0Xûõ@ç¾Ì„Él‘„¾TòÍ`!d:w~j·3Ù¾¡FC•÷!œ¦óŒJ!î*lÿi>Š»ê³Icªgá“A9õúRêÚ…à°°J§æCÎM Ìhkë? AÁ”ÄÀ~ØJiÍ~JŠæq¤0"Ÿ«÷éÄ—ˆeðv* \h.Æþ¢a~•5“m1RCGš–ÄÊT: KlÜ¥åüñûÐJ½9KR=. -é&ÁÓÞ$-Fß±ß%ZR5’$êî®véà¶~¢)¢Ï¾OCSŒ3ÞPs¡“$J&À¬’ È@Oâ©8œ0žÔ*º¸>âxžsz #ò«·Ãj†z.ÑTS';¬Ø}¾=ž;ø¯®•Å£î;`ÍWf²¨€íié}M׌iLŸxqUrôv—ÜS°\möÙp–YÔ«†Q\»S£ŸCüž|„Áï +áªq ý4캽æ¼Q Ä$è¯>­©2ªJá'3²£µiš¿|A‡ìƒl`Ð0s°`NQ«×bwüƒF÷%ÌžºaäK“°÷Ñ>: 6?Kœ~ÈÖ^ç)~Gì6È ´GŠÜL»Þ–³uZá•–¦oŒt?dè ¡&_rvokŠ•âtXC‹]Z§…1úóå‚Â.:sès{CMksqê¢þ#:w šY♉½ŸñK’è »¿8½~E#¥NJµŠ@NtãBð q,&øÛY­ÓääkmÑ þ¬P²ÓB.:»çŠd1™ÓÆȚɫäF=¸RL6©ƒ ®gàõ¥rwý—þN§"?œÿ7SÐèÿë¿ÚõÿC tõrþoQp†>¸Uå„B•§ñ‰äî?y§¢ÿ‚Çqendstream
endobj
-1424 0 obj <<
+1830 0 obj <<
/Type /Page
-/Contents 1425 0 R
-/Resources 1423 0 R
+/Contents 1831 0 R
+/Resources 1829 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1398 0 R
-/Annots [ 1431 0 R ]
+/Parent 1820 0 R
+/Annots [ 1834 0 R ]
>> endobj
-1431 0 obj <<
+1834 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [432.8521 109.336 481.8988 121.3956]
+/Rect [432.8521 729.0977 481.8988 741.1573]
/Subtype /Link
/A << /S /GoTo /D (DNSSEC) >>
>> endobj
-1426 0 obj <<
-/D [1424 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-434 0 obj <<
-/D [1424 0 R /XYZ 56.6929 671.1595 null]
->> endobj
-1427 0 obj <<
-/D [1424 0 R /XYZ 56.6929 644.745 null]
+1832 0 obj <<
+/D [1830 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-438 0 obj <<
-/D [1424 0 R /XYZ 56.6929 559.2968 null]
+566 0 obj <<
+/D [1830 0 R /XYZ 56.6929 769.5949 null]
>> endobj
-1428 0 obj <<
-/D [1424 0 R /XYZ 56.6929 527.1081 null]
+1833 0 obj <<
+/D [1830 0 R /XYZ 56.6929 748.873 null]
>> endobj
-442 0 obj <<
-/D [1424 0 R /XYZ 56.6929 273.3583 null]
+570 0 obj <<
+/D [1830 0 R /XYZ 56.6929 537.7045 null]
>> endobj
-1429 0 obj <<
-/D [1424 0 R /XYZ 56.6929 243.979 null]
+1835 0 obj <<
+/D [1830 0 R /XYZ 56.6929 505.9624 null]
>> endobj
-446 0 obj <<
-/D [1424 0 R /XYZ 56.6929 161.4956 null]
+574 0 obj <<
+/D [1830 0 R /XYZ 56.6929 424.1332 null]
>> endobj
-1430 0 obj <<
-/D [1424 0 R /XYZ 56.6929 129.3069 null]
+1468 0 obj <<
+/D [1830 0 R /XYZ 56.6929 392.2318 null]
>> endobj
-1423 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F41 939 0 R >>
+1829 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1434 0 obj <<
-/Length 3304
-/Filter /FlateDecode
->>
-stream
-xÚ­ÙrÇñ_ò‹—UÂj®½¢'Ê¢lÚ1íPtR‰¬R-¹%`Æ.H1©ü{º§{ö
-ì-G{Ë"‰³"KbܵÛíqÁÜmJ³Ç”&9L.üä’ ìKk7~§®¡¯ý ÛHS¯iÉrm[æ©YÑ÷î¦ä™[F[wHÀ NdWdj6—2.’D¹½Ÿ°À¤Q[ÞK)#P-Šè]µ©Öån}O£«fG@é
-
-Ø-ƒÝ4ÝrÜ!¤S±H’âùR“©W©¶¦7xöÀ_-Ê´½îʪ¦ÞÍ~ÝUÛµ¥à%
-êºn¨½äŽš¾×8:
-Ðr\ƽFö‡µBfuÃuγèP”ï"„ˆn+{Gëß´}É®Ül€q‡ÏŒ5Ð)™$[MRÆõlj¶ÌÓä@mÞ/ÖeÛ~ ùÿ™ÍØ”Ýâf¾XW@Iëç¹O¹\îÀt~t3>®uÅþÿ¾
-)áYZÔ}'á߇lLÔÎ.ö»¶ºµs²o8ÿÞ¶›ÝǺ¡fpõû‘xš-ÒòŠzâ8þ¢ ™ÿØ…Ã5󠀉þ€˜,–Ú
-`žR€7õ³®í$÷ À/-Þ•‡æì@35J’mžÛþ!&@“îdlðV-}Kúl›;»[íý΢•_*£ýpeÙÏÂL‚¥‚¡E)çÚvS¬NÝêÖîníŽëö®‡én‰€ßövwOà²Záö+먘Óy .++¦çL9W™ùµ[ëƒh:©Ã÷î¦!À± ß²ý“ÐÍ::릃àíºj±÷1
-#@Fgu?ÖGn{eH)oìâûê‚|Á!ž«`©²\èçJOÇF õEéb“$ÿôr\¢zKTzF×-3וŸBñ&„IÚƒ@ù‘ŒÏÄxõ»»©0‘Ö©ñ)îmµÄ ‘ê À]Ü”uÕn¨éB,§›=Þ#ìÎ[»¶ ßç'ºx¤PXËI A›ÊQ
-"ò[Ï]11£›ÀSB9÷Ü=Ü´Ò†>"Ǭ6K½|T&A ¥K—3é£êLø:ô‘‚ñã.ˆšÛŽ®HÆÆèï‚CÕg„8Äå?i´­»7LêäÖŒ„«EÂå!D”Ë/]PÍ}»`îRäq£Oæ.h›Ñ–ðVüm«ëÚjG]¿*•!d\d}äðHXÔÁ"
-,«z˜Pl“Æ21þîy$ø"E­T¨¢½Õ½Õ\xÔ¾*ŸŒîÎ ‘‚ï"y¦ž6I€õt¸ã1þ ·µ}R#Ô¡ân·î…¿Ž
-j8Vyî$qÔðÚ0»óDC¾“ÔÆžåQÆõQ.°·ì¹Öä‰d¾Õ.f¤g"ŽPìÒÖ îk¸î'úg¬ƒrÀ'*ÌæŒzÖÅòA˜À~Pç# 35#?N¬õ8Ï’Œž% eËýËì0q§ÑÓ¹½ò*iÆÃgçÓi0°ßà{˜Ã{Þt¼»wrþ¥ÑmVÏýòÛèÍÞE0H?kŒ7Y°;lcQ%ýKJ5œ™€ñ³ÊÙ¹·ÝÄb)[ÿä²ÙVk»œû#Ô—7kƒÖÛ‰/Á⟪Êrü*¤P´ÔXËgXFcŠP¼x‰ToP Ã¿Q AvrŠ¤¦Æ\©¾¼ßGåÐ7”úpy&9D›¸«Üw Ì®pª÷¤™yŽ™ÛY^(J÷ , "[ÒvÇœÔ÷ÁPÍÄ
-ëÀ¢â rËâá»
-,Pñ,ß!Š"ôÆ’÷â
-p8Æ%o#‹õ¼X{±°ÙãИ ]MâÚî~‹·ý‰ —ñúG$ÿ¾o9ï8Ìk o†Øê÷ñù—@q¸Ö±ÈM2}>ž¢¿òÁþWã§æƒS’ÕË—4åÒ]>„Ú›f¿^Ì9‚ø’â
+1838 0 obj <<
+/Length 3726
+/Filter /FlateDecode
+>>
+stream
+xÚ­Zmܶþ~¿â¾uðªâ«(ä““Ø©ƒÆIí
+4 ݮ֧X+m—Ú»\Šþ÷Îp†”´ÖùÜ68–¢È!9óÌ+%.sø—Îd¹*õeQêÌäÂ\nöùå{x÷Í…à1ë8h=õåõÅŸ_ªâ²ÌJ+íåõnBËe¹sâòzûÓê«¿<ÿáúÅ›«µ4ùÊfWkcóÕ—¯^M=%ý|õýë—¯¾ùñÍó«B¯®_}ÿšºß¼xùâÍ‹×_½¸Z gÌ—Lá‘ /_ýõµ¾yóü»ïž¿¹úåúÛ‹×é,ÓóŠ\áAþyñÓ/ùåŽýíEž©Ò™Ë{xÈ3Q–òr¡ÊŒV*ö´o/þ–NÞ†©Kü3ÊeÆÉbR.1Д™UR¾<^ ·ê÷Wk%óÕp[ Ô:ôMÇ;{ åV÷·uWßÕG<5ÐÚB™ÚÀŽjWíë-›nA[œ’<êxåV§Î3õ†—óuíãnê…¥
+•Ik
+¦±¯ºê}½]¨ü‚¶Ìr#ã‚~¨†z_w/¹¹­7âb=ýî«5oäxöp¹VBgJ{¹"+‘â›—_Á`­VÀv-¹‚P×¾Ö]Õmj긭< ©Z¢\myèM]wôªéš¡©Úæwà_xµëÔ@n„!þPošŸó\Æ!Û—Â3Y»ªº-SÚÑ[ßó›À`ìhö‡ö!œ*ŸŸfßßÞ BUÐe¹ºËB óõ¡£éèwY^Âæ
+ Q€Ût†ôûƒ©Á™žD+©¹+¶6Ø66Sru×ÚÚ¾{_3vo˜¤^ØÚEX“Kð f&[ÊT?aýGÙõ]‹ö$/hóð:š;„özàu[SWâ¾ Nawäj»² ÇÎ×ÿ<„²b…vOJÀuÛ|X“23¢Œ
+ôz‹Ø/lœ•óÆbu: ÛÜòBÏy:Š‘ZU÷@{ r$¦MÎ`¼}
+:Ø üú¾ïhdì9ôÞ77iúâ{ÚÎ -(Þ’e\âXB´úÝlý©é„ 9ó1JãèÆ/ŃìÛÄþX ‡~:JͤõÐV9ýú ÈÖ#O¥Y½ÅðS–ŧ²©HÃ>±8«Å$4¤‘S†fuÀE ˆD|$ïèÜ4{Á÷žãz°Zåbéá¾'K2óäR7U7uõåªþ bá!ú𡽨+ð¦(G§ß?¤(bÛÌ6`“ÈeÓT‰FÆä/ƒ.X:
+g ¾çmTûžH•¤¤žc^­L«-Èv¾6¹“ÛþÔnç.¦jï«ŸÆ>TÜ* ”#ㅠߤ[ñ”Hó¬,Uôt[°TÀEäéG_áÈW
+ßqüCíßõÇw˜ˆáãâV~š°‡,ÓÔ“eÙ/Ÿ˜€Šú.¥ºçsÖ‹ ¦ýŸ#èk°½:·#ìSøºFð¡zö1ˆHÿуýY
+!êC=©KÄÈàþ–ã—†«
+•Ç@ „jõj˜¿<TGp!§¶:F²`s‰9ÐÞÅ@„1X<-çmôèDØW§ƒÅˆ´NÃ’zÜVwDÆäl×s®BqìÔÍ¡M™.²Ó/VÆ^T›Û¥p@C\gž@ŒÉ¤åLjQBk–©"Jy ôô±bm!8Ö†ŽÀìAøCµá~®ªC‹“ ÁIôx®HÊPaœ¬ãO7!ú˜®Ä.TfÍê9#«ùö !4£Á‚ Qaá¡¢øÐN: X)ÆwÍÀƒ|Ošœ'<¿ú'ƒ â}Œ¬'¤STöQ‚&dòûlCÏ/N”ÝÍ•©Oyñ9W'2+ƒº/]œ¬Åõ”d¸™íOA¤jJ©Ç•“ñ>ߤA©Ü&Å'6©%„<Ûdð@  ¶YQˆˆü~7J'4ÀòKå«2+l>fÒè¾bRfÆ„hü#Œùåh8w
+6•©BÉKŒuµ1æ
+ËF¯n y^¼ÓOˆÙ&½Õ™°eŒþ«Tä›áDãÌœâG+qJrQÛzWZ>I(6)Etbša;˜‰XœºÛ*dŒÀ‰ZÕž³°Pƒ¥w)r‹ÙVI·¤ì«Kòçt–Ž
+þ·p)ó}’{€5•ËOr€©ÿ ÷N‘ÉUñ ­çà ÕâÕ
+?Žf6׬æ:9W «¹~¬ì YzauñÄve&”Ü.IÈ ¾| 5˜A£ ãg´g5+4"Þ$ٜܽ 4|HñUÇ-A—všÏa/î2|øãÜYÞËVo\G„Û
+"ÂÆŒÓ'èx†»ÈJŠerÉ„5Ë`pŠ(õoæ¸|· º¥±Œˆ÷PØ>+h`èÅÙëQŒ“/?øB4¦ËX(¡@NéòY^Kþ.ÜÀI£¸¡¢z)®U{z``³éÆ ÀÖ6FÛYÁÛ/—áÔÇ_Mmv¢*9QŵK•*µÃqK[1
+Àfp@ØÆ‚§íb샗ôò¸‡CP²Œê­ûp³Š­Ñ’߀.¬Ê4Á|àÈp%J×FA+¡oâ´)øš_„¯+xÀ:9Ø wVí©¦fÃăðžM
+ çãº%œ>ö¥UVè¤ãŸo‘É%ÃUjÞ–Ž’,5Ý—ä^JP<·–«ç-}]¾‘oÈaÈÎ’ÃlÜVwõŒ=„£òØY<vÃs—»6
+ò[.¸ì§<Ê´@ÊßMøzüha.8¼j§-³V‡˜1´¡ÔÛšo¨€©ö‘êô°Ÿ(1›Óò³3… Ùcß¡*H”Zúj4O¥ÞÿûÕñ^]d`Ðåòç§*·xÓUÄMá \q¾óô1ëÇ[ÿÎ};endstream
endobj
-1433 0 obj <<
+1837 0 obj <<
/Type /Page
-/Contents 1434 0 R
-/Resources 1432 0 R
+/Contents 1838 0 R
+/Resources 1836 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1437 0 R
+/Parent 1820 0 R
>> endobj
-1435 0 obj <<
-/D [1433 0 R /XYZ 85.0394 794.5015 null]
+1839 0 obj <<
+/D [1837 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-450 0 obj <<
-/D [1433 0 R /XYZ 85.0394 675.8159 null]
+578 0 obj <<
+/D [1837 0 R /XYZ 85.0394 500.2755 null]
>> endobj
-1407 0 obj <<
-/D [1433 0 R /XYZ 85.0394 651.4464 null]
+1789 0 obj <<
+/D [1837 0 R /XYZ 85.0394 475.2167 null]
>> endobj
-454 0 obj <<
-/D [1433 0 R /XYZ 85.0394 522.8339 null]
+582 0 obj <<
+/D [1837 0 R /XYZ 85.0394 345.3976 null]
>> endobj
-1436 0 obj <<
-/D [1433 0 R /XYZ 85.0394 492.6901 null]
+1840 0 obj <<
+/D [1837 0 R /XYZ 85.0394 314.7239 null]
>> endobj
-1432 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F41 939 0 R >>
+1836 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F39 1151 0 R /F41 1208 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1440 0 obj <<
-/Length 1169
+1843 0 obj <<
+/Length 1604
/Filter /FlateDecode
>>
stream
-xÚµXKsÛ6¾ëWpr’:˜ïÇä串ëLí¤ŠzR5Šm4$Á€ e%ê/H
-X¼bWSi7˜ žÈ£¯ vd™„ÿÒ}Ò|—„8ÝỜPÄÇŒž¤—³Ç×ÃOá68£ÊlºEåŠÐU—ªS_ºw³íÀ`«b¦UÑm¯HÁÚ+b€!û<X_ *y-2E½$„r—ß3Ëx&ÝÑpsÒýMªý5ø².F_—G ÷ƒWñÖª,P4@:7aÓdmC}}íLKv’Ñ~ñð?ÆMü˜P°Ë×i³;¡$1NxÆDy¤âïßn`XV€S|ëà<qSL€{NÚ3”Üu\#¯²µº¢¨kà˜»<©ØP$ãY$†³“z:uSù/;UÂüÊÀ¬7(Â쫳Á¢@ŒÒp«*Y^îÅå`³%# $áéÅ+ȯhû”¦çÚ'ú½Ô®äDUçu
-À…Ý ×]`¸´<Óæ8г-»ù¥™r`ày®ÖßgŽ—b}ùÜ£›×˜õKùÈYoëËŸ~ïÿ­àEªåûfûÖ6ÍNÕiz>´}"•j*Yÿ‰æêåþTõDäƒ7endstream
+xÚ­XKsÓH¾ûW¸8ÙUh¢½7§
++‘oV±ß×€%4wunP¨\hÑk…¼À•”ßðçòõ`í nJ]©@¤Qî/wWI, #F(óˆ· kºäóÍÉÇg–5JÂñ¬7-ð~¿0½
+¼%·Ð7WpþªQE@–äJÕ¥Žì©Ä`ñ}8žC ú1T&zÄÐê1Ú³¨›^ ã6¨
+\·ûKÊ<¸É™„â(ûÔ» ‰£e¸Ý­âð()w õm÷PBZeáV/Ú›ðå
+Úøʤù¼dv­î—?fí¿ôÙ±|Ÿé¿S1.÷>(‘N‰(}ÿÀsõÕëÐõÿ82Z[endstream
endobj
-1439 0 obj <<
+1842 0 obj <<
/Type /Page
-/Contents 1440 0 R
-/Resources 1438 0 R
+/Contents 1843 0 R
+/Resources 1841 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1437 0 R
+/Parent 1820 0 R
>> endobj
-1441 0 obj <<
-/D [1439 0 R /XYZ 56.6929 794.5015 null]
+1844 0 obj <<
+/D [1842 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-458 0 obj <<
-/D [1439 0 R /XYZ 56.6929 469.1685 null]
+586 0 obj <<
+/D [1842 0 R /XYZ 56.6929 267.6943 null]
>> endobj
-1323 0 obj <<
-/D [1439 0 R /XYZ 56.6929 441.8256 null]
+1713 0 obj <<
+/D [1842 0 R /XYZ 56.6929 239.3021 null]
>> endobj
-1438 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F21 714 0 R /F22 737 0 R >>
+1841 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1444 0 obj <<
-/Length 1176
+1847 0 obj <<
+/Length 1107
/Filter /FlateDecode
>>
stream
-xÚÅXßsâ6~ç¯ðcèŒTK¶lkò”KIš›^îJéeʼncû,‘„÷¿Wþ†@°L‡ñ ËÞÏ»«ow¥E†©Èð4-j.µ!11üiÇ4îõ³ë*ßÕK þÖ§Aç×+Ë5(¤vŒÁ¤†åAÓó1†g—¿_|ôú]€‰yæÀ. Žyöéæö·b†—_o¯n®ÿî_t]ûlpóõ¶˜î÷®zýÞíe¯ G–Ç%«›?zÅèºñåËE¿;|îôK[êö"ÓÊ ùÞŽL#Ðfî˜Ð¢1žõ ¥Ø˜vlbAb[V5vþêü¹¬=ÍE·ùX$v·8ÐF5"ÓƒÔ¦®á
- [¹‡]à˜æY+1™ÏRŸƒ'§˜ýÇ$¦Hœ1 ‚´˜Yd&Ú]Ð2‰þ8‚®m‘é—üÔu£6¯AP!<LâTC‘Œ³›Qqw^ür€(‚87!H ÁuE_㈩˜R _“s.Çq:Žâ-pæV)îÁ E ÔˆHñTß•®˜Mïxiî°¸½‡‹6qõ‰èDqÀå[̆ÚU(Ù?S³ôPjžð¦ kVL±;&Ka©RÖXƒ©ˆ@Ê'Ú€ Ä”dÆ”½‚Þj¢Òù±zñÈç )÷UœÎ‹©„©‡qĦ¼¯<5µt¨2 T¸?
-÷Z¤Gc™p¿Á×ËèXÙGá|1©T­¬(qx*×èø [s„x™¤ààòœKOÒxª‹ÒD'"ù\¶êFMІ[ë©÷aúö´ßÜ,•{<þcµîkbµ|¸h³‚C]Ø—~´_§ÑP/p‹ä‘q<wGß×HÞvߣQª:D ƒWDï~Öâ™:)ÛJµP ½t¨Jõ‚²Á¹’ü% …/ÖÉQ°d©£å§@ÀCV
-IîÇQ ›]"¨|Ø>Z“ÙÝ’­u7í·Ì)Ë)Γõäýö0éRha—”‡I{ÇaÒ>ð0¹:ª¾õ↞ûϽԅØÉ÷¼pîŦ±åÒ»EZ¹µ†ö!ºRˆ!MuÝëZŒD®é| 0v!²=¼•3ÉÁN÷¶‰ªµ&ÊÒ;.´\lïZr\ŵ eSº_˶­žSGçF«}@«çi^ S4/ð¡Í‹m=I‹À¬‘¸¥ƒ¨¯òsG÷+WÍ\[óÛóð²‰q­i™ô0u+¥23º©ù²±ùVõÿ
+xÚÍX[Sã6~ϯð#éŒTËwÏ>±4Pvºì6MŸh&#lTË+)Ðô¿Wò%qˆ;¡³;äãèÓ9Gç*d˜ê‡ŒÀ…¦:†:Ð5‘kDóiܪoTýÔÍ}œ ~>·}#„¡gyÆ$i`Ð dLâ듳_O¿NFã!°\óăCàzæÉÇË«_JJXg_®Î//þŸ}çdrùåª$Gç£ñèêl4(p‘ZoU/,8¿ümTÎ.ƧŸ?ŸŽ‡ÓɧÁh²‘¥)/2m-È·ÁõÔ4b%ö§ í0pGõbB†–18® ]ǶkJ:øcðû°ñµXÚ¦?× X~‹ÔP 2:¡oøn=Û² ^gš' MI9’Ó출(‡©–Sm‚¡ëZÍ…s,$áz9HŸcY’ÿ2]S’¥\sü¨æ¨3ÞßlÁ3œvåíò²Õz èS-šÍDN¢»+1·2°,]­Ê…ì%E…C¸(ßÿ)‡ê+Íg8ŽyEË—º~™îl!¬÷+†;(‚.n°8ìH‹Õ gsÓ$!œd©äX1c|–±®0ržƒ>¶õì<i&՞ɳᢇ•.K”Ý6L#[Ìoï…"9΄R
+ ±2y¶]‘ЋH’Î{!íð”1I“U«^Öå@–yJ#*wˆ¥ÛmÞ=·1IqµHˆe±è,v…  ÷·¨|qsOVûjziÞÓî+î„Š Ù†
+¨x@øCšg}]¾L;Û¢ÆUO¦,d,®#\O÷k¢èË(¹ÊÉA%Æøç*Ôr’(tp<ís"ùêX>Ž‚PÁF¥@N"Éxvr,ïfž“Bà…
+tq&T”¬iÊ×uV[Gœ`IÖ,I:ðòD8Svª'2}Û›€eÃP¡;hªz¨ö¨?kªvÕ­ÓòU^¥Xˆi]Ä襭°[{)~ ^ÓŠVh¦­ª8Ò¡‹1S5dt7KUÔxµà±öA¿-ÿ_0Už<¶Eþ:ù¿3·‹\€¢×åçÆ÷ß¿BŽîHtîÅ}§ì½š
+OСýJAl‹>E@£iu)A³r~h‚)BD”×A«¿`8¬Í »–ù9°¡xV{!ý~íxmŸòlµó‹mQ¡ì(['˜¦k•š'oµA»GNqºÈ›óË%­½©K#õûRtD_jý0})ú¾}©õ#ô¥èè¾Ô:²/m»%²]¨¯vZîtÔSízô ÒözÍQ-KX›Ë!Ëj\Ù¦+ôk¦´´AøœóÍUÓ>ëÿ7ò>×endstream
endobj
-1443 0 obj <<
+1846 0 obj <<
/Type /Page
-/Contents 1444 0 R
-/Resources 1442 0 R
+/Contents 1847 0 R
+/Resources 1845 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1437 0 R
+/Parent 1820 0 R
>> endobj
-1445 0 obj <<
-/D [1443 0 R /XYZ 85.0394 794.5015 null]
+1848 0 obj <<
+/D [1846 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1442 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R >>
+1845 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1448 0 obj <<
-/Length 1031
+1851 0 obj <<
+/Length 1084
/Filter /FlateDecode
>>
stream
-xÚÕX[sÚ8~çWøvFŠ.–eOi
-Y:[ºKéK)Ã8XOM-±)-ýï+_1‡Ûfgvò`ùÈúôOs‚ ¤ÿ°Á,h9Ä1¸cB†03¦‹2æzî¾óo@ñ¨~õfظéRn8бˆe g,"ÛÆÆÐ5-H`K# æ݇~·wÿipÛâfsØûÐoÂP³Ûû£“î·ïßßZ
-™Iia •€•ÙtéAý0‚„Z䀀&®h#h! Å™-Jh*à¨,„š ÷;ˆ…Š×@ù ‘ÙÂÕâAÄÙ¸=ƉÃzW€1t#;«@ù`áJU,Z 9‰âIŒñCÄ# #(‡„B#³@Ë¢âW»Ø£˜N¬?¢0÷,MB·pt4 \)ÇÙËÏtéAXµ^æ+ýPµù1óƒü©b?œ”ë]öD æ®ò£Da°>C9\…™>ŠéWø$3ÃÄГ‡›™ëF±Ð6¼ƒxs“=û‘ʽÅ2 *áÁ—t&u¦×êLžé,Õêá%ñÜ ˆžÀ·•ˆ×jf÷¼XH9Y¸jú8 |™»÷ë%+˜úD®%×ÐKˆžï«eu<‰–I 4—ÇÞ‘º ?~e¤—E²Ì¢X«ºUF‰ïj»OÇÙñGƒhE½-JâÕfæÇR¥lŽ#b¹süù¬¿œ$Û–Q¬J{ò2ÞÙÂòwtr¨d²È#üܺ¹³¬—›s¾Š<ô`\‚ïª6ÒþŒOÿ-%iEÅn(g"¾§ÏÙ/K.U $E]
-´\=”~V—ÖGôŽÃ%G­â©Ø‘¿4+‡°I!0w %œi$ÈMÊR ßÒ)Î-£bßűËol]æ@ª”áOð·U¥jíSu8$ºzxªQ]Áp§æŽWà,Y+h '³†«y)WÌXMîØãzTZB0ÄY¯$-á›69(íJ
-P+o™N©Ût¢RéT"•?•—1ž«ÜW^˜LüP—°3 ¯(bÓ:ø|¼Ïäºbú¿®ÇË
-îU
-iZWH癶}<ÿ“úuµÖóùwKnZWr?ãÙ>Êå¦K°Qšg 5 A›sZvèD_åì²ú£¾,ÒF#{}«K_DB?+_‹zÙà“tç¢ÜhÛÎ&0È™Å+û@œïô¹ÜiØr´ÐK]v×4ë”Á¤Ã>ÐZ£Ò¯«ùí9L©m“²G'¤âá64m ’“J<ãhyÑñïSÿnQ{Àendstream
+xÚíX[Sã6~ϯðcÒ ],Ëš}biزÓeÛ4}J™ŒIЬcg%e!þ{å ‰ ˜$Û}h‡a"ëòéÓ§sŽt„=äþ°Ç"<.|ÈfÞdÞAÞ•kûÐÁeðØ T{½vŽN)÷ ¼á¬‚B†ØNGÝ
+ίR¿q¬­!à‰{… R7¨Q†'<Á· J5xNUpH\„ú>T ¢.JrÑH5Š-x“¬´Œ“¿…«¿+W‰ ]ÛßÀõUi Ás´—6çÁ9ä( ^ÜM¦á èS4ê½4lÕüWkòõVžpH9ñ·iÀöóN!õ…x)ž´õƒS}—’ðF¢wi"±‘u繚˜ÆpÝbW¦‘.##Û†·ú™£ åLKs9;\»€àçL¬^íËc?ˆel(Â]7äNê$ùq¬_‡„BóX\aä.WåÍYmf4ó'ÑãBG“82f}wÌQ¬]-Ê×*±ïš´˜©¸Ñš^°AË+gÈiR¹=´R®¦þäZN¾€lMfãµ7‘Nîg‘ŠïÕU’jùìBZ®ùè¨ø=OKÇ<›/b9—‰•Sø#u6vyù’xQ§7àëRêUí柅*iÌxÙÉuåÖÿÐBÉ
+¦Û‘ƒÁîºA/XŽŠâå¢Z§‹ÌZÍlo›Ñ·¸ÿgÁ"f©vªn”±òÖÞëèæ5EêDRínP²UÝÏ”6vœu¢Ynÿ¨ž3¶:Í\ÆWsµ‡Ö²ü“Üç§û$•ÿ§GÿRz´ÿž0Ȉ mó7åLÏïê9ù!9SÓc uÞIiÓÓû/¹îýP¸yEõ]š†dýHHå ðú¡)IeÜzÆüñEñ9õ
endobj
-1447 0 obj <<
+1850 0 obj <<
/Type /Page
-/Contents 1448 0 R
-/Resources 1446 0 R
+/Contents 1851 0 R
+/Resources 1849 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1437 0 R
+/Parent 1853 0 R
>> endobj
-1449 0 obj <<
-/D [1447 0 R /XYZ 56.6929 794.5015 null]
+1852 0 obj <<
+/D [1850 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-462 0 obj <<
-/D [1447 0 R /XYZ 56.6929 121.4768 null]
+1849 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-1450 0 obj <<
-/D [1447 0 R /XYZ 56.6929 90.5476 null]
+1856 0 obj <<
+/Length 2052
+/Filter /FlateDecode
+>>
+stream
+xÚÍXÝsã6Ï_¡GyfÅ%©ïÉSv›ì¥s›¶Y÷åÒL†¶èX­,¹’¯Ûëÿ~
+¥ÞMÏÞ^…©—³<‘‰7]èÊÏ2áM‹;ÿý¿.~œ^ÞNs?a“ N¸ÿîúæ;âäôyÿÃÍÕõ‡Ÿo/&iäO¯¸!öíåÕåíåÍûËI ²XÀzi5|eÁÕõ¿/‰úp{ññãÅíä~úýÙåt8Ëáyñ ¿ŸÝÝs¯€cÆY˜g±·…g"Ï¥·:‹âÅQ:Nuöéì§AáÁ¬Y:æ¿8ÌXœÉtÄ‘8p Œ%‹„H½4ÎYÊÐxðnÝ´ý$H8÷ËõîitNŸ{<£ˆ(dQ",cIkIdÓé@U}зªîº ºfÓÎ5Mît÷дus¤*ú£©uÐõª/»¾œw'
+FÌÔˆC5…êÕLuÖ€®oËúñ¹ÅG6¬Ê:hõ¢ÕÝ2èË•URoV3ݾ\‰úü”ˆ/-éÛÝkíxŠMÕ—ÁJu½[ô\@²‘t ¿ÎÝ4.F{÷‡Z9 ïæ•ê: Ã?ÍÒQµýn=Ä03èlfçÏœEUU³ ~ßèv甿( TÝÃJõóåCè#þ_/ðO§Û'€¼U¡»#ÅwCbáü‘¿cNùs{‰‘½ÐS£ûàÄÞúû—âo'ÞiœåhœÃ×ÆYžÄyÑ´[ÕçÏøÈŠÐàó¦®vÿ]”m×ÃH¼÷Vn¿Ño•Ð†úhûBWúâÑÔàÿ6óNì<ÿ&:Þ^Iá ìšíˆKRŒ-Xfй5ŽÚí'€¦^麧áwúÎe]â¶ÄQuAÄÏzÔÃ>û懈X‰è`&ìNÿvšNrðóò뤵 Áaâ…"ƒÃÉüEÍCûÎããÞþ93rë«ûÓ:ª,éV«
+†#2‡‹ O^°÷Ë,Ëàèn#¹Ð¶rµ<O#–Š<ƒ=PlºDÏæ®x½TU2Ë}Ec×^ž7ëQÍ‚„z§;QD s,¨Ó`XÛ²ªˆšé±TS³ÊF½oè»n'"󛧲°jÓ/›¶ÄÊøäXu·5UdeÏN p›ð}ûºx!0DžÀMYŠ¨¿»â«Hs–ñü«€„IÓÄ“YWG@W©'=ÁÒPØð_`LR+kH¨Ì/;â(úßëuUÎÍSü‡ù$V ÕHJ°/ó]òœ¥QY3hm7bm˜²T:k©yƒ×z^¶šE)Ü}³è=X‚´AêÛò&·ÄX5t]ÿH³¦e ›.
+fåÂ.p‡1Ê+Ð/Uï(»‰s&ðæPwÇša¯æ½S`°ø›5¤]VÒdâ’m0$q» .Cî´Þ3ÖG ¥k²S¥jb«ªkÆÒ ’0Áµöú‚$nj¾°k‹d6DÊðq¯Œ€ùïvÄ+ôBÁô Eß½9ìåÜÀ£y¿ ,_¹©ð©yËTúqHÓTàK®
+bye™îZxdqz°|ß`Nm1~EBP3”—
+|}¿
+á)ÑöXŸ“ndnÕ­±Ï©—\P_tÍ›T™ÂØ.$cYÏ`Oßfaœ‡k >ºèˆ=@i´h³&!º!
+PE{Å#Ú¤`ðHtî°
+¡Ãð ™4úØ8e ÀzÁ! »dóªCÔL/•»ú?™?Žêªf[Yº\Ðw×lì+bc³ß–œMѲՃbéŠ êSÜc¤(máëØN@Éc&sÇŸ÷ö×="|§žQÄÂ4ý³™{Î7¯þk{ÿ¿?\¯áæ'‡§Çñýœ',“yê…1]”üKo¸?ÁØñÿôZ<»endstream
+endobj
+1855 0 obj <<
+/Type /Page
+/Contents 1856 0 R
+/Resources 1854 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1853 0 R
>> endobj
-466 0 obj <<
-/D [1447 0 R /XYZ 56.6929 90.5476 null]
+1857 0 obj <<
+/D [1855 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1451 0 obj <<
-/D [1447 0 R /XYZ 56.6929 65.321 null]
+590 0 obj <<
+/D [1855 0 R /XYZ 85.0394 385.7919 null]
>> endobj
-1452 0 obj <<
-/D [1447 0 R /XYZ 56.6929 65.321 null]
+1858 0 obj <<
+/D [1855 0 R /XYZ 85.0394 355.678 null]
>> endobj
-1446 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F21 714 0 R /F22 737 0 R >>
+594 0 obj <<
+/D [1855 0 R /XYZ 85.0394 355.678 null]
+>> endobj
+1859 0 obj <<
+/D [1855 0 R /XYZ 85.0394 331.2666 null]
+>> endobj
+1860 0 obj <<
+/D [1855 0 R /XYZ 85.0394 331.2666 null]
+>> endobj
+1861 0 obj <<
+/D [1855 0 R /XYZ 85.0394 319.3114 null]
+>> endobj
+1854 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F21 930 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1455 0 obj <<
-/Length 3466
-/Filter /FlateDecode
->>
-stream
-xÚ¥]sÛ6òÝ¿BôŒÅ
-H È+’3Rs­U¬tâ@'’4ÎŒ.‚NX=Ò m“Øäy>ËRú‚J±)û¡Ú¡lÞÝ3šžÙ8ÓE{à´‡uÂ,TÔW»g˜OðºìÈ‹¨äßB‹àE·=0Ô­xÒàI,ËA¬:™ÆþìÚJh¶KF½ÔMÃÐc…çDæiijèhåcS±¢ ·»KGÝs½”r?¬»]=”CýìQmÿRízþÁç
- JÏö„f9iù+¶ó 7ÓѶÛá}2¥ cº–¿Ì
-
-½±
-ÇJKs[ž[NIo[Ѻypä©ËžX`¹<V4ÈŠÚŸì‰
-²|Ž4,}¨‰Û¸¬;[~ 1çL"¾'Ú±ªDÊ¥A;ÈóRk†ÎŽ¸‡Ï·ú½:à±RUD·+!˴С†÷Ä/ɇLy5ixp/˜éïÀ‰_ï)‘ ‡eÊ ™!,ì<Ú p\ T|ñ&ìUªû)ñ‰f¢ÄuÊA2QFÎÖt`)‚9þ’3
-|Kþ¾‚ýPîôÏÎE¿ô~Õʯšà›'o”æ¸h-º x™%Ýh0ƺ]ø‰»1×€|ªeÏè ªã‰ö[žÄ9`«¦ÞÔ“´_)QÃ-¢7 ÂŒ|Aåd<'Lx²/õrX£’kÝu~†÷á>c€É {ª'™ÁV=)¹/*U52Ü{¤$ŠUÛ3ŠŒ0ë}+V¶ô#+™»îö=œ­Jz<¤Ikzžµ% g‡I9ºX¥ˆË8p®XF¼:‡ƒD ØDû¾bDÉ¿‡—nÞ€Ê6Œ÷OÞ ‡úÅBã%™2>A
-hÞ.÷^>—})A8M~ íÍ ëS„ê+íƒZNdÊ„47>먟Öï²mÊEåãG%y$]65É©¼Å’Á/Cp8¾â¯º%Ç
-é&¬šÃ”ÿfŸmŠèî3~óÖèKÎÉ#¶møéËD‰C
-Ù ¬ÃÄƺè³ðñ\¹Åÿc( ™³—ßvYKþ ѳ]ò ‰œÛ’²f%áOy?
-ˆî>Pƨ¢«ªöc|È­“™U烩ØɱU£CÃR„ÒÉxJ
-Ä`‹ 1Ϥ’GÉÃ
-@*$ÙyVÉH"
-漓å‹nß,|ª$¡-‘Ñ„’Z‘æM7TD8cÈß
-Á”®Ú3–å‹PÝò ôܱÁƒ+¼Í
-­UHùnÅXÉÇ<üˆ?¨àO`™a7ÃÌ?.8aT”q‡ÙˆòMöYX?•=Þ+Ù<RTq&Ò¿Q^˜°Æç *õt
-¹)Œ¼n“IåI‘eÜ—>& !öõâUPDDòRWwú«è¨òU.Ñ
-8õëÇ¢ TÆúkÛ@§­Œ$ÎŽ“  ¨â· †¶SQÀ7HwYû6“<vYèñ낦°4È]\TNЇÙå".×?^e&Ίô¬ÙòÆ0sƧ^å«€wÞœìGoš6?½ÏôóZ
-Ö’æ¯Øv%y׺^ ÿ±Î7Å*·[ʒѹvŒúc_íêJò{­S`ìrz#ðdÄ#å_Ê ž%P!| øxàa™Þ$Uvì9z T7õ¾n ŽÿtœgAüÄ/—Æ6IÒSÕÝHý—È«C"/ÓU/†»¾˜š´ü­6ÛáÀ ¼ýhsôÞæ´øÒ äôoÜĶ–BûŽ6 F^…惜€¹„Ó6v:)ΞÜÎŒ9±ÙHâ£lx¼±’#Jž´$äcÁ{ÅÉ;XÇŠsOLæAt–ä•Þ?q䜢=HÙr<G*Ž…ÏkylrçŸÝ–ÊÃ)kvqø4sb—BN¼÷›­x3n:t\±4)YõÁòL¦íy‡©–0Fþ‡ÞºÕ1<Í&ù%hœOâÛv9kýân>aϵ{„P<a p&›ž+Ô?ŠXU¾ec›g¯ëò.h 5n%*[|„À¤ÜÚ×aG¥aÌ‘MODQ‰ÞÔB,Üp@ˆó+ŽžkjÚÃ*LÊÉ¿Çý Ž\ jî0â—3í|×ÆIÞNPHbЩû×ÅJ(<5Èm8?Ù
-2“BÅi–Ú©?¸‚Ââoþó®ãß¾Ù,NòüØ€>ÕN…=©"Ãà†´{Ùë¦;„è47aÖèèÿ@y"Bendstream
+1864 0 obj <<
+/Length 3279
+/Filter /FlateDecode
+>>
+stream
+xÚ¥ËrÛFò®¯àª2áÁ`0
+³ !’…@[¿2
+œ*´VYjÉÃ1VG êÇ<|ˆ?¨äG`™f7ÃÌ?L8bT”­\Ï
+'qLˆ?Ø¢Û8>Eä‡#åÓåÓ ¾[ïÑ¿†Y§sèëòè¹yA‚à¢Ã0‡pA\BÜ#¡áXŠÌPšjOi¾S à x4¢Û«n×`ÒðR{椵Ýqœ·yæLæ3DA·ŽýÀº§f¯ S¶»æER ˜R¯Ýî~Ù÷óét×·6z¸û”IÁ/£°+˜¼ñ ‰ ž§zÀXq|6äÖ°ìœÎÃ÷É¡7í»ÝÖMÄð2!j'Ã)µ² ,…8àø”J|À'$2õ®uk¦–¡g©¤`Rsø÷›'4Dz&k † /l¸™ò1 Ö±ø´23…‰ ›ÚÙ¸žùÆɨl¹K–Ä*ãúì¯.ê§\*¼4”~¥.ìtáUXffJÈš bæÊ/(­MóQùU˜£)€H½§ƒ!ÊÕ
+N°éütžg¼T”“ˆW‚Zvëu÷Ê
+)ZEÛµ#zHƧ9ÞÁûq¼ÓÊ·OS¨wï˜6‰°ã²,Kçy] è輸¨O·hª©c‰Ä„ë¨?
+Ráa¨7[ìn¤:¸(Hr[žv)¥Jli5K©·6趞k`Ù
+6ß±ùO]¡"LHK1Oâ—mÝÂûì%?ï~ÄO7¿<þ0YIÞ:vn' ÄI[šÞ5‰.½5Q¿]¹÷¡„z®ÛŒÝÓ‚3Ÿ*[©ˆ½kGøصJ €nä–R°3§/4ýÅ
+`œXc²~¨
+-$ŸÞxXèòЙË)Ÿ%M±Ñ§¥ º©d9Iã ÷þ+<€,7â'xáØ,†”;;VÝ|’lž[‰2 9ó¤:‰Ÿ8Þ\7½-'…—Xp !üúÁ5ú8ÿýņù.|€”0—fX‹Å6IË“êêĘS“$N‘Ê`k¢„‘Î8¢8©2ÒöÃ^ï¸_aø_‡Å„ÎBTåv5ô<r¡¯Ø¾É§‹ÃÉ8£¤O ‡ç ,‹¿¯¥¤ ™²f—ÏAó1­°¤Ð{¿Ù’7{ëö ¼:þ(ÃþQK·ŒU,Oç‰9ù:ºò…(ùŸ¹6eˆÙ‡ÊËw”+H‘ŸzÊ@þT¯ÜKãC ŸZÎÏXèwOn=e p&“*Ô?J(%Tø”‰M^š“ÄÓ}é·´+LJˆÙ—1çaG1Šìú#N:"OEQi½©‰øñdqb _Ja¶ Ý»)MzÚüm•å†¹­ÄJ—3±þË­•Þ=A¡‘‰N½÷HYáyÜ^K¾‚Räëóhv“Q>«cžx"N’¥ï~ŽôÿrËsœG|cn‚¿5jBR&RS¿HÿÂäoþýËáÇA&Ó¢Ð!:~y›IÉ)ÿJ}öëœDÅP–hO5:úÿ
endobj
-1454 0 obj <<
+1863 0 obj <<
/Type /Page
-/Contents 1455 0 R
-/Resources 1453 0 R
+/Contents 1864 0 R
+/Resources 1862 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1437 0 R
+/Parent 1853 0 R
>> endobj
-1456 0 obj <<
-/D [1454 0 R /XYZ 85.0394 794.5015 null]
->> endobj
-1457 0 obj <<
-/D [1454 0 R /XYZ 85.0394 769.5949 null]
+1865 0 obj <<
+/D [1863 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1453 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R /F21 714 0 R >>
+1862 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1460 0 obj <<
-/Length 3003
+1868 0 obj <<
+/Length 3218
/Filter /FlateDecode
>>
stream
-xÚµZ[wÛ6~÷¯Ð[és"WxtS'uOcw÷ì¥í-Q6»©Š”Sï¯ß H‘"E¥›îÉq8ƒ¹| Š‡bfb;éf‰ÓÌpaf‹ÍŸ=Aßû xæ Ó¼ËõÍÃÅ×ïT2sÌÅ2ž=¬:²,ãÖŠÙÃòç(f’]‚½½»}wóþ§û«ËDG7w·—sixôîæ‡k¢Þß_}øpu9ÖˆèíwW?>\ßSWd|ssû-µ8zœzýîúþúöíõå¯ß_\?´¶tí\¡!¿_üü+Ÿ-Áìï/8SΚÙ'øÁ™pNÎ6Ú(f´RMËúâãÅßZ^?tÌZZfbxF*‘œž–¦à0m Á%Ž&[Áâ8"vààØÙ6"Zt""$gÄÌãX¬¤ò!y΋ýòõ;);̱e‰–892=<gàJ!¢¼Èë<]Ó*«‰(Wø”ÑîRب,Ck‘n²†q÷’íª "<«m¶Èá\fKjØWyñD‚RjùEJíõó¿þS¶0T› Áœ1Òkø÷ç¬@6Õ¤« ³ºNwuEô~ûi¢¼ UVíZ⼎’ž¨x±$:ã­Q´Õ*Ž£ÔK
-r‚Xk½Eí²*Œ½vDÖÏiAÔÍm•¾dÔ‚ÞÁçã>_ר܈>AÕŠ²K˜ñ(µh«™U<ë®É/Zåš+èŽ ä Ãb-ÔŸØŒ8™88g±´f<qXÈàZIÈ s\¨à„uö”ÖyYÌËbý:’Bñº6‡x<5O
-*ì„vŠÉ^t›ÒÙ@5«c§Úò^°¦9$@¿ÿŽ¬!ŽÓ0c…=—ÂÑ*ýª"šª¤6é+å“®×á÷c`X•ëuù‰r´†Þ”¾Bñ™…û
-踋ȼ™•²ï–<>õËÀ=Ì
-vk'E2T#;¡bV'&°ànƒë{(Kàþ*“FTQg»"«Îu¬äÉA xC™BÃæ¤4ýT‡Åì7Ù BÁÛ ™·ý‹rSH¯TèaJ}Éä%­Bß&ý-l,ø«\5ɦÊ:ùÈA%ÃEæ“ä¦ñÞsVåårÄ`åwʶ9%µWŸˆ—%‘^i$üFŠ<XUlš]°ḇÄðì‡Ä ¿>Ü<|DþH¿Q&‡†+ðB‘â˧’ÑMÝW€Š¤pûQðzQ=§êcn,sÎé£ÈtUCŒ¦Xøð%Ýå¥/o¯Um*êY¦uúˆŽl‚{£j¿xÃh³£^=‘ûmþÝå­ ™^B`LUÒ³,ÀD­Dx냖g¯ŸhCZžßC¿û8¶4ÓÚ4ñkñHêµ(‹×Íä ¥y3> Šfº*BQÙ‡„† ñ%[—Û ½0AŸ žoŸÓ²‚õ„ ª”Z¸º¥q[rS].Ê5u-ºõ—T+­hØäKÐ(á˜a´ÐÑ¿èÝ z0DÄLÙðº‰bÓb¬ÚjJ™þÛ4`©xX…CÿCu`xãÚ·ß]Ý
-‚wÆä Ø:\`k¸qú}ŸíF°&WÚMOÞrÌÞÇàCĪ?ý_ ¶Öˆc¬AA¡ÚÊc kŠñX$=;'±øÏX<”ûùXÓ°h!§]ßrQd(mkª>ÃâœÄZ—ë4ÖZ®£0Á»Ñ
-j û´Å©Ÿ4xõÖJ«I¿·Lg´8–52ÕŽKÎì¡]® œ5\‡í·PgÃMÂÉc=={Ë52}hÕ,ôöæÿ2¤¹ÒVãL2˵8½‹B©Î¹î»yjmøϘ<”û'*6ÈBtžô}ËuF‘¡´I´‰$fFÈ3I­Ëum-ÎHšoËu¾©Ù`«OŒ›ž¾å™¿7 «<Q}>¶/qýW]¼¿üˆGø„£æŠÂÿþÉ+Ž\ô;X „ˆÂ© ù8†°Ãv¯{M密ÿŒiC¹£°’c°rx,˜œñqËuN‘´iXiͬ<“Ã:L 
-LÇk/õŸÒÝ/¬Ñ»¹å\MjÑ2 Õèa ÌMlÇ¢ÿO&;²fä¥Ä8{:«i.Aš®ÅèkÙ§mHý씦cï¯ÂMF e:£Å±¬iàù3 ¦‘× ^ÃEѪÊS§Ü@= ™vrò–kdö~°9Ì~G®ÒE›,-
+xÚµZYsã6~÷¯Ð[䪃“$‰gâTÆžxœÚ#É-Q‰THÊŽ÷×o7 x‰šìdËå"4ÐׇFãà3|ë€I£f‘Qf\Ï–» 6{‚¶÷ÜÑ,<Ñ¢MõÍÃÅ×ïd43 E8{X·ÆŠÇ|ö°úyþö»«×÷— ¡Ù< .:dóonn¿¥CŸ·w·ïnÞÿtu©ùÃÍÝ-Uß_¿»¾¿¾}{}¹à±æÐ_¸NtxwóÃ5•Þß_}øpuùëÃ÷×.m}9“¨È?ÿÊf+Pûû HëÙ ü`7FÌvJË@+)}ÍöâÓÅÍ€­VÛuÌ~JÄ ”À2Bòè4[bÁ€­+F<ˆ$ï1]pÎÆe8[„Œš¸q‰â-—pe 5}µ B)¤õÉ&Ëk4Ì×ï„h‡q)Ü‘èa“‚%9ŸgyVgÉ–~TiM…b_1//y</
+W›'»Ô–ÏiY¹!Ü·Ú§ËìÆDº¢ŠC•åO4PB5¿¡¬|ö׊<Åš
+ ôpFئOIù¢È·¯#!„3„Ü4!ÄÂI‹¹ÿ&VT²“
+¾iŽÈß.BÚc ZúÜl%Lêúà³sÏ×eRÕåe<?,ëMž1'"̱/ƒ0Ã4K/ù<xà£`Aùð†šn¯pQ±¿Øüîþ=Ðò€Ú®òWªNòêÅYlÕT›¹ÑýüÍž…Õ*_²zSFÑn±©¢yúç~›-1FIh/©6Ûµkfq­îkí†Éø”YýJõUºôÄ1È°ÝRõc:j’<©Qhn`êVø•óÛ~{÷áêæ6 jò,–VEêHrœœ¶Ï~îÂ"zÛ¬pXA‘†¨Ò?­í96À^ÛM9;:Sú"—,u­„&6ߦɚJÖ×A´íÁÄ>‡i³PK¿,nÐ"Ò
+Dßt&[ƒ•ñ7œê !Žø”kÖÐvÔÉÍ…µÂÂsì¸æ%±$+ÝGŒõ)u†YB`K|¤¢hÖŽR"æ¥X< ™‚Œ€˧î[ÉKC¿hw°!C´í:¥*!d/FlÜ–HF
+Zmƒ$ª¡‘£í®áh(ÇÉ`Ý
+ƒ_ZÑú˜ žM-¡6º›YþO¼ Aóý¦A¿H´m9´)ja¢ÙBGsûÖgÍZ‰@† š“qHlLg±Ï®¼#Ó`
+ù›Q\ÓJnh‚~UQ™ò,í’W*{ÄK²ÝºßŽ`]l·Å …'¨u­ }lnbƒ
+³¹O¿‰Š™çJ‹µ“õ…£ +µ<tÁ
+I€wóˆÊPdÚ›f“VY±QXš€é³ç9)”¿ˆ—­ÐX°k(Ò`B±ó $T`®˜avaÉa~}¸yøÊ ù‘~£8W`…<Áí¦ó›º+
+›Ù _«:ÝUÔ²Jêä Ø”GT‡åÆuw MI­lþDzöž|_f-72m? OUзÈAE%¹ÛïAÍïéë -G«óËçwŸÆf€
+”Ò±ó_ƒGúT¯y‘¿îz#,”¾QW¹Kç!Z£ã° `9|N·Å~G[%h±Üàûv“Ì'œÐ€$TûÃÕ-õÛ“™êbYl©iÙN}ìH9‘Òl€Š]¶‚p1Œ0Îæÿ¦]´ ‹ˆ˜ŠÝF‡Mò±DËg1Ý}T`–xœ…CûCn ™7íÛï®îÆ !LGqØž@.ê„õ‡E"ŽCØ@P)ÙìÒv§&Htgcr58S=xK†°Þ‚&ãGHD³h^g*›cÀ_€÷³õ uà
+"`ñiæ Õû.nÃ@…q“X5aq•VË2Û»yLñph]L(ÅúZôXc¼ÀÙM™AÖ&aUUØQt"kkèϨ<—T^•C8ÀvP DŸ
+cÎؾ¡:'È`´Ñ´pTR’‹)°!ËÕÚ<ÕÑOÒrlŽÅ\M3o¨F¸wÁ¦!—‚õ¿Ãþï[£DkOÈ&ñÃLÖ3ò$Öý‡ã~>Ö"<RŽÂiÓ7TçŒ65ØH(¡ä¬µ¨&°æ©zn‚Ñ
+ËÁ´íªs‚ F›Fìï¢ȧÑÖ¢š@›§BŽä¡Å¾ØfË‘ì-`©WÓìªþ]¸I¼?Žº|jvsÝ=/^a~Âc|B𑿦°¿²‚#ývpÎçîøÜ÷!¬è\BÎ×–t
+VžþŒjÃqGa;Äá¢)ðôV·I7TgŽ6 +« ŽÄXµ©Nê¡êOÿlð_’r…×Öýƒuvƒíã´ Õˆ$måÓ
endobj
-1459 0 obj <<
+1867 0 obj <<
/Type /Page
-/Contents 1460 0 R
-/Resources 1458 0 R
+/Contents 1868 0 R
+/Resources 1866 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1437 0 R
-/Annots [ 1462 0 R 1465 0 R 1466 0 R 1467 0 R 1468 0 R 1469 0 R 1470 0 R 1471 0 R ]
+/Parent 1853 0 R
+/Annots [ 1870 0 R 1873 0 R 1874 0 R 1875 0 R 1876 0 R 1877 0 R 1878 0 R 1879 0 R ]
>> endobj
-1462 0 obj <<
+1870 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [251.8681 599.6322 347.399 612.3694]
+/Rect [280.2146 599.6322 375.7455 612.3694]
/Subtype /Link
/A << /S /GoTo /D (root_delegation_only) >>
>> endobj
-1465 0 obj <<
+1873 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [284.2769 331.1334 352.9489 343.193]
+/Rect [312.6233 360.3945 381.2953 372.4541]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1466 0 obj <<
+1874 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [282.0654 299.4481 350.7374 311.5077]
+/Rect [310.4119 330.5066 379.0839 342.5662]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1467 0 obj <<
+1875 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [311.9531 267.7627 380.6251 279.8223]
+/Rect [340.2996 300.6187 408.9716 312.6783]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1468 0 obj <<
+1876 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [299.7586 236.0774 368.4306 248.137]
+/Rect [328.1051 270.7307 396.7771 282.7904]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1469 0 obj <<
+1877 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [292.0084 204.392 360.6804 216.4516]
+/Rect [320.3548 240.8428 389.0268 252.9024]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1470 0 obj <<
+1878 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [330.7921 172.7067 399.4641 184.7663]
+/Rect [359.1386 210.9549 427.8106 223.0145]
/Subtype /Link
/A << /S /GoTo /D (dynamic_update_policies) >>
>> endobj
-1471 0 obj <<
+1879 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [401.5962 141.0213 470.2682 153.0809]
+/Rect [429.9426 181.067 498.6146 193.1266]
/Subtype /Link
/A << /S /GoTo /D (access_control) >>
>> endobj
-1461 0 obj <<
-/D [1459 0 R /XYZ 56.6929 794.5015 null]
+1869 0 obj <<
+/D [1867 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-470 0 obj <<
-/D [1459 0 R /XYZ 56.6929 548.1995 null]
+598 0 obj <<
+/D [1867 0 R /XYZ 85.0394 560.3013 null]
>> endobj
-1463 0 obj <<
-/D [1459 0 R /XYZ 56.6929 520.4385 null]
+1871 0 obj <<
+/D [1867 0 R /XYZ 85.0394 535.1807 null]
>> endobj
-474 0 obj <<
-/D [1459 0 R /XYZ 56.6929 391.3968 null]
+602 0 obj <<
+/D [1867 0 R /XYZ 85.0394 416.2201 null]
>> endobj
-1464 0 obj <<
-/D [1459 0 R /XYZ 56.6929 364.0541 null]
+1872 0 obj <<
+/D [1867 0 R /XYZ 85.0394 391.5178 null]
>> endobj
-1458 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R /F21 714 0 R >>
+1866 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1475 0 obj <<
-/Length 3204
+1883 0 obj <<
+/Length 3164
/Filter /FlateDecode
>>
stream
-xÚ­[msÛ6þî_¡é—Ê3J¼>¦­ÓKçšÜ9îÜÍ´ý@K”Íš"U’Šëûõ·ÀßD&SOÆ#xˆÝ, „®"øGW*&×b•hAâˆÆ«íá*Z=@ÛWÔa6´é¢¾»»úö-OVšhÉäênßéK‘H)ººÛýºþþoþuws{½aq´–äzËhýÝ»÷?`ÆŸï?¼ûîÇ_nß\'b}÷îÃ{¬¾½y{s{óþû›ë U1…÷™ëá oßýóK?Þ¾ùùç7·×¿ßýtusléÚK#n ùóê×ߣÕÌþé*"\«xõ ¡Z³ÕáJĜĂs_S\}¼úwè°Ój_?+3!W
-l·•íi——®¯ÊZyp®ý¯*3dûrÌ NaJÀ»€°HJQš@ÛÖýÜœÍ$s0Óã<:IAk†_|,J%DpJ]û4/&јô™UNŠKmŠôS6Ñ!‹IÂÍ´|5ÍŸÓºœÄ ì¬ùÐá¸Y-¡3šH:?õ»¨ËS? ÎSÿð×hÞ3þ*aó’jBtïûpð\‰’}Ù³l4¨Í¶Î`8?Ç«1¡Ü˜u-ˆ1‘¼*qþvd  ‰ê‰õÃ
- ·s~ÁÜq¿hîöl˜Y‹¨$t¨ŸPÍçÇ= ÷6ϲX„˜.j†euþFÏy±Û¦õnĵXD$ñ¼ü€šP ï 4øg¥ú¼&׺v „'ðUµRÇ„"b=Sgð FûýlƉH“x~ôjA‘qoóŒc‚xɯuP3Œó¨ó—ÊË6{¨óöeL9XbEg¨ ú”ƒ°†3ÕWá5)×3dÈ9
-±(›áOˆŠ÷lãœÇ/X=î÷ 8'ˆdI2?üµ È¸·YÎÅZÁ–Âè.ê2çêü©šü¾0‘Ö(¤€%pV|@MÈï3ŽB«Ö}þãtq3²%'Jk}™oÌìiXßÒ9¾yü‚Íã~?UÕaÐÙìØ{Ð’þæÉ¡2…ÝÎÙ:¨²y”I³ºÚ”Õ¦©ÒMÛcÁW¢j^€šÐ O·˜¨„Ó¾
-¯C· C†„S„ >ãß|¥{¦Îú7‡_0zÜïðMƒOVb~ôjI‘Qoó”ã1¬¼|É¿uP3”ó(#ñtÜ¥m¶AÿðÔ<8'%T.hP*ô8—D$ÑÉ@‡×YT§,ˆW°1“ ý"ë$#°æˆž±s¬óø³Çý~þª
-»1K=?þµ È¸·yÖE°ÙJøéΠÎ9×Ö/›v{ÜÔپΚÇ)/ÛôdVz
-Ó æ£C}cúãþØzÖ__Óuƒå2móON|^nÙ¡ª_ðGa·¹/RZ|ôš:ËL®9JÜëMR «2/§j‘FÚ¦ˆdØÛôÉ RïƒNŽÖ^;ÁÅúSZœ0ÏÏÏT1 Ǫ1¸ ›ò=Ö¦»]n¼{Z`}סˆõ®†¨]o&/n«ï³¬Ä:Ø>áá„0<©°Ö9,±n²Þ7'jöl‚®?V‡IŽ5éáXx†x¡gÛ3OºmqÚy
->çíã\¹ñU÷§óze,”á(£×¥7 Ëéû—^>ÿâÊÃ…"*ŠVž.êòÊPÖSæð£u‡
-𪠛—P‚{ëøheÎ{’_'º9ë?>ýár.û.#" Âï™8—}÷øcÇý~~`ÃBc½0굠ȸ·Ù؆Ã$ vÍðËìçÉŠì!5¦oª²˜H„J¢a;'ÜcÆÂ{“0ÅÍÙnW:zvmÏDyú`ÊñÚêakÓã±Èqù”na’ëÇÃØ/—‚’Ó=–ìQø!’õ»½kÍÏ5+ã°{ÔŸø½dÍÔ"¡<äP¿A§Ó¢tªy3Ü)Èz΋ÂQ4Ns·¤š¥žDæ ïãÑ¥aYMÛ3îÙþžO±;>/¼ÃoVU,å&WŒ0Ñ·àÕÓ¶ pH†B“ÑeJ‰¥ð›î c^Žû5ZÕUÕnèɤ$Rɤ§Ñˆ 5¡Gß3 {›,VPó²º<!=ÈaWõóÔ!£$N¨ž•@c±ým†„ÈyOîËÎãõ!KKê÷§Â­å{¬w+yv€«RüAåm„êBaƒp»â ;Ý'ŽÜažDÒmþ;OÂMüq¹lPæ6=¹[â¬bQUO°ê Þ6úË0:šjÎÞ{0ÝÛ+,‰Ì–ÜnkXBÝäN¢‘q¦]4>dm^)+¬LËæCc&Òl?Šé! À<哘~Ë11
-ö"P¸4P
-'?5[1§Ö”U}0‘œ©òÃam«°Î{#–0))ú4²ÝeêG&ÉÏÙ÷;¨ò{T‡ýf|‡€Ã¾Ô¬hšÝ¿o
+xÚ­[[oã6~ϯ0úR¨¸â|œv3ÝÛ™n&Å.ÐöA±åD,¹–Ü4ýõ{x“u35EƒA`‰<:òã¹¼Já^q„&z%5C<Å|µÙ_¥«Gèûö
+{š$%}ª¯ï¯þñžÊ•FZ±ºßõx)”*…W÷ÛŸÖt Òõ7?¼¿ýöÇ»w×’­ïo?~¸NO×ïoÿ}ãž¾½{÷ý÷ï8^ó¯w?Üßܹ.áy|}û៮E»Ÿ LïnÞßÜÝ|øææú—ûï®nî;[úöâ”C~»úé—tµ³¿»JÕŠ¯^à%EXk²Ú_1Ng”†–òêÓÕ:†½^ûéìøá*ÈÌ
+º $Ês7~v’ÍÃ6o6ÇâÐuåêÝÜDK”¦ü°õõ‰e ¦"Šjl"á
+„²®óø¸rw=k;ús§|¹›³aÆ{bðX%J8¢’, {Gµ È”›CýŒ %–Ç1Ö§ºŒ±Žê<G/E¹ÝdÇíX<†ÕÏRˆfÄFaA)ð°ùiz€´¾#áÒx %/â‚‘šª¥¼uô FOù~>Þ¤BLRüŽjI‘ ·8Þ¸uû >­OÁ[ :ÏxÜüñX´¯SÀÁ²Hy\~ š‘?¤
+I¦Ð tT3* @Çb<éð6uÎ’qÉ…¢ô2ê(”†lΓ/=áúÙciŠ†|%:øÕ‚SnqÈQÁ—.¹¹UrÊHÜVM“oøyÎ_ÍLÕU9Mç,TªÔè¨fôàNhdÊöoãë.Z3)—¡¬¦’]¤×) êÀâúý‚íS¾Ÿ?N‘ä1±I訙r‹ã/…J_Òø‰"èóDF\{|MÚÍ!9æ»cÞ<Mc,FP푨ôŽh*~a!{J ä¿ èf¬X‰¤â‘øJ€*œžÑðêÉãO¸þ…„jÆUtÜ;¢-Ƽ¢0c’Cü%<Ž³>Õe uTÖ1dmö5ùdN N)‹ D3‚‡N#Ž™JþtÈ7Åîõ:¡,l¶Rm7¤]
+µ$M[M Ñc ~Ïú C³÷¯Òõ}Û´çOvuYÖ/S¤'ž1'aOFsìW(”XiXà…_@_¬ÖF{"Ý°ù…’ûx°=¹Ýå¥D­3ß™¹Ÿ²hZ÷dÇ^žŠ6oÙ&O¶yYì ÿ©\)±˜o1tüœ¦äøŒtÙæU[$n#:è=؇6›}r¢¥wðpž(Û ùÕµ)ë×YµumYõêšÓC“ÿv1î½ÓÒÓ9ûÝË!kìÛŽÁãÉl…5ê¸:¾ûÁÎ ÌÂp_}<êÆ Þdîç%{u®÷‘õØWž%ópÄ„*¥[ìv*ÃçóÀ‹öü$A§a³å‹ãCûÅÜŽ>Än%C¦ù•áGÃñpÖ_^ãuãž«¬-~÷â‹*Ùçûúøê^Ý(l“‡2ƒµu¯ASo2+Á‚Âò˜lÈê<È çöˆ¢Ì`ØÛìÙÒ`BgGë# ¯]àlý{Vžì) ¥g¨˜ŽCݘ „Üu;ךm·…ñíYéÚû…­·Gˆ£çödΈlóCžW®­,ªg»š pR»Vï°ØºÉð½9*´ç‰xý©ÞÏb¬ÉÌáGHz¶= Û”§m€àKÑ>ÁU_õp:G+xv•uq–Á€>¦^CX·Ð»w(SH¥|!îô©.ÇŽÊzÊ&ñ0«  HÀyTl šÛ_ ‚Ž9þˆ}£lºS~rꨈ$40Àg``l“*Ð/Ø:åûÙ9 Ñð&*>æÕ’"nÑ´†Â
+ç‹è:EÀå‰ìôäeþ˜Ó“Ù¢(ȼH\zG4?܃§H:”ï»&LÒìÑ<óµÕĶf‡CY¸è)|\îÖúh) '9=¸'>›0&×·;ß›{zà0   ‡È×¼™+ö$TüDã…ñé°0*¯Z0Ã¥NFÖKQ–Þˆ²ñšûˆj7ðS­F™‚YU3ïõŒw¶¿ÞyÁ:Æç¸;žÍ.¨º'£ÜlÀè–úœzÖ6Ã1@*V+¢¢)[Z“}Òÿ`ŠÌ)_£Õ±®Ûd „š}Ç” 4š.É@5£ÇÐ7Œ¹E—¤9AN9‹/ÉÑå%ˆìmŽúø2sþª)"æòELh ™
+x{˜ùT¨Ð.”òõ>Ï*Hèw§ÒÇñk÷QœwÕƒ qM™ûqšÛìÔ§ Ì&à6Ú3»Ög®žðÉT„„íÂf ¡à+eØ^¶Y“¹É ¬ñ²:˺~† ãô®]g¸$c4†€ñpõe;s]'!æ:ËñÕ–4Db¿²e:1Ît:ÿyÛvŸTµk̪æÅ¥;&¿””åü`$Tw%(”3£`o9…Qx©O¥—Ÿ™2ÌëäZªú¸7Yœi
+Ãam«][pED”*Á†Å¤Mùö2îSsÀDÉð{TäªôÍøŽ=OjîéøÇdwT3ÂÞleÊ,¾ô]í„}3]Cæy„Ï·>ùWTš'STÂDz~°£ mC  ãùµ EÐYø­ “ôÛ†®R
+:Øô(2÷êK'ÓU3`¢\#I wÃÎÞd²«‚8%¢ i®„%÷°QíQÕÝ ª`™{/m»„Ún. òÆ?ÏÉvµõu#gÒI›ZÎ¥ún˜¸ÛøˆK,Ì:’ 9RŸê2.;*›þ±³Ú$¶(§:.=ÍHoÿ€Ó"Cñÿ½ÖÄ&ò
+·‹ƒ5³1-®l5OÊuøš×&l™;⦷Êö¹k2HêuÁÃ|Væ3aC[Ö®ç甧¿Ö§#T†ðˆCcJJÏÕκiܾ‚€b㕵G8ZpI¹y] (oÿ÷þ¹G_† wËŠÇÊmzØLP§,b\cÇj‚\J­O›vü3Þ4ÙetîÂkož£ ¦™[
+±KKÎYryͤöÔxáP¨OY3j°fÚý!ñÃ9¹q‘b|A‰ŽjF‹¡SH1R£[;Îýx/RmëÍ©9´îUµ¡ð?ßvVf§ëÛˆÛK¤úòÝP‰Èâµ½Qäf¨'²ò¨ïhˆk)Ä„š©ÐA¶©¹Ôl ôO7TX>ŠôvæT·–¾lÜ«›~W µHV6 ±¿>ÎnóÊTn)÷e¡ÂC®6Ö˜ÏC¯Aù%v?È9ÈŠ¥Öà çÒêE0"áHͯOÈEµ¹¼>^ŸÎ?˜ødÁâwüúõš©f7ÙCØÚ
+å訒H¶|œ }óÆùÍðÒuºãñ‹×º98fÊâœÃÞGæ¶ý œàÏ{¶¿}©ÿü?`,¨R²8bî1*³“ã”2Úk6]~þöÿTõÿaØ—Úendstream
endobj
-1474 0 obj <<
+1882 0 obj <<
/Type /Page
-/Contents 1475 0 R
-/Resources 1473 0 R
+/Contents 1883 0 R
+/Resources 1881 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1486 0 R
-/Annots [ 1477 0 R 1478 0 R 1479 0 R 1480 0 R 1481 0 R 1482 0 R 1483 0 R 1484 0 R 1485 0 R ]
+/Parent 1853 0 R
+/Annots [ 1885 0 R 1886 0 R 1887 0 R 1888 0 R 1889 0 R 1890 0 R 1891 0 R 1892 0 R 1893 0 R 1894 0 R ]
>> endobj
-1477 0 obj <<
+1885 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [286.0435 683.3704 354.7155 695.4301]
+/Rect [257.6971 713.6209 326.3691 725.6806]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1478 0 obj <<
+1886 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [339.144 653.1199 407.816 665.1795]
+/Rect [310.7975 683.3704 379.4695 695.4301]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1479 0 obj <<
+1887 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [336.952 622.8694 405.624 634.929]
+/Rect [308.6055 653.1199 377.2775 665.1795]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1480 0 obj <<
+1888 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [322.5463 592.6189 391.2183 604.6785]
+/Rect [294.1999 622.8694 362.8719 634.929]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1481 0 obj <<
+1889 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [331.4327 562.3684 400.1047 574.428]
+/Rect [303.0862 592.6189 371.7582 604.6785]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1482 0 obj <<
+1890 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [361.2812 532.1179 429.9532 544.1775]
+/Rect [332.9347 562.3684 401.6067 574.428]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1483 0 obj <<
+1891 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [330.3165 501.8674 398.9885 513.927]
+/Rect [386.0748 532.1179 454.7468 544.1775]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1484 0 obj <<
+1892 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [259.4835 344.9998 328.1555 357.0595]
+/Rect [301.97 501.8674 370.642 513.927]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1485 0 obj <<
+1893 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [231.137 344.9998 299.809 357.0595]
+/Subtype /Link
+/A << /S /GoTo /D (boolean_options) >>
+>> endobj
+1894 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [172.152 284.6583 267.6829 296.4589]
+/Rect [143.8055 284.6583 239.3365 296.4589]
/Subtype /Link
/A << /S /GoTo /D (root_delegation_only) >>
>> endobj
-1476 0 obj <<
-/D [1474 0 R /XYZ 85.0394 794.5015 null]
+1884 0 obj <<
+/D [1882 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1473 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F48 953 0 R /F41 939 0 R >>
+1881 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F48 1228 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1489 0 obj <<
-/Length 2563
+1897 0 obj <<
+/Length 2840
/Filter /FlateDecode
>>
stream
-xÚµ[]sÛ6}÷¯Ð£=añýñ˜¦NÖmºëxŸº}P-:áÆ–¼’œÔýõ{!@òTžLFuxqîá%
-/äg¿þFgKýÓ%ÂY5û_(aÎñÙÙT‚()D8söéì_1`òëþÒ±þ“ÊÅ¥†žDXíÆ{™Ã€Œd„1€‡^æl¬—Ê÷òÃâù×O›Õâ~¾mÿl†²™„*=KCh„
-ïÿˆª1)¢y&¤°zï'Ã(Ñ’ÕL— ÓTHÖn³XmïšÍ³çó]ûÐÌËŒ0E‰²83B#³žRDi&r§³Þ”š èa bA ¥B±\2fÁ€¯È/ãNYÐ )I®‰ŒãYˆ¨
-‘2ê@m·v w`Ššv`Dæ¬]Þ:PbU8“ˆ¡’»ã —Wra¢hèBA4µ|Ú…J͸ÉDc. øŠü2î \Èw ÍCDUˆ”ÑpJÒ²âÂ…¸0 ¦+ÇúiWBx80à‰R‰¨.™ 5TêM’yÍbØKò Œ8èþi#È“ ¹l̈_é€2îñF†8ê*¦ˆ¨
-‘2nDæçBWŒ˜ #Ôtñ5"ŒC¥«P‰¨.y=´D: ó׌èÐz8nDç”p<–ñU"Uƒ>•;xE}õ&ä0Žð70–…ˆªð(£¡&TÖ£¨ÅM˜¢¦MQ¾ÅÕz×Þ=›µ’m-Þl
-À0ëöÂi±p‹Á­a©%(Äd•¤h·žo׋ÒfRàÍGÔHû¹Ñ1V™œÀIv1h&“šr†XÍ
-"úІ¹0¡ÒÜ|)jÚ|Òåë8<ðæ«õ²)Ë^÷‚Œã"j„Cf<)eVå$N3D•2œmCò…DV÷„"Tk–©Å\ðÝeܸŽj˜5k‡g ¢*LÊh¸ñ„ƒÉ£ª¼oKQˆñj˜­0qŸ‚G›(ˆ!’/2ÃÃV39½ûr=Å
-³ F!ëË0ÙrZdŠÑõå_Ñ^Æ}% ½•ax"ªÂ¤Œ†;:ÿªºò¾-E! ¨aÆvÏ#Û `(ã3œADPÈ7À€+•s8½÷‚’áFݽڜÞh
-xeOAÂó˜=ÔVÔQ_º§@ 9ˆ œE w˜ÇWy—¢ÿ”oñiÛÌ­‚Þ5Ü÷F&¢FØäs_°*…SÓ<ˆ+¢Š °$ŒYLÁ0ðìÌ„£Sà_é‚2îñN”à&ðTP…F w"N~³îÄ…81 ’7ªÞƒMk­ÐHëùüƒçŒÈ›?å—i¯iN,Cö×s' œ°™PìµpÀW4—qŸz(G N ¼ï#ªB¤Œ†ºÍ)bœ¨,3' i¯P‘¥Ñ%&ˆXëS¶^¬²%²æ_ÁjãÏW¿È¢˜ÁYœ³©ÐÚ‹‡ãš‹¨Ç[ ….A;>‚*,†±ð]£0æµ-ôƒìí0ûÍ•íj¾iî6ÍöË~ƒï›N»ßs9vzÞmžKl8YŽŽÑTKŒ|Äìó‘&Ê“Òß›”¹Þ¤þ 3©?QJú]ÓÚoÞ­!~Šh”Ü0fæ&Ocr½NÁ‹ûQ–Ý€A9 #{),ê*âÿdm¤5øß¿jþËwø³A >·vb”éx¤… =)OÜÈò. „ ÍG¨ÿ(¾endstream
+xÚÅZKsã6¾ûWè(W
+œ–êŽÕ³$ ø3ö×ý $ä,éü>DÐ5kÍ’Pƒ wól¦)A(®¬ÅÃë€nB‚f:™Ú€†R;d)’ÒtÄ~®”ïo0\÷ ˆœ"„>㩶mûfxÕÀç-¬:yÕ]‚+õ7 y-kͳJ+f„<sÙh£fxQ§½Ymòm6¤\ƒ\â’yé jD|‡`JÃE„›®ü/É°“=ÑÚ²Äq=À D´„ wÛ‚¹ñgL®;I5=,1ƒrÅÌ;¿AÓd°Ú<Ý$ÀÂœ¹U´Q3t‹¨ÖFªU]eC¾%ànçÅ7¨ù]¾Y¸JHÑUàËÔp3z²áÄ0\ŠÂæ°¾l›0K¸€?cópÝÏÏmpÿ7ø`Öù êœ"ƒÕfù¦œ”;sh£¦ùÖ Pâóñþc>rnÂ4nõ¼Ü5"¸C4©˜µ0Ú‘|ƒþNUü -ûžV
+f9=ºW§ž2eÊšXLœvf…áµû¢®Sº™±ÉHÁ‚t+{,k\Ó0®ž¤ÞR#ÎÜxÛ¨iÒ5(o)Ãl³Ùçu©§Üä¼ jDî þºÓÑãÇr‹1mõr—g%$¿‡#ÂÆý‡¿k‘ã=øô™C ³¼#r
+ÿ:s<!`(²
+º~?B¾ ¹e…ŸlµÔ‘EôÃAýT·¸É*%êÁ³ÎK”ª m;ô¨õq_ŸòvW]míÐGÖªAŠ¬ôéÑ-¯h¨Œà|÷|x¥f0S™ö
+ÞÐjŽh‡ „ž?øûÐöu,q®«éûxl’x›»ÙsþµÞ?/†Ÿ%_ŠÃSÀÔuµ.²C €Çí1̾
+¤ä¿‚ÿâ"^Ǹ¤Ì;„
+§—ùÙîy‹ÁŒeñ€½jù œa„­«¾€Ïž1êÍÂhFä×¥X6Ã>:i±EvaKÀéϱ¸
+³Ë°œ„üòõæÞ~ýµ‰óiLÙH¶–íbÝ9–ýŸðR¦ ‡¶ùMo«ªí¶z¡r‚\7ÊZ÷yÌP !ü{ßk,mµWêLiUÜ/:KZ›Ô5œh‚ÏÎHÇEbbæ=N^qìÈ,Ï)l ·¥çÄ×îžò’¤IŒYª65u6U ¾´]†ïÇÉ…-L%§5 È?…)e¶ËÃRG(ÿöþä‡Õ€…I¨÷ЮÔQ$d@–k ņˆ_hU%š³ÛÁªòPM==0Õ½RÓ'l`,½¼¼\:¹dƒC
+vNØ´›9O™§›]fëØðüN—ÙñðTí TØG! Åõü‹Ï@Ï´gŒÄäI“ 7ê
+ÍHbë³iÒ>Ý?ù”€ËWôÄÄ«·Y1½[•HCw«á‰a“IóÛ%ê²ûôš0©Tü¦_æù&¬ê#Aš(Ò´¥5Œ>Áx`ï6_È妅€Ûeó8£kÔÇgÈ;¨…|u=½õ» e ² lÇ õq½
+ÊvÉ›²]Æ\ˆ£T¶Kúš²]6ÕšpÝ*Mò‘B@¤¯l
+uèò…º …:¼‡B]ÆX€®îöÊilŒ¡±­Š\ î+ò$MÇ+r„{ÂÃsX‘coF3Z¥ËøÔ†r[¡ìH#ïÅ~¡r3¦=Í‘#j]ÔG«t.™4Zÿ%F›D™ÿg‰Ç;sôñ£ÅÊé½çMöy÷i¶Ìû«ÑD3üSÏ‘Úþ’þö_”žþÜV¥,±“ŽÃ ä—F¥ÐB7ø¥F'–i+ÓÕÿ­™õendstream
endobj
-1488 0 obj <<
+1896 0 obj <<
/Type /Page
-/Contents 1489 0 R
-/Resources 1487 0 R
+/Contents 1897 0 R
+/Resources 1895 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1486 0 R
-/Annots [ 1491 0 R 1492 0 R 1493 0 R 1494 0 R 1495 0 R 1496 0 R 1497 0 R 1498 0 R 1499 0 R 1500 0 R 1501 0 R 1502 0 R 1503 0 R 1504 0 R 1505 0 R 1506 0 R 1507 0 R 1508 0 R 1509 0 R 1510 0 R ]
+/Parent 1853 0 R
+/Annots [ 1899 0 R 1900 0 R 1901 0 R 1902 0 R 1903 0 R 1904 0 R 1905 0 R 1906 0 R ]
>> endobj
-1491 0 obj <<
+1899 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [324.1075 737.309 397.7608 749.3686]
+/Rect [352.4539 736.7854 426.1073 748.845]
/Subtype /Link
/A << /S /GoTo /D (server_resource_limits) >>
>> endobj
-1492 0 obj <<
+1900 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [359.1555 706.8362 427.8275 718.8959]
+/Rect [387.5019 705.7889 456.1739 717.8486]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1493 0 obj <<
+1901 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [353.6164 676.3634 422.2884 688.4231]
+/Rect [381.9629 674.7925 450.6349 686.8522]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1494 0 obj <<
+1902 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [370.2338 645.8907 438.9058 657.9503]
+/Rect [398.5803 643.7961 467.2523 655.8558]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1495 0 obj <<
+1903 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [364.6948 615.4179 433.3668 627.4775]
+/Rect [393.0412 612.7997 461.7132 624.8594]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1496 0 obj <<
+1904 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [226.7331 584.9451 295.4051 597.0048]
+/Rect [255.0796 581.8033 323.7516 593.8629]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1497 0 obj <<
+1905 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [283.1811 554.4724 356.8344 566.532]
+/Rect [311.5276 550.8069 385.1809 562.8665]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1498 0 obj <<
+1906 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [287.6042 523.9996 356.2762 536.0592]
+/Rect [315.9507 519.8105 384.6227 531.8701]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1499 0 obj <<
+1898 0 obj <<
+/D [1896 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+1895 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F48 1228 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1909 0 obj <<
+/Length 3202
+/Filter /FlateDecode
+>>
+stream
+xÚµ[Ksã6¾ûWè¹j…àIÉi2ñd'•L²ïe“8msW"'"eóë·ñ4AP S™”Ë%üØèFhtSYaø#+Q BQµ*G±Ú.ðêî}wAfãA›1ê››‹/ß°r¥*h±º¹É’KIV7»_Ö¢è$àõëŸÞ½yûÝ¿¯_]–|}óö§w—*ðúÍÛ®lë»ëW?þøêúrC¤ ë×ÿ|õóÍÕµ½U8ß¼}÷­íQöãŒÐë«7W×Wï^_]þvóýÅÕM°el/ÁLòûÅ/¿áÕÌþþ#¦¤X=ÂFD)º:\pÁàŒùžýÅû‹£»æÑÙù#QVЙ ¤t4’ ¡”X•B¡‚Qf&ðæ¾îk°ª$ëã%‘ëzÛ™Ï]o;+Ûk/šv¨mµß?ÙëS_ïlkèÆ2únÿài«CíDÚ]}tð{w»ª¡ÙnúáôÁvüѵ5xƒ•lý¦;úaÖnëèËrÝÜ> ù‡IØ‚”ÔXÔ×Ç3Ž*½Iuó`”Pr]Ù¿Ÿêã“mÞvü+¥üñññRÑ5ª?U‡ûm»ƒî¶Ï>6ý…Zý¡qý­ýüÐ Óµ %Ãê2Ö§i›¡©†Úbv§cúÍ™fó44VpQÄSÌ83z·= :·õ`uÖ7«v÷¥6qê€t¨=¨?ßþìÜíÜH}Ý»¡A˜ß×­mõ5ôEªÛ…©'¸1“ëÅ°>Ń텙vø<tbº÷@Ä=æ¸ ÍH”,;‚JBŠ¬=$eyf•XÌf²k„Ì2„jî6Õ¾Ù5ÃÓÆ,¸šª@x‰8'eV‡
+‘Û!H*D¬Ãççž·d2| 3ÀI&ðQŒ
+‰IdlŽv¿`v*÷å´c°32ŽUÞµ¤I"-K;Q(Ä
+¨þ²´£ÎÓ. ôˆÃ±jûÛÚd™›¾;·)ó(”We¹ D@Íh1*Xo->ñÎØ2åÔ”¥È$yX"ÈXIdnŽ{¿`x*÷÷ÊÙ(L ‘÷@@-)’HËS’).%_ Þ•¡žGq×桘Ëø8 zÔŒ"ÓŒ©2VäocŸ3gšõqD ãÙ¬ORF"‹²>ƒ_°=•ûbrL‘ÀTäP Š¤ÒòÄ%*ðR};FeèQzÄj?l^ÿD,BD^‘€šÑ$f G\Q«òyêÜŒAS
+Ä°¢BE¸ŒlÎrÐá¬Oåþ rð!gy7Ô‚"©´,y©ë”…¬o:Ï@Êøk.
+
+ˆ[\‰¬"”j¿g‘ˆÁn©ò·p>*¥÷à  S6Òs‚ž·>‘úr2HÙJ̲> ¼‰¬<û8Dn ô¡2üó(=⩯7/‚š5TÏ[N™€šÑ&®}ªº"u>ÏF¼`TR
+‘xþ&vɬ´²€"“e* À*N"˳¥…Ã/ÌA*7"¤¶Ö2-.JÈ „Ì;# I¥Y>n
+ÁÍq„wÝS Ö3î`ÉÄÀ|Йè¯tÆg4^àXѾ%C­w¨úòòÔq ªQxXeÏXL$˜Ò;·ßWs©–©¯BV¿½ïš­?–Q^Àêzªf_}Øû“Ãd{þ#œàØ×õ™ógÖ7-‚:|á•éu~}”¶ãõÌõÕŸæ²dQòüè43zœ%S$$-ÑðŸ§>KŒ˜fÉP–Df²d¨Øìãc²Y²Ã/ØœÊ=“±Ì a¼dù™¨5RiÙ½æ|¸6Be¸æQfõ†n³kû¾Þ¦LÃò–< fF¸FL‹xøÿÀzƒË `m»öWŒéÝÉ.Üí5Øtc÷ÔV‡fk/¾}÷^7Ę'ÛSíûζNúX•n ÷ÝùH÷vþ}÷h›Õñ©iï¬Äý%Yë¥ßÛKËtýêÁöHâð¨'ï ÏøYÞ€Vï¯^Û6ÐßgsmuWêvÐ'ÿևǡ)ŠS·âÛÖǮúz@Ãþ«™e§Ï¦I¤(‰CAkf ýzîí0øAgv~¬‡fèí3 ½i¹é‚žµý<}ÜUƒqcîÈãn߇?uëödNRê»ÖBóm±òñ¾nksrP_…ÇÁwG;ß^¹x;êûS8vçƒÓ¶;Â$x´ ±Ý9?iE,\ˆè ’”øùЖèó3Ça—£Ø[hn;%P…@þ-¼oŠÔ7” GÓðÿõì++“çüf»?íŒõÔŸ1¥@Ÿ݃)h¹þpì]»LË3ÔkÕOìþ{ê‡XŽ=šú…ë <¦Ø2Áx$è…41“Òu¿½¯w§½W¥Úú£¶faiÄÐECR#ú ××îPp¬²W:éë´
+‚ªœêº“”)L¿¾õøÍø¹o.¦rµ‘ÖePø®nµFr./°§œ(t:sf
+P šp ÄaÀ²HGôøt DCJþ©ø%¹£©0éPŸ 9$?µ J*M«¢ÇE–›Iå$\Ü؃Ø4" üåD–qˆ€'Î…¨t9DŒU^ÀÖÏ Ïì‰Ä@ZÖn.Ë…½SŸåÚÓèt½ïªmÙh­[6[ïöjðöÛÍ(œ`‡½¥1Y™¹i‚øØæ•^Á`'p/šN'®ðI2´Ü¡qhA|±ؽ2…«9ÌÍçsöp™ÖC=5I!(Â'Þ(Œ©>M<TŒ/óH#e="™xGxx?g=R£I±Yh¡0ŸÄP™óå©Ÿ¨ÛlõMj'Ϙ½¬‡ÒÌÞýµµqž»àËÖÝvk2 èjZÛåF‡Të4¸ÜËqå÷¶6çÿ±ëìþÃ\A¥•ñ¤ÁsdÑ)ÍÉ0#ª­šL«þ©
+±*&kÔóEJ“bé–‚qê]½ƒô“Saß ütsõ•Eݘ$Y£|’¬{mŸtn†›OõàîèWèl¶Þ}­ "ªp«‚\æÓX
+endobj
+1908 0 obj <<
+/Type /Page
+/Contents 1909 0 R
+/Resources 1907 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1927 0 R
+/Annots [ 1911 0 R 1912 0 R 1913 0 R 1914 0 R 1915 0 R 1916 0 R 1917 0 R 1918 0 R 1919 0 R 1920 0 R 1921 0 R 1922 0 R 1923 0 R 1924 0 R 1925 0 R 1926 0 R ]
+>> endobj
+1911 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [352.879 396.7158 426.5323 408.7754]
+/Rect [352.879 689.0814 426.5323 701.141]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1500 0 obj <<
+1912 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [334.0699 366.243 407.7232 378.3026]
+/Rect [334.0699 658.2017 407.7232 670.2613]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1501 0 obj <<
+1913 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [373.9 335.7702 447.5533 347.8299]
+/Rect [373.9 627.3219 447.5533 639.3816]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1502 0 obj <<
+1914 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [319.6839 305.2975 393.3372 317.3571]
+/Rect [319.6839 596.4422 393.3372 608.5018]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1503 0 obj <<
+1915 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [307.1508 274.8247 375.8228 286.8843]
+/Rect [307.1508 565.5625 375.8228 577.6221]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1504 0 obj <<
+1916 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [334.8268 244.3519 403.4988 256.4115]
+/Rect [334.8268 534.6827 403.4988 546.7424]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1505 0 obj <<
+1917 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [337.0185 213.8792 405.6905 225.9388]
+/Rect [337.0185 503.803 405.6905 515.8626]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1506 0 obj <<
+1918 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [364.6945 183.4064 433.3665 195.466]
+/Rect [364.6945 472.9233 433.3665 484.9829]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1507 0 obj <<
+1919 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [374.6372 152.9336 443.3092 164.9932]
+/Rect [374.6372 442.0436 443.3092 454.1032]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1508 0 obj <<
+1920 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [292.0276 122.4608 360.6996 134.5205]
+/Rect [292.0276 411.1638 360.6996 423.2235]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1509 0 obj <<
+1921 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [319.7036 91.9881 388.3756 104.0477]
+/Rect [319.7036 380.2841 388.3756 392.3437]
/Subtype /Link
/A << /S /GoTo /D (zone_transfers) >>
>> endobj
-1510 0 obj <<
+1922 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [460.1655 61.5153 533.2211 73.5749]
+/Rect [460.1655 349.4044 533.2211 361.464]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1490 0 obj <<
-/D [1488 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-1487 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F48 953 0 R >>
-/ProcSet [ /PDF /Text ]
->> endobj
-1513 0 obj <<
-/Length 3476
-/Filter /FlateDecode
->>
-stream
-xÚµZ_sã¶÷§ÐäIž±
-åÚSNpÁtªPˆW©µ'Kš2.Täg×ûšÃ±Hq=Òœ·3jÜö ПكC¾´ y¯."WÄL실bèŒetú0ÕA¹¡ `2±Vó_¸æ7MN&ëèhðŒbiYÄ°¦,ÕZ¾öH”IÂL"݉¬³¶+¶ÁþéØ“eõr‚“H&ñ‡ÛVÙS1ÅI²(1±£Ê›å²!³‚ôR7ë}ÊÊ*»¯\æº-p±ñï¦v­ªx**»xpˆÞtaǙѱ:mßCªãö¨PÅ ìõ
-p=´Ã@Å.õéTçä8àvj
-†Çg 6 :5OÕG„_8—U±X5Û5øß}ÄW€fN ¨&¤!.Äqf#1þ÷vD™= ÀÈy¢O
-JÎùü›—:[—9éðÓf™uîlª2/'óD>[HÅ Ï$ëªÛjín³i¶æ
-2¥ç†º³
-Ž·Îºò© ŽuÑ=6Ë–^
-Ú„Äçœy•íZLŸy2n¶[jR6[ûÑì…™£)± àñ|CZ<•ÍÎ<Û”to"|"$5ßwô´¸rd°55=ºì>°¾Ÿ²ŸøZ—m,Þ ž»ÕdõËp»óÆ>—ÁŽ‰j«1¶Êz"of¡çOÅ°4 …Â+`5gºw.2ŠæeKϺxv(X$½‘COJ„+5nÚº E¼¡ùÔÅv¾¬ G VÕYš¦"Æ œ =Û’
-[½½"Ç’NHä\ŒOÈJP,ñÀe4ƒ¨çmaKåv]Á‰˜ù®¢jF“¢Ð‹Q¢ ÅÒJ b€ó)úbGÏ‹,ñpÝ%œÖ–<ºì‚[_uY¸¾;®cå©\}ÔO {8áž0ÈÀhBŸQóû‚ÞiÏ–®ó…:‰96¶408 è-AÄ®ì@JØ;pçó÷+"#EïFÃDAl~ÛmGƒ X›=¸ÑÒ Ù–tòÐÆúÙVÍ#½((•­óReçí!¯vK_zö; ÆC»ïß9«rÐKp[aNØ ö_íY™Û€—±}†a+¾cŸgÎDïCŠÓá¡Ö¼‘«Ò­ÃZœ *gx
-(ÆØ\F‹¬ö†\Z9X”VN˜õÇÂÖªéj¨%µ0¢£XˆL×C5nRhlRht<à\leÇ2zÜ}wýOjŸòǬ~pS­Æ% i€b¥¦—= à™ÓaIǶ}ÌzÃ@A GYÓ1+Ôøf‹mÅûá[5d릷nÈæPÑ­¬Ýcwf5ÚxÔVT‘[V; ‚¹9)>œewtBG¿¿Q±Ûxé\ŠÔXæ¶ õ8“€,¥xhºÒ2´F{¡Em’
-[te$çï>|X ¾®èõù±$#“ÿtÙ}U¶ÎoBbä.¢}£_Ø¢ƒ )ú£÷~Wl煮mZêH_çå&«è÷ŸaÝ„ p܆÷GêΦ~–&aqî¹¾
-*ŒO›¬n]%–Â|7Å¥ÃÜÍ`Œ®*ê/OYPV±¿Ïl<é°’Ÿ@÷ÝäÞŠª’þŸØ\ÍY$BUÑ;òQÐÀ›ÌÇr—eÛôpñÛ.«FŸ@Òß¹kÈÎ:±¹þÔ}×XtÃtª¯¹LãB„Ñ.89QlIϧ¬g<•õŤ 9‚‡Ka©‚ßÄÑÕüú'òBvÜ>Llx…™y5+´å”þ 3øÊk…šÎVH5õ{¸€zSâfT {#Tîóû¸½×Gs±³»½P‰dJ&ñجÖí1–¯Ñ35Á¤Hº€0øƒpøÂã,?ì·D°äõÂJ‰­cPžˆ£žœÌ‰Gçpðkª€,Váo!Bkë×|{)Þì}{ö¿Íòb`Ýí,ý¨4/×ô3ƬA%hᙤIøÕo¼‡*‚
-Ý(qw9Øåß5÷…­GúF–ã‹
-39¦!ÃQBaÄýÞ·w%{$,,ûËÑc~9fý—
-ÃÂeô+-ÞºÅ`aÃø¼ÃEE¿âøà…£ÿKÕ9¼Hûœ8qÆ ñ÷gbxO&†µ½ð—¾`ņÿ=Kô(Cˆ¹g›ÑÃJ´˜‚QŸ 4««ñEÿ‚®>BÂÆ•T(„góGA(ÒÌÄZÿ–~ÆQAHã(=ƒ ’2üEûLž±ŸIsiU¸@9¶ÕP%$z?_‹bªãñ’î(¦¤;mÒqÒ=ä ;ÜeAP‡M“ýb—ÊT9p‡jè•ôîPI_WJ}¤tÐÇÎ
-endobj
-1512 0 obj <<
-/Type /Page
-/Contents 1513 0 R
-/Resources 1511 0 R
-/MediaBox [0 0 595.2756 841.8898]
-/Parent 1486 0 R
-/Annots [ 1515 0 R 1516 0 R 1517 0 R 1518 0 R ]
->> endobj
-1515 0 obj <<
+1923 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [397.3443 737.8938 467.1586 749.9535]
+/Rect [368.9978 318.5246 438.8121 330.5843]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1516 0 obj <<
+1924 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [321.49 696.0508 382.69 708.1104]
+/Rect [293.1435 275.6898 354.3435 287.7494]
/Subtype /Link
/A << /S /GoTo /D (options) >>
>> endobj
-1517 0 obj <<
+1925 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [329.3035 171.0954 407.7186 183.155]
+/Subtype /Link
+/A << /S /GoTo /D (man.dnssec-keygen) >>
+>> endobj
+1926 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [317.0267 666.1628 385.6987 678.2225]
+/Rect [427.0093 171.0954 505.4243 183.155]
+/Subtype /Link
+/A << /S /GoTo /D (man.dnssec-settime) >>
+>> endobj
+1910 0 obj <<
+/D [1908 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+1907 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F48 1228 0 R /F55 1311 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+1930 0 obj <<
+/Length 3378
+/Filter /FlateDecode
+>>
+stream
+xÚ­]sã¶ñÝ¿B“—Ê3 ì½Ô¹ø.N_j;Óé$y EZb"u"eÇiûß»‹]€¢ä뤓¹X,û]Èr&à?9ÓÊAÎâ$ô”j¶Üœ‰Ù
+Ö>œIÆYX¤Eëëû³7ïƒx–xIäG³ûÇ-í ­åì>ûyþîÛËï¯nϾóÈ;_¨HÌ¿¾¾ù† }Þ}¼yýá§ÛËó8œß_¼!ðíÕû«Û«›wWç ©•„ý>S8²áýõ_¯hôáöò‡.oϽÿîìêÞÉÒ—WŠ
+¤† 1Ï+ U¾
+>£ª[v)?ð|?d8ÚTæO)ªc®qÞ­Û_ý…Uæ"Ëé’šª£ lÖ¡«µ¾@‘:ö­7w…Æ‹­0ˆ¶YDsoó\´ËµÉ0«y€¼‡;ëÍfºÞó}(ÚÃ@c*P{‹`¨Â²^¦åÛ Q€žˆÅôÌ]›Ìï £…)±1HS™
+;«ÈC’¡—h9AÒèqâuMx
+¢æ zÁð&¨uŠÇÄëBj†æH3ˆå”í…£f‹óXq·Dc“"ªŠ’H¬(‰À—oE)‰†Í ÔS$ÚŠ l¥[ÊáõvWpU:(³ÍN¸†Ò{6òŸföÄ”yrу4í1¦¹±œMTŸÆ¡r xÒÈ4¾8Çɹ©“Mµ$smT ó?5ãm ¥n3~.Ê’FLÔt;ý³m¢ X0:àp¹N«@ݤcеœGÂàH§i¢ê²iö2hƒóÜ _mè{˜\UnQœzÛ ×( œÉ—L+ýç‰T7*‡wá"‚fñ_ô1  ;fhn*ÛýM@UoiôŸ·ÓïZðÈB®Óæ— c·5Ö±Ú¦Óªé¿,ʉT
+“<qõ }¸ËDÝýf{‡Ø  Õ(?J³åöMÛ³áÉG«S†¹Ÿòí¤ïšºçìË)!užl )M¡"É–N6(¸¸ÁŸ‚Kþ©à‚öñ½Žl ÃepÈãh‰»·Þùƒ¾cEXP½e4Â[Ù¢òÌ@觃Ä]Ÿ8î]Ÿ˜x ¹˜-³–rÑöýÕ?h”ÿfK)œ™4ŒG<`g6I1æ
+endobj
+1929 0 obj <<
+/Type /Page
+/Contents 1930 0 R
+/Resources 1928 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1927 0 R
+/Annots [ 1932 0 R 1933 0 R 1934 0 R ]
+>> endobj
+1932 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [317.0267 736.8562 385.6987 748.9158]
/Subtype /Link
/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1518 0 obj <<
+1933 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [356.8967 636.2749 430.5501 648.3346]
+/Rect [356.8967 705.9305 430.5501 717.9902]
/Subtype /Link
/A << /S /GoTo /D (tuning) >>
>> endobj
-1514 0 obj <<
-/D [1512 0 R /XYZ 85.0394 794.5015 null]
->> endobj
-478 0 obj <<
-/D [1512 0 R /XYZ 85.0394 622.0858 null]
+1934 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [432.0945 675.005 500.7665 687.0646]
+/Subtype /Link
+/A << /S /GoTo /D (boolean_options) >>
>> endobj
-1118 0 obj <<
-/D [1512 0 R /XYZ 85.0394 597.3039 null]
+1931 0 obj <<
+/D [1929 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1519 0 obj <<
-/D [1512 0 R /XYZ 85.0394 168.0037 null]
+606 0 obj <<
+/D [1929 0 R /XYZ 85.0394 658.3825 null]
>> endobj
-1520 0 obj <<
-/D [1512 0 R /XYZ 85.0394 156.0485 null]
+1318 0 obj <<
+/D [1929 0 R /XYZ 85.0394 632.0762 null]
>> endobj
-1511 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F48 953 0 R /F41 939 0 R /F53 1029 0 R >>
+1928 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F53 1303 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1523 0 obj <<
-/Length 2578
+1937 0 obj <<
+/Length 2611
/Filter /FlateDecode
>>
stream
-xÚÍZKsÛ8¾ûWèHmYž$pôø‘õÔ®œ•5µµó8P±"‰ŠHÅñ¿Ÿn4HQ6í8R®ÀÆ»ñáCwÃbÀáO LÊR'Ý sš.Ì`¾>áƒPöþDÄ:£¦Ò¨[ë—éÉ»+• s©LÓ»N_–qkÅ`ºø#I™bCè'¿ßŒ/‡#ixruý/È ¥LÎÿyöaz9¡‚4Výåz|AGÉùÍøêúýo“³a¦“éõ͘ē˫ËÉåøürø×ôדËi;åî²W8ßÏ'üÅ Xݯ'œ)gÍà>8ÎÉÁúDÅŒVª‘¬NnOþÓvØ) MûÔ¤¹`B5 ØÔ>?.ÁaܘµŠ¥6}<ìHpÇ 7Ð}j5SBg­îµèè^ôÍ™q,URÝW~u‡šyw%e§nÆ™“
-GÇJÓeQÁf¸,Ù m²_yüH“u^Ï—>–Ü/ý†rõ2–oòµ'ÑÌ›$Üoyí$?êÛÁL`LPsÆÈ0ø¼ÜÔ~SC%%uRÞQ+¿»]¦:&…Èâ´‹´+ꇞõÁ¸v*Vü“séW D–’°Ú¾®uÊÓM‹°´§ÝÊŒ åŽ{¥ùqþÅÇM¹
-›øÅiX-,]3‹=­z¶¯¡Aj’jYîC'ŸyLiñT4Œ¹¼¢´_/Bsf Àê5ŠÑ8‡ÇŠI>(æVÐdzfÑÏài$5_¤Í*E«Æúa‹kЂt¤e².«š$ûÊßíW$%€¡4_­Êû
-®$˜·bNpý]R õ1§œi®ÕËÄœf†9Šö UûÙ+¹YÂØr3(>i„U±.VùŽ„
-~ô#l6cô7‘â`©ú HÁ\¹Y=ÄA;˜ %}˜ ©™ËÌ£+ò¨rÇoózœ6à­`&“ ¹ïè³mò,P´Ë˜´Ö|)Ò¢½I,]Ï·£WÙ{gxÁ¢Q梾‚…fã¢x™ñ”›y²û,ìÇ&–~)rÊLÏ?P&ß,¨ÒX?Ar¿,æKÊ>s?V5´ÊÃEî#æâv.{ü¸ %åš¾ÂE +€¤¨‹¼n«] 4_,èN¯*›º<j uǣ㉟]\LØÙäÃÐÉä,®3×Òn‘váZ¯¶ùÜÇ ,ظͭQ¯~•}KÿZÁq
-í¸·æïnÇÏó·ràW‚7ÿSòww[~rþvoÊ߯Ÿ$¶Éxö(Rûÿµj‘™:¦2 ^€$sÜu#¼O"½° &µT·N™î)zW°»–\ëæ®Aêô@8=‘OC ùðd×5jÓÁHÝW5åBèî!N€’»=
-¸á  ö‡•B ­¤õa
-íJA—b£ ÖˆÔi%EŸL*g³Ä+d›l¬ŠFíbpr\Ö±,†ƒ 6ÅkQF]Ù$¯k¿S1@Âu¾hš–$Yø•oº£å02§Øù¢Š¥UUÎ zNCõ2–<p=}rk E_í
-¤Å˜a7p—²!Q, wŠþ¦HCðÖ·=Óe|¿¢Á!×¢opÍ»ƒÇ—±!â7b(¡d›ïÀnÝSœ¾£ÞÚÇ7`½r ÆlÓA3~å¡ep%ñ 0ˆo¥ Éø*Õ÷®®ÀóUJô=ƒóAsº~øÑýð:cÊZÙoeµÖX3+Tw–>™;¾TyÝ7ù¿ùë`endstream
+xÚÍZKsÛ8¾ûWè(m¼ ìÍ;YOmœ¬Ç[{˜%Ñ17’¨i;ž_¿Ýh"%ê‘Ø©šr•`èþúC7(1àð'Æ2ë¥$^3Ã…Lg|ðúÞŸ‰8f\·Gý|{öæJžy+íàö®%Ë1îœÜÎ~Z&Ù$ðáÛ×ï®Þÿûæ|”èáíÕÇëÑX>|wõÏKª½¿9ÿðáüf4ΈáÛœº½¼¡.eü|u}A-žŠ=Bo.ß]Þ\^¿½ý~ûËÙåm³—ö~W¸‘?Î~ûf°í_Î8SÞ™Á<p&¼—ƒÅ™6Š­TÝ2?ûõì_ÀVoxµW‚3©¬ìQ ”}
+4žY%UPàí}†›xóΨÖPá˜I8΀c–é"«žWq`G¦ö,ÊÆÿå\fó¨Øóá}ZRE(*ÓùCVþ¤hÑ’â4“R™Öt=SIÅ<ê”ýÔ#7¯êE—“Y±Hóe(P* èdQOù|6M׳¾ý'ÌIžœ¼¨l~·wkú[¤Àöú–#˜Ó͸“áæ^¾±/ë‰ïÙÝqmu"™–‰Œ…`Þ†.Ê}"OÙ§wBuVw
+¼}‘.«|ZÂigêÏKêYÜðažÑCx#‹=O÷ÙkzXÝÇþzrÔFÛ['Y¾üLpxXÍÒ*›ÑNÊY†³
+S…ÀP?ÓSƒMHÊ”Š·„G„¾ÒÈD]t§'…2f×É ôd[ÃV0ádM]´”ñª˜çÓç[Ëœ·õ±\V0x §¹ÒÕ*K×Èç w5ŸC{1yÌɽÆBÐ/ºº)8TF'Vt•…H²L(1äï
+›MQµØù”O30žR>Ä¡1[¦“9ÍÑèaÛ`%:®6äªP¦TÀ&—3€‰pÃYþ
+ت>V6¢/¯¶#«±QrãÎ5äGO¨]¿ƒõæqýùçeÀ†DKï5°Hî xò|#`zr^jIJN…°“ÜjiIåÚÖœÙÍIŠÑ¨ùmÅX£7Šé¦í€>8à_0Á¹Q‡[,ÍÅø…Öœ±(ÊŠZà<º{˜wù‚øù¼xŠü€cª à
+ɸãîÉØÚ3žSaB˜'ÎY®²i%BÖ¤¨víí! ä É­L÷·^“ϸÑ»prK‚”ái$ã´¬²u^~6ãƒ8eš–Ù~^n3Þk… ? iÖ@¹‰çGRà}•”GîX{SfÛ‰èü°nlRl°÷Ø3$òÈ1DtÞšæ&R$Ù¤H(½I\âÔÅ]ÏlB8Tÿ·ÒyÌ´μŒ·7“¬sãs
+ÖŠåü9NÚMèé $‘šùĨ.‹Àj“}49(- ¼P (`’û 2ã+r žkm@ÔaxÒ‘«þ.TÎñˆÅ°ÌG……ÍEbó}ú˜Qm’QäIEHl±í1O©rûöUBfŽƒîð> [âEV÷„~D¼ 3ˆÕŠnøàá.ô z¢ˆâ·|™W9$Ãõ°«OT¦³êeI ù2ÜoÞ…±×½·‚ç7ìüæÓÈËáùæ‹C¨\}²í.íÃÁ^®Òi°xÞI;ê+K=m;88Wá
endobj
-1522 0 obj <<
+1936 0 obj <<
/Type /Page
-/Contents 1523 0 R
-/Resources 1521 0 R
+/Contents 1937 0 R
+/Resources 1935 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1486 0 R
->> endobj
-1524 0 obj <<
-/D [1522 0 R /XYZ 56.6929 794.5015 null]
->> endobj
-482 0 obj <<
-/D [1522 0 R /XYZ 56.6929 237.323 null]
->> endobj
-1525 0 obj <<
-/D [1522 0 R /XYZ 56.6929 204.9886 null]
+/Parent 1927 0 R
>> endobj
-486 0 obj <<
-/D [1522 0 R /XYZ 56.6929 204.9886 null]
->> endobj
-966 0 obj <<
-/D [1522 0 R /XYZ 56.6929 174.9041 null]
+1938 0 obj <<
+/D [1936 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-490 0 obj <<
-/D [1522 0 R /XYZ 56.6929 117.7253 null]
+1939 0 obj <<
+/D [1936 0 R /XYZ 56.6929 746.113 null]
>> endobj
-1526 0 obj <<
-/D [1522 0 R /XYZ 56.6929 95.1854 null]
+1940 0 obj <<
+/D [1936 0 R /XYZ 56.6929 734.1579 null]
>> endobj
-1521 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R /F53 1029 0 R /F62 1062 0 R /F21 714 0 R >>
-/XObject << /Im2 1051 0 R >>
+1935 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F53 1303 0 R /F41 1208 0 R /F21 930 0 R /F62 1352 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1529 0 obj <<
-/Length 3258
+1943 0 obj <<
+/Length 2894
/Filter /FlateDecode
>>
stream
-xÚÍ]sÛ6òÝ¿BôLÄâ“ îž\$nSÇg»3w×ö–h›SŠÔ‰Tœô×w R¤,ŠéÙž:ž ÁÅö{Ÿ0øã“X‡LZ51V…šq=™-ØäúÞp3m¦]¬ïo¾;“fbC‰hrs×™+YóÉÍü—àøÃÑåÍéÕáThDááTG,øþüâ„ –ÇŸ.ÎÎßÿ|uthTpsþé‚ÀW§g§W§ǧ‡S.•0ôSü÷ÓÅ)!<=üí懃ӛvÉÝmq&q½ÿ;øå76™Ãî~8`¡´±ž< ¹µb²8PZ†ZIÙ@òƒëƒµvzÝÐ]dÒ2u,Ì: ±‹NÚ†‘ÒÑ©\ò8˜§«Ã©d6(ïèyuUQ#+è™Àƒ³ Jk÷ýEéUv_d¿2&fIáAI1÷Hi:ßB¿Mé¹tßO«tõÙáÀ7n¿zÜdá‘\ïªzoB~D™w`e³þú¶\ÒL9­ÖÂís™¬jX²`±Û£
-³¢4ÀÄ‚› *WuVÜ÷G.Öy-s?ÜÑJxš `™®Y]ã~ðõ‡ýå²ÎÙI•…Ç\¯–e•Vþc-fú%YÀüïví¤.Iþªe:Ëî¾ÒKýÔÔJèûÍfë<YÑ{‘&«[Lä¤6òÁM°ÊÜz¡‰L\UuHܸNÓm)—J„<âfb¤àå:W÷j\u´ÅŸv<Чóâ~¯Ó™'˜ÓdD ¹Ü^“â2Œ…P½5=Q•kd%
-¾!¹äý• <oú#Ãô·’¢Å[À“yI¡¶×¤™ ¥äb?)Z¬‘•< W:Éœ*!Bay jB+Áaç̓ªY¹X–EZ8̓w§?½%^;mž¥ dæ ’G$]ÿÇö¹4¡Ò¸ÍD åßbi¥ŠCÃÌ–¥ýÿF5 éèæà
-hƒ¹|³ÑŸjÚnjY†ÜàW ÄRêIæ^h£É?N“á±5VÌËE’½~h=¢µD
-7V¤áƒwœ™gÜ]¹.æááb¢HLºë} Úœød*dh÷ºÐ'S6#†ÉE°^‘5°0ÎÚ~]M"éàÉg£ -fåÜK«Mo³š:>'ù:¥¦·Ç€àÌ4šÔ´jº75â8½èvS¦NÉb‰”â}'°­84 Qž=œêàydÝpJ°©Ìü…)›Ãœâ1˜;ª
-Pz*WJ×&p/w|5ب|âÝó¼1ÇžÁgÇÔ
->DhIîA]áT '<I8¡!b Ç°pv¸þ<IzÕ¸Jqà)hL8% •Šbγë“ïA»Ê嬩¢jéB `|t›T)}õé+ø’hCòA“ûÔFp®†ÙÐÙß[¶±àø¬M³Ä;ZFÞÆ^B’¨µäÁQ_³YO’gmy›î; ùù )FÓ´‡Ìõ¿”)~2KËBk•!³ÄÓ›Ø'~ǧW‡Ò߸ ‚Ê|^õò¬yvŸÕ‘¥«Ú¾Ô鈗r7Ôxt4HÝî²ßpUOF²ÇjÌÑAn„•bRçã‹£ŸNL‘‚(®Ÿ CÚÖ–†Àv—E6sT¸¯›_°ˆ³íXʳĘXõè(™GA‘4/û#¶îßp²,Ôܨ1£.5$\“Q?ùp|~2ÎlœùáK¾Ö)‡ñ¶ˆq÷ÕeKx|ÈfÔ„).©5˳ÏÝ?âå,KjšfõÃ0ê6¶A^c¸¨ ã{˜×¡Ê®¸
-«C©å¨IÆL“+8ñZ¤Aê¯ÒežÌ¨Äd‚Œ Õ²ÍæäÚ^ƒ µ)‹Ï àãZ tîwkwƒ|s§ÉVyYþ­ ÖËw.ZRdÞa ø9Å‚*b:uâäÞ
-ƒRÖ†‰
-¿M =×ñvÊ!5ÆIJ+1,Þ]¹yõWa8D’rÌ6 Hül¬¼mº¸þñô?Àop„Áuí«ÖÈåîCàc¹¾Í³µOýùz×æ`‡íÍ(¼+ÑоBÀ?Êbcq¦Ã²>bŒ˜Ü“tÉð²žD½(·@D4ž&p+’!3Ê£kÌ]…îqŠ[¯%Üêà!©¨…zÏ„0&"È1Ñõõ‡òLlGé–‰ØF&2¬ÇØgq¯C–7œUˆe´1zŒ{Ò†<Rd©Þ_~þ©ÜëÞi×zÝçåmñ.Ë*à °¹¥²^b±‚С=hòÚøñÓñ’ÒZ£—q_V!à£Øá1’
-
-FuÌçgŸ€¤<Û!.7ž¦Ð8¾ü™Tu½AF À9räÈéà^±$Ò‰QWž¡ÇÉ3 >#Öíîô Ǻ<6¡ÑÑXæ Î96ŽÜÆÏ/¯OGFªà’Ê>Cl[õÌÑ"­JoX| Ö¬š~5ÌT¥{Õ‚`­V®ð†oÈ o›Âá:Ú¸E{¸Õ%Ãö'˜–1‹Ä eS~~}rq8ÕLŒm›[ŠEíëNZPµPcõžPE¯\˜b>È9ÄŸ[•{†‡ß_yênõ¥8ò
-Õi–ÊÆcá×:TÍÁŒÓ Q?4w ÆcÛ¹q××qãøNn¼3ÊÅ_ØðŸŽtðsÕ g{JР÷YáÍêýOz¡å¹ŒhNº¶¡Û RÐä¡·™» "ãàv]ïJ.ª:˽÷ó¶opQl ­ëó÷XœfXz 7ª¶
-º·ŽDJ
+xÚÅZKsÜ6¾ëWÌ‘ªò xñ•=9Š”(IÉÞѤvó:P$¤a… É‘¬üúíFR¢,;>lé@ Ñ
+ýCKæÖt´ü°3ž–—}Ù6Ôkoiøag€£#"L‡@!<-j -ÁÒ–ÇÅ­ ä}îÊ{ÓPó°/²ÁP¥°\nlÔ황ۆÙø|‡-ʪÃ4¨A¨¶€6x!JŠ´¼­ëCSæÙP6wDz(‡1 ~&­NmT7ö{“¯çûQà”¿s.A­ëXª lè‹KY=ƒ—õ ®“rí­Q¦ÊáqÁ !„…”Â1Ú ªâÍé:Ñ‚¤Ä=nÛ®Îjãùðû°+ó6%
+Nv 8P<WÒïRjÚwæœè¸B¹m«6Ϫ¯Ž¡B–DaèØöèïù$œ#šûüa*ÐYºS‘K
+Ò!KãqÒK+§Lˆ(òZû„NãÐVìÁºhèƒÔŒº?_]þwíô¢R–@èÏôR´u†6Ô: ú6ÿÓ ÆR®À!?;t$y3T§Bˆ
+-Í;Ö·-&
+kÛt–XRTeš;<û²8$ñG¶~n{RÀuy×LOÙªj ö®Ë&C‡²ýÐ~b^AÖ_’ñ“Øž½wí¡Ë×ÊŠ¢3}ÿ™’mÐ_–Î9<îÍg®õ£yü²Cþxþ µ†öOã¼Ê™ñ…uÿ‰Q÷ZÐ
+¿*0x~µ>bß×À4ΉyüLÿ³Y^ð0‚ðšÀM¦ üW<b‰LŸè8ª“7ÏÛW
+:„E•$ \º»P%5ò¬·±èïœ –
+$ÖY᧶D)Leürt<•¸äž»tÛ»ÑÐZI—ŸÝ’€Ž,YÊ)|Üœ¹$wtE º©+ز|çK·²FÈ7Ðí6acõ*4Sr#"Çj²‚¢àˆ˜:…Âá׶q»_”•9Nõ§°SgQ,Æ©L¸ÉSO ébµ¯Æ× ÞÆIúŸ/V}úsï&À][/äCBŽ\=-ࡲ„y"ȱTAçN¢ "­ÞŒiä¸i©àhP»*L‚[ê×4¾¹8#2ZÚ-R˜>ïÊÓÓUî¶òmÈÙ‘j ÷­o»tp\9wÜ›‰ãj³!c'>½¥{ÆØWépo!c+¡œ/ ­tc‡ÞŒª§kjCT’&ì7Uéë8±׎ d FV<HoÌ-±Ù¸­vÙ½[þÆx¨övÉf Ïz{—õ¾250{ÿöy| Œo¯®Ùè
+³? êYA#Àx©g2=y÷\¯H¢aHÓb.‰»tfÛª®x~ª*Fþ×x¶î‹ªÐOe
+y 
+”UÅÈõŠ$ÏWCI\¡¥d2„3+!¶þj²ª,ÿèdS¼ãÓäx±Lp™»Æ¾~zÄñÇ¡¡Ž¹þÕš“ØüôÚç¥Áp'"|Á"ã/8v)%ò‡ÆÇ4%N(%â£)ž–€ît| ŸcŠÍÆ¿xP}hŠ—¦ò~™Žoô~ÿY¿Œ¹ÿ—ÕÊSúýãµÊiÅÓ—@…Á[T_¦É‹Ø- D´¾±ï,0࣠éò10«ÊÞy»4òظ˜‘Qè <Qä_³ëìiàÌ‹šXj¢‚/SëÑR:†œÊ£ÏX’f|ä'ÌH2žèWýŸ ªÈÕ5ÛŸð 1åÎçcPgY›5\—"XWå½#Z]Ç^×q¾ÎˆB•’Ž/.@öÄŒºJ:ƒ©X~g£ùš—ÍuhJ›Tüö`­¦°7¿öõKǶïÊ:ëJûºÝCoãÌP‘l½³€}à¨8)‚jà´¡&!C¸r¾€dUˆI ‡ÝýÅ4âAÕZ$YJ‹øujܘ%Èb·-<à¸m§9Ç?Rö»öPsPR”}ž9€ú§žxË—9 æœÅ2Âì±(„Koáæä«W3þ§þ³Àñ&@ •$ò\äŸ(àZ¨Ò4}ví«„…‰¹&¢ÿikwendstream
endobj
-1528 0 obj <<
+1942 0 obj <<
/Type /Page
-/Contents 1529 0 R
-/Resources 1527 0 R
+/Contents 1943 0 R
+/Resources 1941 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1486 0 R
-/Annots [ 1531 0 R 1532 0 R ]
+/Parent 1927 0 R
+/Annots [ 1947 0 R 1948 0 R ]
>> endobj
-1531 0 obj <<
+1947 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [341.1654 731.9163 414.8187 743.9759]
+/Rect [341.1654 175.0606 414.8187 187.1202]
/Subtype /Link
/A << /S /GoTo /D (the_sortlist_statement) >>
>> endobj
-1532 0 obj <<
+1948 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [434.6742 731.9163 508.3275 743.9759]
+/Rect [434.6742 175.0606 508.3275 187.1202]
/Subtype /Link
/A << /S /GoTo /D (rrset_ordering) >>
>> endobj
-1530 0 obj <<
-/D [1528 0 R /XYZ 85.0394 794.5015 null]
+1944 0 obj <<
+/D [1942 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1533 0 obj <<
-/D [1528 0 R /XYZ 85.0394 714.9798 null]
+610 0 obj <<
+/D [1942 0 R /XYZ 85.0394 385.3709 null]
>> endobj
-1534 0 obj <<
-/D [1528 0 R /XYZ 85.0394 703.0246 null]
+1945 0 obj <<
+/D [1942 0 R /XYZ 85.0394 353.2653 null]
>> endobj
-1535 0 obj <<
-/D [1528 0 R /XYZ 85.0394 522.9001 null]
+614 0 obj <<
+/D [1942 0 R /XYZ 85.0394 353.2653 null]
>> endobj
-1536 0 obj <<
-/D [1528 0 R /XYZ 85.0394 510.9449 null]
+1240 0 obj <<
+/D [1942 0 R /XYZ 85.0394 323.4096 null]
>> endobj
-1527 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F39 899 0 R >>
+618 0 obj <<
+/D [1942 0 R /XYZ 85.0394 266.7517 null]
+>> endobj
+1946 0 obj <<
+/D [1942 0 R /XYZ 85.0394 244.4404 null]
+>> endobj
+1949 0 obj <<
+/D [1942 0 R /XYZ 85.0394 158.1241 null]
+>> endobj
+1950 0 obj <<
+/D [1942 0 R /XYZ 85.0394 146.1689 null]
+>> endobj
+1941 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1539 0 obj <<
-/Length 2765
+1953 0 obj <<
+/Length 2922
/Filter /FlateDecode
>>
stream
-xÚíZMsã6½ûWèªjÄà‹
-F—Ÿ®¨yx~q><¿:;ïÿ>úñä|TO¹¹,Î$Î÷“_g½ ¬îÇÊØF½G¸a!cÑ›Ÿ¨H†‘’²j™Üœü³~a㩺&ÅxÈE${iCEöðÏÒO0øY/rÆQ´û«ÎâÃ?€–ÄTdjè…h@Ïy*kz&ŠC-…tÐ_²
-qð%gÁû´¯²ÛtB²…Ǻσ‹3’EÌ#P ŒØÁ&*ãD6Ó}RÙP‚9¾Ã1QU*d1‹:PU&ÔÆA_Ýœ^¨Æêà”ÐX¤åc¾úB7EºzÈÆÖãqZ  w HwQ® æ†éxó>¼B†q«¯|õÊjÄaxô´LtÀ+£Ð{xû͵ FSQšÚ`“2{ðM ²fn°^'ßåN°AY äó$[ è,Ú²k舺€$Áâ­‹t¼Ñƒ¹ÖBcy/ƒl£05+Ø·øM5â ´¡Œâ.#
-þ) ƳŒ
-Äõ(ýÅõÏWbUq½RÂëÝÆ2
-‹¨6¯ªq™¬J’ò;ßÍ‘#”n‘LFR±ýaa”ý>vœvµ§b͵‹×^aÃùr­;R1Q¹a–P¹þ »ØgpM¡ÐC6AOÖód¹'ów·iù˜¦ º!Ø@°Bà¨
-­5ÄuÃáÍåØ…€î‚³|QRüÄÑ ÿ”A‘Ý/’r]mƒØ4IÊàål»Ž„(Æ߃jÏ›‹9æ@–VGßâsÕˆƒ˜C®¨²ŽðÈ%ŒñéG_š`„NbÁóu™Ê)ñØú~Š…¸(¸ÅØÄ…
-RW5<Ló¢,H¤H %Œˆðê""×+¡’ vJ3?°ÃT6ÉH¯c ¤$Æt“”$÷`„¦E]÷h›'¶rÌçYcëÝ}Ó¾ÖêŽMÌ_¦Ç×5 i ¨Pî(uý¹q¨8gŒl7œÑ`Zëcu”w<›*OD™‚IãËÂá:˜<è‰u€)y´`JN&>ñdM.¢¦š%ÞÁ½ä¾T
-n®/ÐeÓ³AÙç*å›t1q)1È×ù,?‘|±‚$Á³,ÃjL#ˆÂç5($‡q¿ÏRï1)„M37!ÔsJäð‡U×Ää G¯¸ÕZÙÁÀÒ$á©nØ¢à_˜
-óqÙÍÏ£ë>qðΗê)OÁÍ]ÈŸ Y/—ùª¬Tû1+Jˆ;Ƙ;Tà™73p d˜­nW ôŒ©TÿYD3D&¦sµ÷XI¥E¸~±+J›Ýnvó1Ãâ|ìpüÿ¢êHs±ÇÒÉæDY×5c˜Ù9¢öÿª&ÂuJ#$؆ ™Ù>ÚöÕ7Ø€A1T™×µWçï¸Ô¡±¾ZF'z
-ÒД¹Óz³¢ûåzµÌ‹— ÕA°™^¸çExœ÷»b_]ävÍÊA½GV‡ùœÏ5+êЀ¹{áwÚ4¼ß)€ÈP*Ð ‘¼«€á!÷0ˆá°#qß·åßFÕ/³,ŒP;, çû³^§ï>÷Èòæض2¡´öÀ‡ Oé§ïB4Œýê@5gÀ·ZT½Sÿ©„·‘endstream
+xÚÍZÝsÛ¸÷_¡Gz&Âá`ûäØrâkNq%g¦íÝ=Ðms"‹®HÛqÿúîbA‰’-1©•©“c øÛïDÃÑ3–ÙT¦=—jf¸0½Éíï]û"Žé7ƒúíQï/~9U®—²ÔJÛ»¸j­å÷^ô.¦¿'–)v+ðä_Ÿ‡ƒÃ¾4<9=û”PÚÈäøãÑùÅ`D/lúþlxB=)5ÇŸ‡§g¾ŒŽN.Î>©{48ŒÃãÁ៿ .–[n–à
+÷ûïƒßÿä½)|ݯœ©Ô›Þ#<p&ÒTön´QÌh¥šžÙÁøàïË[oÃÔ—`Ò\0!À8ÓBlÿUú¿I©XŠû\ÿѾà)ðךñ”¯—²…¼†iïzΤÌ*©ò“YVU‡}«´NŽæ
+Ù‚âuð*í™Iíõ›û䘄‘žËŽ)Ãœi
+ö VU[ä£1`Öiæ×þÀaDúªœÍÊÇb~Õ‡dA“œ¶–ñ¸e;ó‘ÓZû1@ØHaã¨F)Á$ÓhgGÕ_6Yº”t‹F‡;ýÿb
+N¶½ÀÚî±woqc|]')èÉÛ_PH@ ½*ïçSÄ’§ÉàÛ]¾
+ÃÇ|öD#ƒ¶a
+Osšƒ2¶ ¡¿º¿¬é9§!,L),\ üHz–ßÊU³sÇ]ªcйÈâ§q41YšÅq°ŸY3"Ú2´SzŸUôŽ~¡±QÐ1Áç…8´Iûë¦ÈmåÿŒˆ.á–ÖÉÂݛ׉âϵK’C©;„[YÆáË¢pÿ6ø'p[¥<×e r0ôN๻¿œ¢¿æOÑ5·ì ¾ˆ‚½šU×ómøêüO9_Y›þvûÔaˆ¸Ú‘´@د Ù«+W©…8Su¤Ø3¡L4DcÌV¥Yã“H£†ˆÔ$7YuCê¶hXˆ]…áÝšËБ…ËYfÉB¤‘…[ Ó[_û6*ûM%öäBðìò€òž»H¢?œöiíxéª Ãu=+/›8÷®¬
+Lú"®ãû»ÜÍb†Û˨ŠŸ>ï@´µÕ7Ù*Ë™“^t ê,“6¥3‡gÃÓÏ
+Äñù"¨ÌjƒŒÀŠ¿
+H
+:$‚G,€2:j‹3¼ â _⶿ô ‡¸
+¼„®#[V”*“ÚðÝgçãÁqð&Ò)œÓ™ØÄ´Õš1ºÍë›2š•ù‚­›£^+UùÊZ-»oÁV-B¡ ŸÑ2½¢p¬¹ÜŬ
+o™Yà&Rîºì‘ôLC˜NÌŸ û†‡Amt'X° B“‘T4X©§¡r­:˜c(žŎзŹËïpî»KMí/ÝC~B-Z:1VÇ ªâšåÉš½„Ö£0¥‚Ö`Ó¸p¤ƒ ïZ.ŸÉ…·f…È ‰˜çk’/U3¼˜oç¨ãu1ÞˆÖåþ+=ÐöB&4¥ž`@i
+<ø õ’eº‘
+Øm8Ú_÷†²6í’q ã¥p‘ ƒãPòM@®b¡]ÆÌôîy@ Y1]¢¤˜0-ð 4Ž `‘âÔ˜
+öçÈb-ï¡Áýáf°'£^3ê“ËQ" ¦íó\f\¥¬‰È¿U½¹Þ á?–ñÅR¬ŽDëÛà鑾 ¨ÑˆZº¤[Þ# ý­l–:‚ÔÒÒÔ†Mõ_òË›‰?r.¶³¤Ù׉#æ ¬Ç;ÕL*ºp±yO“÷:Mø÷Þ_Ýž‡ )ï·¤³Ò“-ºl\‹J`üÙÅvÁqÓ²ÖÚû€ÊÜendstream
endobj
-1538 0 obj <<
+1952 0 obj <<
/Type /Page
-/Contents 1539 0 R
-/Resources 1537 0 R
+/Contents 1953 0 R
+/Resources 1951 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1486 0 R
+/Parent 1927 0 R
>> endobj
-1540 0 obj <<
-/D [1538 0 R /XYZ 56.6929 794.5015 null]
+1954 0 obj <<
+/D [1952 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1541 0 obj <<
-/D [1538 0 R /XYZ 56.6929 133.9784 null]
+1955 0 obj <<
+/D [1952 0 R /XYZ 56.6929 671.961 null]
>> endobj
-1542 0 obj <<
-/D [1538 0 R /XYZ 56.6929 122.0233 null]
+1956 0 obj <<
+/D [1952 0 R /XYZ 56.6929 660.0058 null]
>> endobj
-1537 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F39 899 0 R /F41 939 0 R >>
+1951 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1545 0 obj <<
-/Length 3132
-/Filter /FlateDecode
->>
-stream
-xÚÍZÝsÛ6÷_¡·“g"ð wO©c7ê¤nÏQï2×öi‰ EªeÅýëo» (™Š“6½éd&Àb±Ÿ?@–£
-5‘êx ”úñ|Ç{ÏýƤ]oÃ{6åŠÍ Ç›S“—=r¨d9.&t¢NðË™§‘Ý ›
-cØÚrY;á€ê$1áG–Cžƒ0€4èr•áì€K6¢Ös%—ßíõ$P責³Ö¥ƒbå?«²L”AJ”ÚR˹6æ} ` ͆_x]þVø ÔŸƒ.Æg,
-TøüFâ6Ý6ÔØuUÎËÖñáÄ(ÙRYU¶eÁ3]DÂwêÒr1耛bë€I½` bwËea™PôS«°<]ÈòäU³«øÌy˜
-üf†=O‘NóÝ‚ÀAìD²Æy=6,LoÐô<
-.C€–s²“Q=@‡Ú. wzC¥ 't†1ÊcB£xÔ{‹Atµx_´¼ƒ“˨Ã(ŸæsNl›ESa,öy,×Îî‹žÒ‰1à«r¹rKc3†pÔ˜S‡å‡Ú¸§šmNÔ/™žÑ‡1k0Z&jÃ_“*8ADÝiMK8–ŒGæ–z¬„‡2?ÝôîæŠVÊ@‡/†r>fÏ
-¥¥¦·Õifç«8×Øj—û¤N°î†“åÙ¼Üõèríà]ææP^1¶ÉÉ¡AJ Ç<fâñžéUéX* ”L¢k$Îwyiî>É<ïOVÒ%W‡IÝBdF­-N®ëbÝÔåÂÞ\
-Œûº«ÑóæÁGì³qìalte=ãÚë(ÈÐÆ÷M§÷>z Ù°Åw;<G()5bÝ?$7½!röД^*@
-ËšæŸ@°Y†Ð袸̀Ò1t蕋̓J\÷à/ÐÉKû –xd«SU8ÅGwv6¡ScƒNÝÛ {é¹U{‡œ± ‚!4ÖAÈÉæMoûRŸ=¸/™ÇÁgB lÛE
-@Æí™À9JyáÐcP=ô ¹š†OgØGœ!g=¯n\pGßù¡ƒ©“ø Í÷u³¯Š|YœaÕÝZ÷ðU‡áJu¢1<Ö :nüÔÃ3öö¼n  …s!UÔ#®Tú¢>¸î™‹Q'€\›-»ûÓ·`©¥“Ž” D"õ§½Üƈc}æËíà*/HO‰ŸþíW<ùm‚…¿ˆ¤ÿ®ö¡6þ†‘F‘©T †Æeúv*®_ý€>: Æß¾»œ$:Q€¿€üß×·×w/E7íôuÝH‘„4ÚÛû5>øçh(ŽEh9¬!¡B…‡MRCnûT%/ßu
-9¯ÞN_Tò‹ê#
-E¦Ï9L”ŠP‡ôKÀ±C¸Ÿ LV‰A©T©óŠ9lùö“P‰Ô¨ô9? c\@×ËN° ¨ úˆ
-zÜÿÂ:Ðäî$~Î9tg ©…€¼¾k€¤ •œWKoÿpÈHpñTEϹ†R"Š<v ú¼zì¿>ãGÊ?¡ÔÉ$‚jcÌçþH)A#QEÿ‘R&ZDIoáÏИ²µ
- 4 a•=ð½’>ZîÇkµ°Ã?eáT~÷dVô¬é7Ëx2w?X
+1959 0 obj <<
+/Length 2986
+/Filter /FlateDecode
+>>
+stream
+xÚíZÝsã¶÷_¡·P3'_$ÀöÉñÙwNî|®¬´7Mò@I°ÅF"U‘²Ïý뻋%Jч/öMýÐñŒ¹X|ØÅþ°»€èpø3®RÝ1©f1qg4;á;¨{w"B›^Ó¨×nõÃàäû e:)K™t·­±,ãÖŠÎ`üKtöþôzpÞïödÌ£„u{q£.¯Þ'¥ÏÙ§«‹Ëw?÷O»FGƒËOWÄîŸ_œ÷ϯÎλ=¡t,a
+·€ÙHÙÌ!%ýd“ÑgäuF<¹j% Uí÷Ù”øã2ŒRÖD¸/yUo‡óà›3øOYà"âæ9&¢µ6(=ÐÚ€ê÷é[?ή26QFR!þœ
+•+B‡ÛrÑ M_?©Þæ4È&òâ'Éýa?[ U9Îoqì[·¨ˆqë«œQéª+"hLZ.Jñœð ¼‡ VdöæŠåÌ- ?ȹ,ˆ7\ÖDøÝaT4+W«͗uVCûlê· 4q_殨ò{·ëçüÀ —aé·ŠŸ²#VªÅ4éˆPË£Ñ4'{f†Aq1jðÖU£E>t¡c^ìyÿâŒÐ"q̶áB^˜¬¯mdÏ3\0¦
+\ƒ?5ž¨ë–Ÿ§˜µ®|‰¿÷›ûuÍ9K¤é:–päÁ@^ºŸpJj¡‚†µM )l£aâ¡Hñ» ùÔºEߎÐ(ùHä#õÈ*äËT7¯µ ºA¦ß¹©ŠÀžîò׌\ÒÔ_©@¿=Ÿf£¦Óð‘¾W^a˜X™ô­<˜CVÓÚŽÏÛâÛ©^!c“0#¬<b5q*™ŒÓÔ êzÐGßR¥Ñ):3:š—~RÜ# º†¬aγEMTyšy|b\Î2ò´tØÕHUsP º° í·®·ßrëÖ~@GíÅ¿²}ƒS –Ê,7ö˜Ž˜ƒNÒÑg8¹`‡F×äÝçc´UiM4Ëæs0³PºúÁ¹‚
+$7 ¬”Dx0@â3œ<ðÆã`á•«Ø~Õ5 ‘¨Êi­úe•ó²$-³©9vìÄZ3­RLÿÚ+GF—@ãÌ»‡ #£æ;Ÿ¶ô‡=‚°çÀÈ锦ÇT Þ¤7$ä!!xƒéûí4€µ3@èlúD¸ÂÒVK ¯Y[aÍQ¸“œÁŠîúý›ËwpâEgeQ“¦­h;ÚʨÊ^6G!²ÆY|çq[ÀXE~†ôÞkBš+}@è­Õ¼”Ð/m›{…®“â}q,"èb‰°„_ý®2Ñ
+»±#*8?è¦iˆUPËÅï¡j*{¶1͵íYcW'Ü–3ôƒl ýyŠü¶{C)p,’c©!1±"±xsŒmš¶ÌÑ`€<v¤·lY-"M.¥ ‰Nñʥܜ5n¦ñ–› ¡°w3±&À²¼[¬N¼²!i
+Ñàˆƒç Üóop IÊÌ™Cf€0$W†-{s SµÄá¼3ܳ›ƒë®iô&dî)^Áí£ˆèj9Ÿ—‹ºQîû¼ªÁûa ±W…-Ù¼bL“p®€pDƒà¸2e¹ñ²ü,côbõ]+ÝÜ@VQž¾Ÿ6Ej}ä@a;03<Ý
+ÌþtZëp\ÖZìK©d}Õ~ìîûn¶îîÿ\¯f"Me¤B=2n6ïüÿp÷¯x¬LMEÅÔ¾À¯y— •dZ†´Ù`n¸nËé´|ÀФüýHsÝ3Ñ0I«á×°Ëhš¡‚©ÝÆ/ ¬*˜µó>ý
+H«’δ‘Û ¯;®àà¤bQûÓX÷Ù4ßÚ"u³
+@_ð¸“<fJs1%iDTÊåU·—àuÑJñ—xÍ
+ù©ÚC:ç5U|¼ÃoÐæÒ‰Y>î‰ÔðCéý~Ör…¢ PMnX¹ÏÄ1YVTž/ó²r¸É)‚lpÇ@øê»jW~d¸Ì§uouH†›u²ºvrÂWá¨u쎽!XТ-{z@!X€±*èÎ0Ó¸C ¯J„¶û÷d[Û¯8'”bGS*Â$nB øܨDÀþyï@Lc­Õþ’b­-ù›U˜G…±»wÓrN‰K—´ÆoI4
+õMØ
+u÷Ù"/—a¤ê±Ú™¡­Ý,˜]fÕjƒýÑÛƒÙ,šÚ»Êž7 þø‡LÙº*¼å€=¸{­ôöR›ëÕ8 ãÂè':‚&-{Ï}¡Ö>
+Ï/TxjFí"¨¼­]X³ù4åµÏãÚh‘…nzXá–ò×Xh˜¨Ý»Â–Âu¸|㑸‘ýð\ë¢ #»/ü¬ ¿9ËŠÇ];‘æöG¢{¿«ÂÛ3¬ÄÉU“!8j縓Œ|ˆì¡–£&‰^­ý'¡kë—ñÒþ =ÑÇšž-QKÿ(y%=Ü£BQŽ½ ®…öÙñ4ƒf€±Ý÷há¡H-½(+b­=2ݤtÀÜÃ3Ðzâ2ŸM¤Š˜ãœ°Vä*z0ø€‰%jâ@잇_áUlUû.X&¡@ƒÌ'?üôš±HÚ?ãÁ&ˆ+þ±Öž§¸
+S†Jìz9Ë;GóO}§»~«¬ „Uû€(®ñ8aV!]-¶ç+ $MÓ¬5÷ÿY¨—lendstream
endobj
-1544 0 obj <<
+1958 0 obj <<
/Type /Page
-/Contents 1545 0 R
-/Resources 1543 0 R
+/Contents 1959 0 R
+/Resources 1957 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1552 0 R
->> endobj
-1546 0 obj <<
-/D [1544 0 R /XYZ 85.0394 794.5015 null]
+/Parent 1927 0 R
>> endobj
-494 0 obj <<
-/D [1544 0 R /XYZ 85.0394 513.3136 null]
->> endobj
-1547 0 obj <<
-/D [1544 0 R /XYZ 85.0394 488.6113 null]
->> endobj
-1548 0 obj <<
-/D [1544 0 R /XYZ 85.0394 303.0671 null]
->> endobj
-1549 0 obj <<
-/D [1544 0 R /XYZ 85.0394 291.112 null]
+1960 0 obj <<
+/D [1958 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1550 0 obj <<
-/D [1544 0 R /XYZ 85.0394 122.9426 null]
+1961 0 obj <<
+/D [1958 0 R /XYZ 85.0394 229.6198 null]
>> endobj
-1551 0 obj <<
-/D [1544 0 R /XYZ 85.0394 110.9875 null]
+1962 0 obj <<
+/D [1958 0 R /XYZ 85.0394 217.6646 null]
>> endobj
-1543 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F41 939 0 R >>
+1957 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F39 1151 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1555 0 obj <<
-/Length 2939
+1965 0 obj <<
+/Length 3016
/Filter /FlateDecode
>>
stream
-xÚÍ]sã6î=¿Â÷ Ì¬Y~I¢î-ÝÍöÒÙÍö²éÌε}e%ÖT–|–¼Ùܯ?€
-á:§ŽÐ—íäQzw Nm•Æ%uJüH |ѵõ®/©·.óöL8?k8 胠
->AæÅÉFObY!ýrK>}‹Ž'dü²Ž‡=D¥¨<ø­î›v¯:tþªk;÷NnöYpD0å)‘ $yŒç`p½ØÞŒ®IÏEóÂj~ÿÙ„Ö
- ´%„Z«
-bÙ¢(}
-íkŸ{¹Æò„ØУ²±ØöþsJj‚Ð9Žcæ0rgu¢¸š(¬ÞÚ§ÅUÃÅÕeßSVÔnoß½ ŒzKqZõÕºœ÷í¼¦, $£4„r W†î—õ’:”PP]£ç‹ªç!ïIâ Ç“NMJŽ#=Ø5UßWN r- 7ïü‘„€~X2Áœyo+Ÿ‰"¬.
-IG%Ûš‹¾K™ˆ ™/´Š¼ \
+xÚÍ]sÛ6òÝ¿BôŒÍ
+÷ïï®Ï/ex7·o*Œ¤wõÝ«Ÿî¯çÔóÐ×·wo£éçêÇ»›Ûož¿:OBïþöÇ;Bϯo®ç×wW×ç¿Ýv}?°<Þ–òûûÙ/¿³v÷ýYà+F³4_h-gë³0R~*å0ÕÙ»³ G½vꤘDàKË 9I9%§Hû±’ÊÊi“m;ÚÔ¯AÌßÐNñß+@êêVÙ0(]ë°%uYŒkŽú¶ç"õʶé-3vQšzI`Q¶ùÖ,ÊÂGaÂŽ.Eâk%SËÞ=ÒQÀͺÌj;G%‘]‘õFÞýý[ eUPôԛñh³æá•Y›ŽMM¿«fÇ} ­zYM˜ùœÚyÆcLæC¹a*¦>X)ÏòU 6§
+vàØ UÝ&…¯£HÚMMi‡¯n,ÁÀË6›ê‰p]è¾[5[Óey,©«ÈºŒ b ðþhê²ýûùe¨
+B6}wÃá-z^{á&é:>°*W¬ámšÊäÆñþÐl7GŽHTthY™$¡`­Žô¦YUZyYÛšem™¬åD‡{Y±6µi»mÖÁjõ@€:\ˆ Ýª$¦È('7@@—¦Îº²µ¬Iï_+S•SJjAøè©@®[‚¬I €&¿}‹¼#„jÃ_dxmþ(Ý„åw- ƃ3úùƒØm†eØve¦k§è·šv›U¦³jA”õHø½­»r[—“¸)· ÆuV£*)½¶_.˶£y?AeË#ЄZ¼jzër
+b·O¼L‡‚uk¦T4ëÌ1Ygktý ‰ß»ÝÃ1ÓeÖê­\d±’£Æï}Yw·×šÈxʯR†›Æ #¶j§éVN',̈…9ÖÅ›»w–]Èíb”Ûy¥|!FÕð%;A€ä…^ù±ëÑ›Jùq³-!Ô6õaÚFqyH\†¾Eh‰“ž´‰
+jÆgôƒ¦CSÚrûh5 ؆]™Taø „:'´i
+ûpñ1[o*kƒ±vBx4Åñ¢ó›+š Uhx11z¼»§ªd¢T•m©aƒW0ÿÀ¥6ÄÙb~×D1…—å »Œ˜mžŽçsÁ°”À<²s‹2K*!NvLÍ& øù„qlåCL;¥@›Õ°À‘2òÖ f4 K“ =²øÁõk­_Òö@©JBU¦¶qXB5RAEÖ/WÔ¼šºw! ¦áЖÀÑB ¶\oQñ²}K;xXmm{º"–±ÍQé Å>åÌDÙ•’ÞŠÅö¨¶Iö71s>÷ ¸åžŒè8Š
+ò"TLLrgºÕhtVYýÅÊáìtbeÃ$ âë±*wZ8
+‚-ùÒ(´îO(ÏN ìí¦é[å|^#·:]Göæ¡åت/\P·õÊþ„“ÙÂ@Ýõdcí¤ænöé}›Œ
+8=Æ1{;ÆWÆV`ã¡P¥\0êiSòx÷—W L¦ùp4Óî«ý a"#¨oË£‰ëº\7µÉÛ) %ú}=äèEóh#vÑ8ve,C"æ4¾½$s@?4ƒÜÇÕñ†Ÿíp¡ ÐˆyLìð†ÐÙccWP),{TÍA}ÎÖr &ŠËLDÚ†
+pÜ‹Ä6÷ö´ÿÁdUêŽ
+Ç£xë­•ì¡]#@»-†­ˆdˆÔª­œÆ°4VAÈÁÆÝÞ¹>¹/0_R+?á œ`»Á(û¬]I1d¦©ºÅV=”亣»àq{ÂqŠÌpê2°®ô 9›†Ï+Îp\q†õœ¸qÂœ~÷û††Nžàb4€êfW•Å²<Aj8µìÕ”¦3Õ‘Äp[“â¸qCYä|*Øñ¼5- )£P¥Ô‹ë‘º¸ê„"·Í–CˆýÛñ5¾PJÍ”Ö~˜Fñç\t©8ðãXF‡]n–cdŽNr@ó Å û!©ËaS—*MüHûk´p\j‹@ûQ Cؼ€Š;¡HxûîÖ¿~ó3^ú¨4ð~x~™¨DBý¨Áÿy}w=åÃŽ$Æ
+N@¢£µÿÚ~Pr`ƒ{3û’J"?J"5-!)?Õ1l&Ѿˆ…¶z.’WÇh¥¯XÀn,ñ)‹‰_1¹ñ¡E`µvÑ*Ñ(#™úÚ–äiÉКò+—L$À£OJù2±Ì XD½ ‚=ñ¯XJûI ÓOÙF¨|©c:b¸ycË
+?Hß‚ž½ A0Älå ±$ÉËoB2•@=Ô£G©lÈV2¤¢«ì‘»è–ôY©…]C©…ÝÊä+Ê÷žLŠn€Ý↞ˆ/öÁPu¿^ÐE±â;Iºzå7I WsØ…÷+/_äeEÁ…X{T ÙSϨþ£u]P-ÈÒíO'hÐ ÃáMÞdG%•’´¿¡Æ«øc’/T¿Ÿ®*¿}•ÇÜ´æã°5WÒÙÛ5GûvŒ—Y¾:>=O§î@'¸ïèÉ]€N¤eù¬˜Ô©+ΤоŠ…ü<ÓÊÁôçÔ’_ ̹=]Ê ñà >û#?t[| Féïý{ÿíÕ;ÿ‡Û{.(¥Nè@‡EøX ›ð/ ŸGÀ"gòÜ/ýW þÂY`БFAz* „¾°2Ðò•Pn¼ún, áí…XÊà¤HÆË}!™ü/IáËÛ¬€;uIA)`èó’‚
+wà”pÏ*
+fŸŒÿŸûUÓþË®ÂVšÊé8$¡äµi‘™BuˆàÙq¿R¼ÿVÁfendstream
endobj
-1554 0 obj <<
+1964 0 obj <<
/Type /Page
-/Contents 1555 0 R
-/Resources 1553 0 R
+/Contents 1965 0 R
+/Resources 1963 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1552 0 R
+/Parent 1973 0 R
>> endobj
-1556 0 obj <<
-/D [1554 0 R /XYZ 56.6929 794.5015 null]
+1966 0 obj <<
+/D [1964 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-498 0 obj <<
-/D [1554 0 R /XYZ 56.6929 723.7047 null]
+622 0 obj <<
+/D [1964 0 R /XYZ 56.6929 622.0858 null]
>> endobj
-1557 0 obj <<
-/D [1554 0 R /XYZ 56.6929 699.3651 null]
+1967 0 obj <<
+/D [1964 0 R /XYZ 56.6929 597.3835 null]
>> endobj
-1558 0 obj <<
-/D [1554 0 R /XYZ 56.6929 499.5106 null]
+1968 0 obj <<
+/D [1964 0 R /XYZ 56.6929 411.8393 null]
>> endobj
-1559 0 obj <<
-/D [1554 0 R /XYZ 56.6929 487.5554 null]
+1969 0 obj <<
+/D [1964 0 R /XYZ 56.6929 399.8842 null]
>> endobj
-502 0 obj <<
-/D [1554 0 R /XYZ 56.6929 352.0214 null]
+1970 0 obj <<
+/D [1964 0 R /XYZ 56.6929 231.7148 null]
>> endobj
-1560 0 obj <<
-/D [1554 0 R /XYZ 56.6929 324.7169 null]
+1971 0 obj <<
+/D [1964 0 R /XYZ 56.6929 219.7596 null]
>> endobj
-1561 0 obj <<
-/D [1554 0 R /XYZ 56.6929 283.2444 null]
+626 0 obj <<
+/D [1964 0 R /XYZ 56.6929 131.5008 null]
>> endobj
-1562 0 obj <<
-/D [1554 0 R /XYZ 56.6929 271.2892 null]
+1972 0 obj <<
+/D [1964 0 R /XYZ 56.6929 107.0349 null]
>> endobj
-1553 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F41 939 0 R /F21 714 0 R /F39 899 0 R >>
+1963 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1565 0 obj <<
-/Length 2487
+1976 0 obj <<
+/Length 3209
/Filter /FlateDecode
>>
stream
-xÚÅYÝoã6Ï_¡‡{Šå‡(REqhšuö\l>.ë6‡n÷A±•X€,y-9Ùô¯¿!‡”%[Ùlo X1Cr83œßÐ, ðZ*Ò8PiL$e2X¬Ohð
-R’&< æ÷=^šP­Y0_~Ïþuz=ŸÞL".i˜I$þ<»|ƒ”?gW—ç³·¿ÞœNTÎgW—H¾™žOo¦—gÓIÄD,90ŽÅïW—S\t>{7|œÿr2w"÷ÕbTy?|øHƒ%h÷Ë %"Õ2x‚?(aiʃõI,‘±žRž¼?ùwÇ°7k·Ž™I
-M¤æjÄNœŒ‘TJ>0”LI"¸°†2ªÅ '¥4œUù¶ÉQ¿‹l³)ªü£¨ð;»~ŒÒÀš÷®€I³Øò¼É‘Ò°ÊÖf¤Óp;a:Ì›ºÜµE]áìTÒv•µ¸¢h¾›D1—a»Íª¦ÌÜ:˜¹·›ë5îš]#5[.Ó'Ú'Ì¡Àš!µhÜòŪ
-Ë©Ý°¬×YaõQaV)t^Ïop€Š,jû]6àoŠÓpZµÛ"opnN¬xŽp ‚œƒlqb-ó!§2Ïš6jëh]7­QÀ¸ÊìtÅpjŠ‡ªøƒR¾È*¸+®yèÍíépm<eN‡l‰+ÊüÞ®öZ e[<¬ZÐ,¦*œ¯Ìµ*~ªeYo6uS´9’÷ÙIÏË­áSöŒãæÛóŠÜ±îÌ`æwÍ.+Ëg·{[´‘ÕüàzÛ¼2’r ’îŒ_
-ˆÌl—1žTvà,OE»BrV!9pOîüËL0v‰p ê]¹Ä‰Uö踺“À‹M]-1G]<w^ß4¢’€3$&r¸‚û+‘Ús’*lVN: :通!Á:¯ùÛ‡öÎ9N]W>­êÆM/³6C¢ñ¬ÜŸ‚2(wÁa¬ý€ââs¯ziïZ¬¢c
-j<ʤ{ëŒ1¤Šp½+ÛbSº ¨ "‰Å=~Q*ØÃ&,ôç­2·r]wÎf×£W€ ~¥ÑǸ–HÂóz‹´üs¶Iœ`žc¹r©ùƒ[Mõú#’0æ8,HŒAZ–*’X•&úkJ’HQT”¤ÿm—¤§Ê‹à>
-¼ÜÐﲊ:¥¢DH¢c–t/f½ìË8#B$"%ÈhÅ\ÝÌÞΠÒK&h8 ˆ.÷m(©&<IxÐ?íÛ40¶€Uöîûw… ¢u"_3
-W$V#2‘V`c—òœ3¸¯kÒó6ò²qz§þ]ÆÙƒžÿ‡Ë²”­
-zXÆ»°¬ª¡½SoqìX‚<´¶7
-Ô' ¨´¹ò¢-<b7€‹•½';‹[oÎÏ
-ˆ;5¯Œ¨È?GœP7™W˜Ë¾¯Ë²~²'ñ Ìšr›e÷Ø·¬[ãd$h
-Þ í×0Ù~!3‚<ö¾Úä6%ó±Âº·>.y÷NÂ<,‚ÑS%…¹rÀ-ˆ3eέ¬ñ›UÏ8ØUŸ
+xÚÍËrãÆñ®¯àÁ¨ÊDæ |“m­C—W»‘•*Wl Q†
+Á[ Æ¹Œ<Ë{Òâl[ì?Ð.±Œ-7Më9Ú{ v³­Î¥”ÑhÕ #ö8ÂÞésd© ¬§üÄe'vš9¢Ý5õª¬ïð¼™âk8Ñ®ƒÃÔ¾£n~WxÙv(¶ìsj™è6_þ›×5ü (ëâ#ã¨è wø&~ª?4ßßH½ïY—Ð;µ¾j¦x²n›rÑ&ÿ€[ª ˜ø†òÛ¶©]A½m‘×pg‚ùM©”†á¤¼'
+ðí©‰âˆj !p´YØß?+À±xMñ+ ›R,lÖ…Ú8O-æ lzI±†åÁâë.7^!úц¾AæÆ€^ölxll݆mII‘ó™^ÈÀ¤fSf"&EƒWØZ†@"KˆÞ·É‰À`m’ž°tÛ6Ë2ï¼)e fƒßd¤½ŠÇ~V\PÓÓ¾ðÃ’ˆ'Ц_]¼½Ûâ3h´‡5"Eµ±,‹GÆ!õ|ãwHHT“£¨B“Þ %/UQ¹¦AÏ4Ì|Ðõ›Â÷¶ñ&2Ižp°Ä=¾"îV÷ úz|Ì›“Œ> 5<
+éhì{Òé{tw<"í·àZÖ™ð̃ßò®nŽ¬c€ç5ØìÜ+q°$¬5² ˆ`Éc$#¤!Ò:¯‡^õf'fÒŸ¢æU ±ÃO‚l‚q`l×”u7ØjB Ý>sÐÅìåv+>æÛ]U|sêòei,-¤!UŸäó©,¶©LÇ>ßÿ·*œcð~Ož€Ö ÀÅÍ°bŒjî4·. V½?iä@üÁÁzf3¥K<5™Nñ²Ù¢†Ñàµ-À­ÖJ
+²,y‰-„‰“àPRy÷\áTG—9&X•²4©,ÛBh„œµõÔ„Qû-}I¡)ËÎ
+EÝ㟩„<mÿ,êX„Ó9Š~8ÿ'ð£:Ú‚ò/w/ Ë@ãqI:ãbdÿs
+´@¢à¯•¼ `cÝ4Ï×Äe{¾eþ\GݤLbо¥IÒ©ŸŠÙ‹¯÷©?@<þB{í¯7ò$0ŽÒàUÎÀwC\Þúѳ„Ÿ*2ØàìÿR¥'ùendstream
endobj
-1564 0 obj <<
+1975 0 obj <<
/Type /Page
-/Contents 1565 0 R
-/Resources 1563 0 R
+/Contents 1976 0 R
+/Resources 1974 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1552 0 R
+/Parent 1973 0 R
>> endobj
-1566 0 obj <<
-/D [1564 0 R /XYZ 85.0394 794.5015 null]
+1977 0 obj <<
+/D [1975 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-506 0 obj <<
-/D [1564 0 R /XYZ 85.0394 769.5949 null]
+1978 0 obj <<
+/D [1975 0 R /XYZ 85.0394 613.3608 null]
>> endobj
-1567 0 obj <<
-/D [1564 0 R /XYZ 85.0394 749.4437 null]
+1979 0 obj <<
+/D [1975 0 R /XYZ 85.0394 601.4057 null]
>> endobj
-1568 0 obj <<
-/D [1564 0 R /XYZ 85.0394 660.1505 null]
+630 0 obj <<
+/D [1975 0 R /XYZ 85.0394 465.8716 null]
>> endobj
-1569 0 obj <<
-/D [1564 0 R /XYZ 85.0394 648.1953 null]
+1980 0 obj <<
+/D [1975 0 R /XYZ 85.0394 438.5672 null]
>> endobj
-510 0 obj <<
-/D [1564 0 R /XYZ 85.0394 449.4639 null]
+1981 0 obj <<
+/D [1975 0 R /XYZ 85.0394 397.0946 null]
>> endobj
-1570 0 obj <<
-/D [1564 0 R /XYZ 85.0394 424.0768 null]
+1982 0 obj <<
+/D [1975 0 R /XYZ 85.0394 385.1395 null]
>> endobj
-514 0 obj <<
-/D [1564 0 R /XYZ 85.0394 352.0618 null]
+634 0 obj <<
+/D [1975 0 R /XYZ 85.0394 216.4249 null]
>> endobj
-1571 0 obj <<
-/D [1564 0 R /XYZ 85.0394 323.4047 null]
+1983 0 obj <<
+/D [1975 0 R /XYZ 85.0394 186.4354 null]
>> endobj
-518 0 obj <<
-/D [1564 0 R /XYZ 85.0394 272.2519 null]
+1984 0 obj <<
+/D [1975 0 R /XYZ 85.0394 97.1422 null]
>> endobj
-1572 0 obj <<
-/D [1564 0 R /XYZ 85.0394 246.3845 null]
+1985 0 obj <<
+/D [1975 0 R /XYZ 85.0394 85.1871 null]
>> endobj
-1563 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F39 899 0 R /F41 939 0 R /F62 1062 0 R /F63 1065 0 R /F11 1397 0 R /F53 1029 0 R >>
-/XObject << /Im2 1051 0 R >>
+1974 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F39 1151 0 R /F41 1208 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1575 0 obj <<
-/Length 2175
+1988 0 obj <<
+/Length 2116
/Filter /FlateDecode
>>
stream
-xÚµMsÛ¸îž_áCöLÍò[âÞ²‰Û—ÔéK½;;ÛíA±éF3¶åZr³ý÷ H[ªÕ®û:Ì„‚
-
-âüñߎ‰ƒ•‹d‰}½õó%
-Z´8_òò)AÕ’Fo×ÎBBäœÄ+|Bmê†ÎmïÄ»ˆä ?R½Ë‚LÏ»&oJ4ÌòárW­
-΄
-ý6´.u
-&ýÄ{Zg—Sg¶Ð»s•ê{ëlVu_¯%YÎå¹ÁÑaé¿óº¶*ê>‰¤cp!rí0ûò>
-"çIææó6*¸ëUPÃyCüÿ”ðÿâ àFå  sɯ³¯X7?I–«Ú.M¸šji‡óØÀ6žð µß•>.
-
-#QÖÕ>
-/Pãþ€R·Ã«Ž½TR¤£ý¯ü‡•C’«ç»òáINd1 ]a0­è…f ÿ¼¼¾¾g—÷oИ—‰_Ú€õ¼Yð/Ü6ÞZÇr"´
-ÐMHÖâ{ÉúÚ¬x‚˜ÿpËÈ€†é[ßNîÿ˜Ü?c“?/_¿¹œÇJÈŒÀg4\M/_ÇÉgŒ÷gضF©và)–ê'=|ÃTœÐ
+xÚµXÝsÛ6×_Á‡{ fJßnn:u9§N,÷µ¾i’Z¢mÎP¤"RqÜ¿þ_)ÓqziÇ3æ
+X,v±»¿]€DþH$$’šê(Õ LD´ÞNpts¯'Äó$)ésý´š|ÁÒH#-©ŒV·=Y
+a¥H´Ú¼‹%bh
+püûÕb6M¨ÀñÅü P„qAãóŸý²š-Ý„ô¬?ͯ܈vŸó«ÅÅüõ¯Ë³iÊãÕüjᆗ³‹Ùr¶8ŸM?¬~žÌVÊ}³fFß“wp´ë~ž`Ä´ÑüÀˆhM£í„ †g,Œ”“·“ÿt{³véØ1QFP*X”0ŽlßgzÊLYcÃÍÕZ~•Ž„"­×G‰b°3œü³²Ü: ²<V E].9E\rÙ¹œÒˆ¤… Æç’"–¥„ÁASn}¾0î°œ ɉa$ óØr\MIâü§ñçLœÒ4’RAl)n¶Ž>Fa®5sL=ÚÚz<;ðý|K£W5XõŒ
+‚“¾dk”¤½8†ð.Ø_¥(å0e4^ÝçÎ*Éz¬àD,H°êWËùë¹·~ ’CD,=_YTy3M˜ÆqQ¹o â-‘OŽ?gÛ]X²½Ÿº5SõÞýØíë)ñ§bSTwnh]W­[Þz¡õ—„ƒ–piL£¤s)¨WWå#ð¿§4u”AqìÇ7µûVuë‰|7MºNEXžív¹c„8CIÐÅL®ÛCV:úÐdw¹1òŸslû¸›;
+„–¡GDú6øæ<–’sžôs>ð é­
+8”¦“œti—P¥âË Žzïh/Jéø¢Þo­Gaô!kQTE[d¥‰ós“¿Ç˜VÖOvÖ-]^œ»¨ÂQYåyî(7‡›&ÿxÈ«6H»ÉóÊQùç6¯6ùÆÄ,ÄÈõ½Ñj$&]´€Ý ƒÓèL
+Hòr\ßÛ°cÔAPÌùFœ£€(³›¼tsfƒHf¸ÿÙ]ü ¦y¹1¶2Ö²8kvùÞ%
+ñ¦ÚB˜vå‡Ä…«'Ä×j;8Sã<gí¾YõèˆCõz¸ÂBÊÆ­8©DÈôk,À—‘èV†œ%>=‰ÍÝ}Ó:L ¦ @Á‰ÎìFÂW7‹`nÂ7î›ÙiÐØ뢫7$p6 ƒÜ1ÚHF¿ "\DEÊ"©Êû 0"HLú"G@B¤
+Ñ#kó˜8àÉÿSÜÜóææù¥_ΖÐY¸}±4v=dm^ÜŒo!•ïïFÂ…@¬
+ÎÕWQTg~›_°µÍ/øýp¬)fÖ]Y¼zEe!bD/;µa²ðÂw5,1Іe<¿»Z†°ê@óy7A—Ç™ölA|“\ñÄæµI§Ï\C;e{8Ò;ò€lE{?Z4Á‹ŒÒ? iÐœÂk¸ôBÏ^›jþP4ù ¿TÀû)ÿ³:ãÍÊßåXšBË…Õ0F(p<ci®<D×'˜é*оßÊñ|Ê÷žËžÈQŽrÒ8™0øèFï3¿ßn_ØëÙÉÒ¼‘¥©øŠ[0à ç!®êjÄšÇ&i
endobj
-1574 0 obj <<
+1987 0 obj <<
/Type /Page
-/Contents 1575 0 R
-/Resources 1573 0 R
+/Contents 1988 0 R
+/Resources 1986 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1552 0 R
+/Parent 1973 0 R
>> endobj
-1576 0 obj <<
-/D [1574 0 R /XYZ 56.6929 794.5015 null]
+1989 0 obj <<
+/D [1987 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-522 0 obj <<
-/D [1574 0 R /XYZ 56.6929 769.5949 null]
+638 0 obj <<
+/D [1987 0 R /XYZ 56.6929 617.17 null]
>> endobj
-1577 0 obj <<
-/D [1574 0 R /XYZ 56.6929 751.488 null]
+1990 0 obj <<
+/D [1987 0 R /XYZ 56.6929 591.42 null]
>> endobj
-526 0 obj <<
-/D [1574 0 R /XYZ 56.6929 529.8403 null]
+642 0 obj <<
+/D [1987 0 R /XYZ 56.6929 518.3317 null]
>> endobj
-1578 0 obj <<
-/D [1574 0 R /XYZ 56.6929 507.5641 null]
+1991 0 obj <<
+/D [1987 0 R /XYZ 56.6929 489.3118 null]
>> endobj
-530 0 obj <<
-/D [1574 0 R /XYZ 56.6929 426.6253 null]
+646 0 obj <<
+/D [1987 0 R /XYZ 56.6929 437.3327 null]
>> endobj
-1579 0 obj <<
-/D [1574 0 R /XYZ 56.6929 399.4643 null]
+1992 0 obj <<
+/D [1987 0 R /XYZ 56.6929 411.1024 null]
>> endobj
-1580 0 obj <<
-/D [1574 0 R /XYZ 56.6929 191.6116 null]
+650 0 obj <<
+/D [1987 0 R /XYZ 56.6929 208.889 null]
>> endobj
-1581 0 obj <<
-/D [1574 0 R /XYZ 56.6929 179.6564 null]
+1993 0 obj <<
+/D [1987 0 R /XYZ 56.6929 179.8493 null]
>> endobj
-1573 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F53 1029 0 R /F41 939 0 R /F62 1062 0 R /F63 1065 0 R >>
-/XObject << /Im2 1051 0 R >>
+1986 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F62 1352 0 R /F63 1355 0 R /F21 930 0 R /F11 1442 0 R /F41 1208 0 R /F53 1303 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1584 0 obj <<
-/Length 3620
+1996 0 obj <<
+/Length 1853
/Filter /FlateDecode
>>
stream
-xÚåZKsÛȾëWðàªPUâd^À
-®p÷ÿºøø‰ÏR8ë/œ©8
-fOð™ˆc9Û]è@±@+å)ÅÅýÅßÛ {_íÐ)¦i©X(5[ˆX±È¼°,-ÁaYסaÊH=Zv!„fq`@!ç0{ÔIBŠž$„L)ÌL³PIeEQlkä ô•½¾§ p ì³ÜæõåB >O³z}ÈW™}óf›½z*³ÑÊd牛Q¯Ã¥ˆæY]mcÑg¢®+ûLÝBMEÏ•ë´¦^I“¥ ÷ ;ƒƒã&¥ÝâuyÂŽz^çåC‘¹#õ¦6îHo&D‘ëð'xZErðó>”@îí´[UEM/Oy³ÍKjãYŸ¯-t¢ ¤›{šç"Äã®OÝà$4iB‡§jï‹d¥– )%‹…–CŽ¬€!ÒDÄ}iÌ<o²CÒ
-^¢`~ªŽô¹Ì`Sö{ãæ…IöY7ø9sZIŠ$#C®gŽ51FƸG|¬’õçºHê- º?T°( =çˉÉAÕ#¡\8Òñ<clb22#d4šLŒ'Ó/(Ù`5ô[Ú€}MñEs®_TØ[vɉ¸Q훼*“¢pïÖ„à¹m®žP>–z"åA¯k-†Ê³«ÒüOÎev¨‰!OÛ|½Å&Øí6)2"“iClÔrS£öàûƪiµ£!m·VÁ/#«šÛeŠÔ-“§Í–šI™Nú*©Qm øøß`“—bÞí36=S‰CPÚ†¶‘×öÜÐÍ¿%â†3
-¯,›I–ÇJ„=Qd›†f\À$‹€…òÝ.KspX…[ø¿p<70M z4P|ŽUl©åKÑ1 Dð’F@„ÀK’zÊ 'TÃ9\hè朎ûà?^Yé}¼B}ú41s k‡wÁß`Š›ù;ë²€)Ù—d·/²«‰-…ªõgO¥¿õT ɯÔU:åb¦Ô 'H >®œÈeÞ] 3TæT¦Í•\Î%ǧêYRÉßy}<j— }±ý¯ó=Ä
-?O;ÂEÛcá$®CBŸÓlï’‚hÖ½wß¾f´‰Å”î“4µ^L°5^|ÁxOgÄ2sÅ(Œ_c„yLò"Y™ëmµ7ÕaWS³5`ÞíÑ®ðI7‰ Gx–§2 yÑ­¸r[X709ÉÇ€kç‘šä™%SÂxe«& X bÙ[]š±.ÍúÃ-¨r{6ürf¡(fZµóeÒiÝZ3Ê„ÁKusüs
-x
-u“Í2ÿJ0'°NŸy™æ>úBâq¨†'_ÃlôED¢ç}ÞÐÃ:Ê>ƒÈ±qvpg€;û9Ù&z
-p"ç¥OûìUµ½nHÇö.i°Y†>s‡/UióX Õ
-̈D«·Õ‘.TÌüÁbïÐapã½µ±'¤IÅFÈ_Òö¦!ë„óB²=R°¦ÕŸP#o=c{È¿­˜¦sÔS×mÊ0!ÙÒ\~''…
-†œtý
-šŒªZ Üè\Åa,8 y–= ï¸3µT»
+xÚµX[oã¶~÷¯Š
+õ}î}üÄ£X÷k3•g&úœ‰<—Ѳ§bF+ÕÌ,zw½í
+ÉòÜèn±<JrŤLó·±h¬@6;¡öQL­˜åû(J Árc$†1çÌ
+ˆž5È–RGèaÏ™3“jŒ‚3£$hî9nûI*â ü—ñ«x
+O• MBYƒMBA_ëMÞ¯ëG¢ÖsA½eØ;y,Û”Ôð;\3µªjŠÛÖÍ»ì 3×W<þ\äz~èòºD÷H›ÅóÍzI”O&$0™~ ²LˆåŠz»q}1spD;ØËzѹe©‚´h×ê·•?6PQ²oaßÖœ;Š±bßPDDZ
+ÔiÓ¡<¸g2íz“)ËtÞ”ÛÌÍ‹í¢NêzÑ!9͘Ժ)ªh
+ÛšÀ0]/—X'¯À™V Ð'ª
+ØȬ…ã
+(–+™‘y
+MæœÊ‰ #}LúJx隯\Æk¢oÐ{žú“Æà hbj{_¹ç­/füÞôE»éÚ³Š&¿”XjHmW3‡íq…uãåMn*¨9 þ;Š.ek)JÓX¬1¥z@±z¹À)´Õ™Jµ¥™
+[Í*Öi~è³}¨¼N¡n¼Ž-aÛ&Á'ö2ùð „Tp¶ìd¶NʤÁK Ñ„àé.µÓØû‹Îû¢òmßßX Ñ5ü«v«
+ÚÉÐwDb,„«áh×!pédø·WD“Ÿ‡R^'sª窩ŸVlU‡F²ŒËS‹£»Âš(6…áÅuaåLHc›B[U—F2gYfóv™½€1 rÖè\}
+n: Ôo¨ÿ¤ü_*Q<g
+Tymß
+Øa’ÌšTµ\Â)WùܪÆÖ ÓxJ%YÔŽæ *·)]Øä Fâ¬Ö[OL¼îˆî/K~ójñ•¨Y9G–¹Ï}øžûþÔWLúf y¶+K(œN~|tÕ~ÒX}pHÿWWÁË Ýݦ(L¥)]R|†3è3]¤¯D?¸êx}ÕâtåêŠ('¥W~ÂEš|Þ–DȱВŸžÖ›: nï‰x'u{óg·©Â]ª1äÀú™[¸‡/*»&WM7åý‘&'lhBçXL W…pÿ\\ŒÙ`ü9hð!$º³‡´½__]ã.…žÈÞ&$káX×5+Dûî‰$â'Fw4Þ Ç¿ÇgløÇàý‡›áiPð òŒ†óÑà}X<c¼»Ã¶-jÎŒâç‚îÍø A<â :œÐ].è°J¼a•ø_äQ÷ˆc@-×߉á“'‚ÊÓ@Édƺ À÷Ýi&Î7äuœ«áA1W»²—ôVÀ¡ò÷3K5ƒ°¼šñþ_ôÐMei<Z7xtøû ßW ¬ð¶| wU9 ¼>÷Ê<onFìðÈ)W^Œ Wì†#À)‹.wÞ‡SžžšžoÁÐ5v×”MPÈ î"å°Ë„*y¢¦?…ž‚Ï»Î
+iûù _üuýËíÝ$ Å=h²WÂÕì¬+­NÃÁ@âø§‘}w¬QdßÐ(¨ÉxÙ­ˆŒ¬rgŽèrK÷ÆFýFû7wÊã"e—»7ž,R©Nßx\äÑ.Bnƒ±‡L_;2ãô½]Ú´úBÀµÝXYxð[•ò*Wð·ܾñK%R.2xðKx«ò¬ë§J¾{Å|ó£û´e*ËdûWÅÖ½˜k¦<•à‚X¾isóÒFeÌdþ­¥û
endobj
-1583 0 obj <<
+1995 0 obj <<
/Type /Page
-/Contents 1584 0 R
-/Resources 1582 0 R
+/Contents 1996 0 R
+/Resources 1994 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1552 0 R
+/Parent 1973 0 R
>> endobj
-1585 0 obj <<
-/D [1583 0 R /XYZ 85.0394 794.5015 null]
+1997 0 obj <<
+/D [1995 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-534 0 obj <<
-/D [1583 0 R /XYZ 85.0394 408.8853 null]
+654 0 obj <<
+/D [1995 0 R /XYZ 85.0394 655.4043 null]
>> endobj
-1399 0 obj <<
-/D [1583 0 R /XYZ 85.0394 384.5457 null]
+1998 0 obj <<
+/D [1995 0 R /XYZ 85.0394 633.1281 null]
>> endobj
-538 0 obj <<
-/D [1583 0 R /XYZ 85.0394 174.3152 null]
+658 0 obj <<
+/D [1995 0 R /XYZ 85.0394 552.1893 null]
>> endobj
-1586 0 obj <<
-/D [1583 0 R /XYZ 85.0394 142.2096 null]
+1999 0 obj <<
+/D [1995 0 R /XYZ 85.0394 525.0283 null]
>> endobj
-1587 0 obj <<
-/D [1583 0 R /XYZ 85.0394 79.8825 null]
+2000 0 obj <<
+/D [1995 0 R /XYZ 85.0394 90.0274 null]
>> endobj
-1588 0 obj <<
-/D [1583 0 R /XYZ 85.0394 67.9273 null]
+2001 0 obj <<
+/D [1995 0 R /XYZ 85.0394 78.0723 null]
>> endobj
-1582 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F14 740 0 R /F41 939 0 R >>
+1994 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F62 1352 0 R /F63 1355 0 R /F21 930 0 R /F53 1303 0 R /F41 1208 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1591 0 obj <<
-/Length 2761
+2004 0 obj <<
+/Length 3601
/Filter /FlateDecode
>>
stream
-xÚÝZÍsÛ¶¿û¯ÐQžD,>H€|ï”8vëÌÔNm÷òÚ( ¶8‘HE¤ä8ýÛÅhQrÒèÉd‚‹°Øýí@ñƒ|¨He"è,ŽÆ“ÁdqÂÐ÷ë w<#Ï4
-¹ÞÞür!õ ‹2%Ôàî>˜+XšòÁÝô¯¡Šâèf`÷—Wï²Ó‘HØðöîTÇÃ7øßÝåíÝåÙíé(ËR1<ûí͇»óâRÁ@¢¸ág×W—¿þyã&¸¾"òÍùÅùÍùÕÙùé?wïOÎïÚ „›äL¢ôŸNþú‡ ¦°×÷',’Yš á…E<ËÄ`q'2Jb)=e~r{òG;aÐk‡ö)-ND¤D¬#G)¬ÿuËòH3Õ¿*Œ„Œ2ÎâýSÑ8S¹&Ϧ%:RœƒpZ&‘<kM*D`R£S­ä
-¬&½,'Õ¢(œÖͧµ©›ú¹Ò%ÓQ¢’x®ð}B·S¾ µä0>˜vľ›XgÃr½›¶ÓauO´b»'x{wuKÝ«Sžým×}µÂ¢18²$vr“Of¤ëg×ïΣ ²ö”ñ#ªÁ*I£- ÿÀŽƒJyLT‚nc.ù ¨
-,g=¨ücmV…9
-[ØÂPÆìÐ`ÙYîÖi{óu3«VEóÔ‡˜Ç™±• ¨€*:â:N€™PŒQÝñ­ç.
-*SʱÛ&|X{ÿl*ö Ü"‰’Øy2}³Z3)RÇ‘YBd†dT·@¨bXgëCØK'
-Ïê´ \E3#"¨¨XuÞ Ð°±ÝvÚC9#ÑYòLv3Í¥›»®ü5Âr‰«ñiÿÙŒîx²N1‹¢i|ÍF6'˜šû|=ozrµk
-’¹û
-Z.›º!|“höï€Ìô\έãŽ8; ©åzAŠÝÙl<´µñ®õàx ›šeÅ rþÛ6äÐÓgŒ9v+&û~Qô"«>ˆ×L×ï62YGuÁ
-•¢à³IÑU©56…¿¡ñq˜YÌÂcåökßühþÓ³·gQîÕ«WýÛx׮ز n2-u–fq¨N쟞>x1½ýàÅ4Å-gÜQLHµëtÏœ ˆrên¶hÔŸeñRéÓÜÍÜš|±„KÁ‡ “×ëí¡FänÊÚ€kLýKa/¾°ù>/×ùꉘùë¾sÏ ’A5¼€ê£z¤Ï=1_k3™YåSËú*<sb¡,ï¶ÜgǺÀP”˜¨@të°hÀx[¦óM "<@!òÅú~ì.æ cjêɪ[2®;®6&¢ÍïùLS‡.xtPû‹Ÿ¾^ÆÑ9}pç:›cÉ_Ö}¬wçi|¢À5J,¤ÿRTàÅã(ÖÖ¹îZƒ·çêÜäóµã»·†·:.›ZøÕÑ‘×xÑ„/deÿ¥’Oc¨›Æ`6ScS»šhù&/æùxîX|iæ†^x¶1a}ƒå)ç|ˆ×<¬ä”ö(öY¾1Dˉàw¨œÄC[W­¬¢ú:P)J=Jû¸{yÐ54å }ÅzoÚ#…v{ ¹.СH£ÊGhç{Hz ʶ£ @‚*¤Sˆ=ÅÄÞ
-ªÜxa:cÀ?ËÎœ)¹ET™Q¤ÿ>+CÍgˆSóÃ.Dºû[ýR`Þòì‹Ì˜FDv 9¬Íe>“=_àÌ#ç@K«I<[ÍA=>,"¥AàÚogPÉ®‹£uuL,yçC›pHE:ý iÜ·´ ˜ ½ Iòd!?G.bz$²ým…ôUu+×ë^¿´<¢œ¹oUbpo¾^”ÔcÃ}Å ù¸u?ˆÍ ƒ)Ñë§Å¸š3]gcËJùß#oÏ[î.:θ?œa'MR»•ZTcù ©ôsšÞ0ß1nF©fÑ–ÕÌÕÆt`Ê\ Üuÿvw÷(™ Ç²Ždêë™l¸*fN{–Ë"Ã*_Šq’¸“Û+y+)žÑO·|™» p¨:òt›1µ«–;Ÿ×Q|Ør :Su¶¦ù¶XÖºÖxÝØ%T0´p¼Ój²Æ*ÝÉ°¬ìAã‰:].…õõ²·äN"ü}aO…ËZþîŸ1n+v<€§û.°Û;'š!w$ç,R‰Ñÿó2Dendstream
+xÚÝËrÛÈñ®¯àÁUªDì¼€rÓ:’£-GNl¥*¯ ’(ƒ
+·ûí‚ù2Ž‚Ù ˜ÏãX̶*~ ¤t3ÅŇ‹´
+,ŠcÏ í¡ÎÒ+
+
+»!± jÒl™o“‚Æ}™o*÷5#”æ»$M}‡„¡U[rc2§¾ØÅD*î]£oyLò"Y™]m\-3Á(u[ÕÅ5-vtVÀ¦ ¤I5Z—žNp#„´H‹N]ù±C2Œ¨øH«ec"õÉ#5HpìĨš81ðO„„"ö6 ½Éetêú: û2i‚¤jtcBÇ…¯e«gÿšŠ5ÀÐnNPÃðևݎx½¶¦LÚ¿—ùÂpñ …¸
+ås,¡àû’qWŽ?Bþ[ S+­-¦¹§¼°&da?6]êBŒ!†ùŠÆyCã'ú …††ö=BlC;#4"ó©ì§gYL.ìRfršÍÀÁÜÐÁ§4_à[b3»Ä‚Êv l6ž˜ƒI·1ëØW8ô= òrYÒ¬Ñß@¤®=ŠbÃÉÏRÞ²Úî’&_äEÞ˜ W¹{ÂÇ,Ù¹IFa‰Áp=3p­ý(nù«©xŠKÓÿN¦ð„º! Õæ®ë2ÿJ‘u@$„6/ÓÜ|ù°8TÃû,á&àC9µô0²¥È+GºÑÈž.Vô‹
+ÐHŸcîg FS|³Vña’mDϘ$[}0|›Í›j^ävÆ„-ŠuKÖY‰ù‰1êYeÂÆ£d;¹³u $í‘©;’|Âså(,k™ãí&Ûç³O6µš(ˆœD<<¼ìKÊ¥]µ¿Œ¼C‘Õþ·ì%dÊS](0€±‹¡mú5Öˆ~íTfšÀ1¥¤ã&{W#OÎ6K‡ò
+ŸŠ"N$Ï:c0)é}úYe¹ÿ «È×±>_”Sj¬¢³,:'êp2#í~3gd¼ÿ­/ã0?!ã\»Â2,·µSX¹Mšå†&H»¼¯Xiž°Ö-Ì8:Ó6¶µó=Å9+·üÿNn{ñ³äÖÑþå ÝŽ“r+C?Rã•[Å|a5ö¸ûö£…)Õ"± jÊ]`Ï«‡ÈÝmL.þ3É‚E:<O.ašTd‘õ<d3½‰L¤Vñ®2i$¬«îqÐì쇪u"þ¡fÏŸEÍîî¿{}û±7; ¯ Í—(²|F¼ÿXøìÑPh`AŠ>—J$Ä01ñ¶
+v`ZÃ<]©ëÂCݦ(onîoÞ›ºÇÃÍTMBBî--Jsk
+KzæÑÆ„ÝÓlö¥ÉJŒgí÷2u!‚5¬AÛ^µ…5 )•X쮯ôDh#õÂö± “46'Š øÒ;Î…ÀªÙៈš´rq}‹H )uåpéW+»£`¦½Çë·×> ’‡^<Óúã0)ÔP»o}9çŒ1ï:Móþ!·¹»Ø­¹Ø”šá“/ಗóZ̃”d.çÔ|þ¨¼ãèhŠ?Ž…8ÛÍDŸz3iSšÞ‰6}´‡P©ˆ~Øî†ëˆŸØ#~N† ¦ÐÉIE> »„)zþ@„«„3æ3Õ>£ì“§)GÌQZº’ @µ™Íˆzy>=N@²Ô•û¹SbÑLzììpµ¨ÞÀ'Ô,ò2Ùûëmø ®G¾}N³ÅRÀ¬À{‰ø“ d0he+Mš¤5¹/›C[ÃÄï­jµ!=~X]ðŽ£m²ÿ ”°sù–pªŸ§E•¤ÝlîJl¨§T7+”P³ÛCÆ„1&öûǬ}†aí"k ×è›P'î=K …CKˆœ¸>/ÌdŽ¤Ã
+åx!‹«ƒ“—±É¸òVÄr`x3]ê¿jß°j”α
+ÖÅÅ¿ã"'f&ÂYyX»sá­‰3B¤± 
+ú&Ú7JƒV¯¡ïæ 0N˜G¶Pžz cüO“n.kÐ*âмSØq,$|Á"·‡<‰­PÃOø‡’‰g!L Úö ÐXŵ{ÕEÃjïEv:mŽcB‰h”šT`Ì Œñg«ÆåmöIY¯zy‚iŸè0T¨,Ž­Rƒ®º%‡Ø›Øw*nË“èå Sî4¦:å…¾QÞn‘3ØoÕúøt_SD•tû¶ÚŪªD)㒤̳¯íÀfŠx„9ëtå#ÈN¶'…¥ŠºNa->ÄqÊ{'üsEøÊÙ«‰÷”4ˆþfh È2«k¢ ‡„ ¹zS¨Â©½µ©-‡¶Æ¬µÖæ†Ô#®/¹õÒN¸/„œ£—©¦•—Ž"ma§*Û-›mLggݲ)Å„ðY1ñ”ä2RÒJô:ÉKß=F~H=ôP×E7_cáVòÎ%~Kþ­ÀlŸG
+1— àŸgB‡R³ðêœQÅîÿ13TÆendstream
endobj
-1590 0 obj <<
+2003 0 obj <<
/Type /Page
-/Contents 1591 0 R
-/Resources 1589 0 R
+/Contents 2004 0 R
+/Resources 2002 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1552 0 R
-/Annots [ 1593 0 R ]
+/Parent 1973 0 R
>> endobj
-1593 0 obj <<
+2005 0 obj <<
+/D [2003 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+662 0 obj <<
+/D [2003 0 R /XYZ 56.6929 306.3415 null]
+>> endobj
+1788 0 obj <<
+/D [2003 0 R /XYZ 56.6929 275.1221 null]
+>> endobj
+2002 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F14 956 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2008 0 obj <<
+/Length 2796
+/Filter /FlateDecode
+>>
+stream
+xÚÝZÝsÛ6÷_¡{“§ƒ ïžòa÷œ™Ú­íÎÜ\ÛJ‚-N(R);Î_»X€%ZNÍ\&“q-‹Åâ·‹Å1øÇGi1™Å#ÅQÂx2š-OØèê~<áŽgâ™&!×ÛÛ“×çR²(SBnïYiÄÒ”nç¿ßýûÍÏ·gק‘°±ŠN'‰bã·—ÑçÝÕåùÅ¿^¿9Õñøöâê’È×gçg×g—ïÎN'Y–
+h\Û›[läZÞÜ^¼»9ýãöÃÉÙm7€pœIÔþÏ“ßþ`£9Œõà ‹d–&£GøÁ"žeb´<‰%±”žRžÜœüÒ jmÓ!£%2’Tè« >âq$c%zfK2š$Öl0ÒÓ g¬?Ò6o‹¦-f ŽäˆÀúl4i¤t&­
+`Lo©&çyQæÓr‘~Õ¬ÜÌ=oYsÍêMu
+’®@hyK¥GcG>Ü[QÑ×YR"Ý°àZ niòª¨îï6%Mµ–ô<å}Ij0ÈÚs‡S§2V5ôÕUóE8 0ÐaÔ飣L`Q2)ðô¬3ÔU×AÞšûz]|öÒµ×Æ »«Ë²~„q:Ùf†ršhÀa³$)-£T}™»òH3Õ÷Ö¿ÕÈ«€î$£ì`¸ v D¹¢oÑ5qÙ¨Ü5Îô6„œ‰Hʘ”J¢8㱇‹jV/;ƒ]›?7¦i›]{I =pžÂ¾NçNä ZËXD"MûZzt6®6Ë©©N)Îhë…~Hðëýå U2ÝølÆW1ùlAæ¸úùÝÕû³=ô$RGB%êˆÖ@¨H¦Õh²øÿGLÆGĤH"³ôLÆ<â)Òö0ùËƬ s
+37$S nê²9̧£¡^~r‰¤_çW> y(Ìãi&ÆÏ{Áñ&à ÈGLXHÙKN¤,R,£\í2_ºüêƬülô7 Ãþ°íêX‘ù öÞzÚz‚eÓoʽñW>‡ b¤¥
+Ó…>HiÛé¶(¸§€&y,|Ç€ŒY{Sñ"ãg™µþëÊ!Ò SåÕÌ|9,ƒ†Ëƒƒè€¢LÕ¦òø»§-Ýœ`©ôø³92Øý¶™ EÐÀ5DO»™r»¨fã“ÛÜQ>w¶l×yÕÜà|4Ó}Çi‹a§’¼„g – Š&×~Müb}-Ó8¨wáPﱊÇ*ñ±+*»„ ±K6v‹?€^@,àò/5·'R J)ˆàS
+üµŸRL|0.L†÷ßÍ,Žfðoø©ŒTªþʈ|‹g€ Åœ%‡VŒ´ð§·iºèóþ­;ƒ¸n̈°“¯S{‹üÊ{ä÷§;K¶9v¦(Çš‚¥­¨2±É3~)yÆ*<iŠÞ?WÙÔZ3f¤© Ïëî„ «Ð9n 3kÐÜÏó6Ÿæ l!a¾ØøU•îè æÓ¬Ìý¹–ùú#•~g ûüÇ©iÑ zíý+õ'²PÈéc÷°ðűã1cšŽ‹–Hx0Ù¸Z:T„Ò*_CP\Û6en7ÌÚRº“¤X»S±h¨êcU?VŽ¿&ÒÔÐokçÁá/ ¾]Xq‚#ñ›— J¼ë@Њj›_þçúúæì‹h¹cotŽçßo^)3qÆ_8 aFT,é\ñ¦ž}4î`ûâõÕ/ÇaWÇÊ(«ß¥žúárœ…eœén9†ŠÊ´µuo S@)sôÞ¡ãÐð…)áñÆþm@Q€k¥Æ3:✫ðömïN2¥¶š“§Q’ûþ|ùK8™ÀÖ4ÖtPó
+l?f›5ý¬Úò IÐÃcMux-K¥ðæVº[Zdµ·´2¸¥ÝV:HÊÞ2&ù±_U®¦h¼|×µo²*s¢á}ë'× ]0źùf¹²–R©»Av©~gL”®Ü¬Ì¬@qgãé“kEÙ×ô9ìû5WûÛLœÐ}œ&Y¤dæ[Ìê
+9ï7ëî¾Òž–°¯¢+1ÐÄ_Ûƒu対–ukÊ'b";SêBW‘„`Þóã‡"²8Ñw ÏyU™’*­Ó»4nÐ1,lxô±g'fÈY!jj-TÐÆ,mf†ýØÑ¡Z½¹H XA3‡ŠîYj»éLòcž{×!´ˆ2hƒ¡êÖ÷#*\=c ùŸ_
+:.»tÓUµÆ"`eÚÕ†Çq$b•õÔÙ[:®´Ø—fã¡Mó÷gopL'˜ D|û†$‚%Ô½#énôov"èy1pLùb
+{hˆÅyµÉ×OÄÌ_ EJžiæ^Çœ.b¼fA㻧+î¥KN,´ˆÃo›íì>‘‰Ý#SPÝú+N`¼ÍRyý7!±;Ô„Š¹ifëbjüØiý`"ÜÙÞåE»&ôÀ£ƒŠØ_¼IqøzGgôHë@o®è=p€*k^ø¢Â j,¤Ý
+ÎË]ÓsÏ6%¬?`v
+ùû®y˜È)íQ
+ì‹üÁ-'‚¡rs ]Z´ªn‰êÓ@¥håQÚ/»N³Äh z.×BïM{m¤Ð.ða!×!i”øí|IAÖrtH¤îXæn±§˜Ù³UA)’[¯L¯ øgÕ“™’ÛXD ŒUú×Nj>Aœ*É…†V^HèñäÀBNöW¿¶Ü.ܘ‡§Ï­˜’Å‘”÷JÙ0ÈôþÆؽËÜ×ý U\endstream
+endobj
+2007 0 obj <<
+/Type /Page
+/Contents 2008 0 R
+/Resources 2006 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 1973 0 R
+/Annots [ 2013 0 R ]
+>> endobj
+2013 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [55.6967 389.5558 116.8967 400.9478]
+/Rect [84.0431 269.7901 145.2431 281.1822]
/Subtype /Link
/A << /S /GoTo /D (statschannels) >>
>> endobj
-1592 0 obj <<
-/D [1590 0 R /XYZ 56.6929 794.5015 null]
+2009 0 obj <<
+/D [2007 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-542 0 obj <<
-/D [1590 0 R /XYZ 56.6929 374.4628 null]
+666 0 obj <<
+/D [2007 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1283 0 obj <<
-/D [1590 0 R /XYZ 56.6929 350.9179 null]
+2010 0 obj <<
+/D [2007 0 R /XYZ 85.0394 748.5408 null]
>> endobj
-546 0 obj <<
-/D [1590 0 R /XYZ 56.6929 144.4344 null]
+2011 0 obj <<
+/D [2007 0 R /XYZ 85.0394 686.2137 null]
>> endobj
-1594 0 obj <<
-/D [1590 0 R /XYZ 56.6929 119.2896 null]
+2012 0 obj <<
+/D [2007 0 R /XYZ 85.0394 674.2585 null]
>> endobj
-1589 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F48 953 0 R >>
+670 0 obj <<
+/D [2007 0 R /XYZ 85.0394 255.5751 null]
+>> endobj
+1658 0 obj <<
+/D [2007 0 R /XYZ 85.0394 232.5802 null]
+>> endobj
+2006 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F48 1228 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1597 0 obj <<
-/Length 2948
+2016 0 obj <<
+/Length 2917
/Filter /FlateDecode
>>
stream
-xÚÍ[[sâ8~ϯàÑT ZÝeí[º“ôfj&é&ôl×Î̃N·§Àf°I:ÿ~.6L ÓEñ`Y–ŽŽ>«$HÃôb0Ó¼§4GÑÏÎpï+|ûpF|›AÝh¶z7:û×S=´¤²7zhÅÇ1é&¿Gïÿsþqt9ì¨À‘Dý8zw}sáj´{¼¿½¹ºþðyxÞW<]ßÞ¸êáåÕåðòæýe uL¡?(ø¾w#ÓÉ÷¼]¿¿ëÿ9úùìrÔL œ$ÁÌpÿ÷ÙïâÞæúóFLÇ¢÷/­iovÆC‚3V×LÏîÎ>5ƒ¯¶kh‚ÅHÄTµ FijB#É(³¨ÍŠIöÆtœTY‘÷L°è¡X¸Â}ZU©//ú$ŽÒd’ÜgÓ¬zþ I¢£óÉ$3“©k™UZºâ,yv…dZ5M÷œ[‚Åc6I'®&óÃWß2ß}\L—³Ü Cqôßo©oØaîB‚º‰d“ÉhSª|?WN¿geUº2Ìç)Mí ä¥o_=aÇò'xc4Ê*Wû5{L˦SÝrá)çE>Éò¯uõ2·™—<™ùÖѨînå²e±“´²‚å(«llYŠìÁ=“ù|š“ûiŠLwXa¬0c â5Â1A¤? ãèÆqcä8]<ZM¹É뇛@¹)Ùƒ¦õdÌ–t?Áæ qI×åúUj¬vŽïúa å‹uuR7ŸT
-³DœÉ^8öÛ&cPÃH‚Ø"ý¢áÙ"Y÷ØWÐLÆ+‹BÚð‘)|†éßË´¬yÀãÑð“—ÔБXƒ¥c„mŸë®9÷fÆR(-_3NA '`
-tL¢°0ÿ½±0휉14¬–®œ»XÉŽS `ñìÖ-í^¬
-!:"hSj€½ÿhRmGþ‘yí\Ûg3 8HŽNOÖ.0HÔ1îŒObˆL .çËêÛ§Åó0ý ‘˜‹høyˆÎô*™IÓ•
-ñÒvÇâb÷d˜D`À¥oøla°Ç:? s¬{ìBA(h—-dPÇu£©ß‹2­QMª6Uj2Afå{WÍš ª¼ó5÷Yü-ÈþÔ&*N®ˆÞ–+[i$É>[% GL4î5ß9MXa®Ù”$CÙHˆy®K’©1^ j`ÙƘÁR¯…¯µ`ß&ÿ WÀq-»¼æК5^áîrhÌÆoWfcþüú€"Æà®’lz4ß`ò0ˆ¹]wýË @“8U÷KãÒÒ±'G5E„Ƹºþ
-jh
-ð½\,Ž†¯§½ÖåSu®Tr$éØRéDD1ÚØÊ/·¿ž_߀ °¸Âû!~–°M?K¼Ÿ…/5mä^½O%¬%µ ÖöíH—Z,¡D Dz1„“b–dy ãà⸹Éó£|j¸§êS)!s†Ô QIãUfbì X³q;¼zš|:PT|žkE Y–N^˜K‰M¡ô×.meážótñP,f¡¬ÕŒ´ˆ‹=¦Íy2´œXb;bPmîñæ_gG­+]$ˆ7"AU§ô¦Ý¶Ô:Ê-éö>R»ç±)¶ŒùÛ@$ŽåŸ…FJt ¢îÑ.¶DÆHkÜ
-RjPÛ¸XÚëÀæ0†Q&¢!T"¶Têf{Šn÷
-µ¨šrRUéliS¸çJX}Ÿûeå
-“¬´Iï¸ðA˜Û’ îi¯hÛ+ÔæÍìõIôìÞ\ôiJ–9S(íEfSºþè M&^vËŸÚÖÜʲwºy³/Eut}aë°½§í?WÏóÔ}MŒ&™¯ãiR–¾nZß‚vßîSwó›Õ[´Ï³÷!¥nö T›Ê)‡¯}¶+˜|)¥ò 9iÖ¿Eˤ¹@¦6µÌÐíqa°sÆ×¹=ªî…rý6EYép-ùA^ÈõØ[(H<xܱ‰‘¤¤ /Å|¾Ï1UpÊÏTpÊo^Ü?-i|‡ª-·Â+eЩ5õ1}’V‘~7Òæ†c4Ê—³{K„»p¦n¥oæmír‡k¸â¾;¡à%rs@§Ž‚ÊZ„^L¥Õ#Sðz´V÷ägäÞÊå}iŽ’ójúܦÆNÉ-ì K„N™ T?-|¦PÏÜ”ÍÌÍ3 `*V3m™×déwŸÝ]ím{#Pº=-ƒç|
-š‹»W»Õt§£y“¬VÌi.sŸ :Õ²©\w[cÒ Ù²)CPLIíŠgÉ÷Á¾£H
-Ý’ûbYm Æ8dô”õ ‰5¶± û¶øÚs…að§¦ù h¿­¸[T_D;ä‡C>Ï°ŽC~¶þuÕ4ÚæbÍ
-oÒ2\ w†Å÷l Ùò¦ÒÊž‡{{-Ü ã†äî4MÜÜY?.a,ëÛ,5¿²IÍö6$Bµ­ îu&óûþïnõOD®‹Ãºµ­(,AÓ´2ñ¢¡eÿÂ%¶áðÐó­Öÿ؆QÃendstream
+xÚÍ[ÝsÛ6÷_¡Gj&Âá“ îÍíÔÖId¥×¹¦´HÇìH¤JRv}ý-° EÉ’iÙjFã\‹Å‹ý
+£„‹oA³m¨)CBÁ…Cí+çÚCUÇuVÕÙ´Â÷³å|¥U¯TQ£àn¤fpÝ0FŒRÜöC#¡cT·ó†#FéÓ>Þ˼NËʳái —ÄH&—É]: ÁƒÛb6dÁ¬xÈòoH©ã›YZa¹ZÂÇù<.³ÿùúU§K!X0mºÄ¶wqtœ{K3HX”CÅ}–¤•Õ¥‚‹¢Ä*i<½ÃZXéÉÅ-ëFXíž‚„êŠu fém=/*+³âÍ–ó¿d>}UÄ77®¿ô>‹ëFš ½zœß
+'ñM6ËêG»Øü™à4I2Û8žaͼ¨Ýòƒâ<~Ä"<ñÙYN R2ß=ŽÎ–Pùm7œÿ¹K}…xÛ\ͳ$q¨qÝ.[Nÿl+,ÃxÒÔ}-þ•¯_?݆•EVkV#µQlÔÔ,‘jQ䉳=HFµp/¸ôlÉ©í¨iî¬Ë–QDhW*ñ Ù->ãÅb–M­!­©]³‘B€¥íx@ÖÚÚ+”ÆZö´¼w2ªç-pד…Œh!ÂÒ`Ê#¾È•IA$ø¡5OöªF´vöí(°òŦÅ:«Q3"ðôü¥”«ØÂt0 #ðÜFƒ· IÄØko_Ci¸›J?m ]pɃ34,nYm†Tm´V]¿m46
+^Ról¬ñ„eÓb'@ÂÛF´
+mzU†p.UǼI;³ü>žeÉjŸd¥®EùöôUö-ë%ÎÀ3ØwFuÄØï0â=±ˆ”šðЈÖ.¼ÿd7àtŒ‡Jöµw\›ÍØ`/eîˆzÄæA@‰ëžhA
+E“-œ.ë»Ïåã8ý2“Hª`üåámU”™MïÓ•çÞk í>]i¯ Ò²t ø?Óiý,ð!±&3C´æ}!B51Å´]*Æö—„ÕãÓ×ãÙ‘ôˆñ„€6bº/b
+Œ~»-š¡‚müå·‹q?œÿ-rd]ÆyuÛì{ì²½àvÄ>^pD¶Q؃­0†H ¡¼ÅéË"‰ë•5äàJ?¼gy<Ϧ>ðu<Þ†¯—üÈC
+¬¡aOH!"M¤MHaw
+íŽ#Ø\ŸæÕKŒ6òVi^?]G¨#†NÛ
+¬'"ZjQ˜¸´¬\æÓØæUýáÀÐX•‹‚¦EG÷Á´#íc
+±«1¡êÁ4DE‚µ˜Ú¼”î­„Ïn"ô ‰r¹§‡•P{Îø<šŠ‘G+}a¶°ËUvÐaG¸#†P„„ö; aH¨;¾4‹ÝáÓ4¶ËŽ”‡Â2™ˆÓ}ìEÓb–<Š 9R}‹›k¢™FgaçõÒ¬ö£ù¹ 0!hìãræ,¦¤þ€¾Äø¨ííræÉyõÐ Û½Ý îíBËy£‹{rªŠ‡µbµ¡+ÚÃSŽ
+N¨E»\ÿ.Ë*­÷YŸ\o®O dþ2Íʯªµ±¼¶w_üš$®c²M[Pµ˜yªZŽh•É=·*€ë¥ÏwS"µb›Êd9[%±Ïue²{9Hx%lÄ@!#³½N¼ZÛ:óø6Õø'3’Ù㘥Êhë®ÏÇÖvüza7íO/0"
+>â"Îfs¶`Ø‹¼—?;ˆãõÃ,¢$ìÛIb‘£¨Z_pñqü ¬D‹H¨àó²<Àž÷3¸®$>^ËTH éÙfbšA©jíåog9½¼Úö
+Y„è3v
+|®´Õ·¹YÖXH²jëüiác1ÜŽ
+ÝìÓÝêv·®í›ÝH²àß0µ%'œ-Tîî³-]~òŒ’Ä+ïöŸcØû[î¸l·©¸ .Ï Uá?׋¿Æv)Ù¯ÓY\Už6k.Î?â·›/‹‹Fe‹í#w?‹°WßM»%¥·­9øºçöU†+ Cí'2içË2ƒ©Ã'©—å Ë£a{gÎþ
endobj
-1596 0 obj <<
+2015 0 obj <<
/Type /Page
-/Contents 1597 0 R
-/Resources 1595 0 R
+/Contents 2016 0 R
+/Resources 2014 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1603 0 R
-/Annots [ 1602 0 R ]
+/Parent 2022 0 R
>> endobj
-1602 0 obj <<
-/Type /Annot
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [333.4761 85.0848 413.3061 97.1444]
-/Subtype /Link
-/A << /S /GoTo /D (clients-per-query) >>
+2017 0 obj <<
+/D [2015 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1598 0 obj <<
-/D [1596 0 R /XYZ 85.0394 794.5015 null]
+674 0 obj <<
+/D [2015 0 R /XYZ 56.6929 741.8766 null]
>> endobj
-550 0 obj <<
-/D [1596 0 R /XYZ 85.0394 717.7272 null]
+2018 0 obj <<
+/D [2015 0 R /XYZ 56.6929 717.2979 null]
>> endobj
-1599 0 obj <<
-/D [1596 0 R /XYZ 85.0394 695.4159 null]
+678 0 obj <<
+/D [2015 0 R /XYZ 56.6929 609.8545 null]
>> endobj
-1600 0 obj <<
-/D [1596 0 R /XYZ 85.0394 695.4159 null]
+2019 0 obj <<
+/D [2015 0 R /XYZ 56.6929 587.5432 null]
>> endobj
-1601 0 obj <<
-/D [1596 0 R /XYZ 85.0394 683.4608 null]
+2020 0 obj <<
+/D [2015 0 R /XYZ 56.6929 587.5432 null]
>> endobj
-1595 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F39 899 0 R >>
+2021 0 obj <<
+/D [2015 0 R /XYZ 56.6929 575.5881 null]
+>> endobj
+2014 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1607 0 obj <<
-/Length 2370
+2025 0 obj <<
+/Length 2524
/Filter /FlateDecode
>>
stream
-xÚÍ›[s⸀ßó+x4U‹Žî—ó–I`[;ÉØSS{yð€™xàÄ6IeýiY6VÀ8ÉÖºRŒ­–ZŸZênY†?ÒICMOŽ&¢7_ŸáÞwxöã)Ë ªB¿Ô§ÙÙ¿FLõ 2’ÊÞléÕ¥Öšôf‹ß‰8êC 8ø4¾º4ý8˜ÎúŠçößl</¦ý1šÿ9ÿ2N\)é º;¥øÅõÕhüã/“²‚ë+w{2 'ë‹aÿÙOgÃÙ®~' fVûû³ßþÀ½ôõ§3Œ˜Ñ¢÷_0"ÆÐÞúŒ †g¬º³:›žÝì*ôž¢û q®Jáôp³® Í–—F É {Ñê@¤ƒ¥¢ˆ S%Þ8H ½4ª§„A’QVŒÃMú4
-ãÕ6, žÑt5š±e¯óÛ(í˜Áý6JŸì¥ –…xŸè Ê`d¤Áì6Î\¹y’–î’Í"syâBue£¾š”`¤$7e£ËƒÚ v%„ #-æÉv“[=a ‚di?ipç´xˆ“mæž<Di'›Ì=wåXiSöŽ¾h¡ƒ«$þ ÝRV_èèšío‘)=WU‹ÉC¼ˆîÉ:Œ7«'÷t™”Å¿…óÿ=†EÙ…{4OÖwa‹Wƒç¹‰ç¶
-ƒÇ8¿uW–cqñ¼—ŒÔ½´SSèLºW«²†Ð}¬'æ¾ýŽ1ÝDƒ}ýüžBlo¨RU§3÷-ÛÎoÝU˜íSB(’T†t¾ÍoÁð&ÑŸ{†¬“b­Ê¢áf±¯>°`ªDYfÍÖ6 †À„RòyWòÛ0·«ƒ“íÊvI
-3èi+çœ-ÖJO·Û$Æ…è†h[B§()½~i“o5ÈìDôë.>¡5’pyŸ0QaŒ‡ïS¸ø’Fitÿ†n½ü3šïœûb[ùöÄ}–Ñtå¥â,Þ- uÊsxüþ}Ô(Ôyec¢
-2\Òçyꛄ*5(,ŠÃ ¨A
-k駷¯Ò\ªÀEkèý@Hx¥<RT9¸ \ºÞí Dû‚1~Ý]Ÿ!ýÈ£M¸™—7¦9$Jıå ^T9É‹1KBþÁàd°<‰ ƒ CaÅÚ!Ü/U)‚?p"í:5àÂ[Aê™ÄÌ³Ü ÈB>CnI¹™4}ZK Åì™—Q6Oã»Å—ä¸Pˆc¥ë6Þ§·%Ä0¸Çsj
- %Ì!cÛ¡Ðü uÖ ~¼|ºÞæ|Ï‚b`6 ^e£ã/P¨05ÈÊb›*WëImrt˜ž§ÖÇÒûXCRŒrÒ
-¦¯5÷ÊÖe{‚žrFˆ!žäR6 „jc´<¡áÞy[«âXª`2ic„{^›Ý ªzªvwR#1¤á%T…„*fî€Êv@å;úªv×B‰†˜“Ɇ—–D+$)užùêëåõçóñx ÆE0ïÍ@k¡=Ý:LPQ„5! !¶‘R•žx8±'zÿ;ê œîÛÍvLN{n¥A¤íÙb+Ý©§l‡g¹„‚´aÕ$’!eKY&£ëÉç!Ll»W &9¦i3ÈP ~µf¶Há ç ü”Š×'¡š=ÅË!Áä$‚åjË/r碓´Ý"é©Úa LÚ#/MÉ Ò˜:7>¼¼šâÓæ³-ú;Ã?RBO¯ŽfdG8zvx^SŽ¨ÄMÞ›*¤¹rÞûsœ­ÃÜž æF€ï¾ÜÞà¾k©÷¹pOß['¡6‹&NÒ†8>ë˜ãév3íq¡Fž³¾±ÌtPI¼“«§q‡¹b¸É±c† “αÿ®£þ@a»€×dDq\+ZEßÃÜý„£KOËî²Ôd¹9ŽÒ@%fµçv,PNaÒŸGÞÔ‹¦C—×Éä]”.“t} d¡bǧº’ˆƒðqŒ#L¥—ŸKÒü4~;`¡•9x’ð~›äauúu“;Ï¿:ÌÖÓû½pm'9µïb†lnßOÒp¯Ñuú¸ú'v'Mkï–Or·Ñi·“˜;\¬å+ö%-“»Ržêÿf3Šâendstream
+xÚÍ›[Sã8€ßùy4Uc­î—}£˜ejº³Õ5—‡˜Æ³‰Žhö×ï9–+äâÒU)"˺}::G:2¬Gáõ¬"T8Ù3NE™ê ''´÷Þý|Âê2qS(K}¸;ùÇ¥0=Gœæºw÷´e µ–õîFDÿuöéî¢sE#MNc¥iôáêúÜç8ÿóñæúòêçßúg§FFwW7×>»qyÑ¿¸þxq;g9Ô—A uÝÛ;¬T×¼½»úx{ú×Ý/'w‹„ƒdT ôßNþø‹öF0Ö_N(ΪÞ3<PÂœã½É‰T‚()D“3>¹=ù¼h0x[U]MJ ¬¸éÅŒsÂ$ßÜ­ï‚B·uÒ)¢%¯z®½XN„rí,pÌ‚HJ³žQŽhÁE5 Ÿg/ç³|:MFÈjð ³$>´*ÛO†óY‘>%§±04ú6OfiRø‡‡|† =?¦ÃGŸW>Ö%‹dö”Ì|z”ߘ ÓªÎ ÃΡ—˜1â”âUwÉ÷aRÔÝ eóÉ}Õˆ`Qþàó’ïiQ¦ÙWÿäÛle„‚­ŒðÞË lM‡Å`Õ×Q©Ÿ éTT¾LëÌA6ò‰áxP¯òžëù§b~_$ÐwVŽ_–{òº?ª
+WØAmw)¶ „šß
+&š‘cGŽ¿A ˜ÑŽt͸Fó„ˆÊýø« /ó È3ÿ"ù>Ò ÛÄ×ÏiùØÖðújÓ‚-jõŽSpO=Š%zY£UqSmIH$¹ÚgÄr¦ë&ƒïñ®½0*‰ãÕêÁªù´Ló ÈJg¢?©¢E’àƒõ00w”ÃY:+„0)š…«*œ8lˆ@µÁ}>/_Û!$‘––¶†8Ê*‹â_ξö|¢˜‚Eù8¬°ºtWÛÝ
+<I2° ÔÙ%‘VmRSj !ÕÕÖP@@T²Vc4Ìg^½ŠižêÌJk諳]AR¾RÑF%áB5s<ÌçY‰ ?.üz!žÒ|^ø0>…×…°\àyÈk†J°ÓBõBû>‹ ƒ$TC“qSàPN@P\fùv' a :G]ã.éx>KºÀ LšQ­"¯oÔÑCUÝO7X4­t­ XnE°j¾\¯ œQb´tu§¥‹%—Tf¡
+à‹«)–`ö—Uß´ª€ï}9Q«æ€*ÀÇF×y™ü†ePÞ´XgÒ=¢C«Fnšó§tÔ¸º ˜×ñ‹»ð™÷ƒáŸUÙ‘5Ì'ÓA™Þ§ãxEOKl‚ÉÚBcÊ;[H,R°v”¸C¢3› Æ㺅ÿ™äÿ§?)åY²¶ë¯³ÆAÓ ºðOÅ=?¦Å:o¶T¯Q¤³yùŠ×Oþ^3­°EáÔšºèzßÀ`Ãj7'[‹™c°œŒ~eÌ%.y=çóqåó€Ç¸È}æ@òyiVÖy¥7oJ…Æ*5ððM8é?a–n°²áÀ5@›V1Õj]H…É,/}â>ñ¿Õ~'sAu”ž²¨ª[­´²ÎÌ|±él0\;e:L6ۻЖÊÞ5½ïÞdScƒ½Ó €ØnàXœ®ÆüåaÖO¾çY²Ëž¬\Qúþ‡•ªT9dŃ×}xÄ;NJÜÏm„Ù
+ú¾ÿ@–ŠK퀩ÀK;)+@¿MGƒ2L—Ï;!|iÌkj…·†±1ƒ[AR-II‰…£@I û:áøÉbúF”è^‹dO–œ‡eÉÇ’[bé8Ö*Á‰´’p€#îkºYž¿À‰/zró
+æpÚ4Lt¹e\¥l‰ß>*¸7¿P°#Ö?nà@£l—Cæ–ã}­wÈWoп«½ù‚3?ØïY*º\17Љuf‰ß>ú·?¿@°c^¿°Ó³g:®,‘B.nunçCüd¨“ßï+·8›n$
+l1m%ÚŠzÌ
+ ›>ëx'Q©‰4N6D7D,ߊsC
+Àzo€z€pG«Õw…ªãJ’1î¹úË ß*%©6Q¿¿®¹2ß jq¢-N
+Uí¸¡dT'êë—N½Ný^œ¨ÇŠÓZüÞÅm§é  ˼+¾þr~óëÙÕ5~n.UÔ‡çn˜m¥ÝéU’õÊ6¿péø¢ÈBY®kÏ{ÑÇÿØøÏå©RÑÙÕ¿ñ»b+£þn—çXêAmü׬½;Ì@Ôc¥©%~ãÒᨵ%Ô0ï§/oú¿^ÀRŽe¥ˆ—³Y7ÄE¥ÝÙ‚½—ì—¨äÕ†™*¦×}¯N{`wýö˜¤³xøÝtHHPI„p¬'Á¶£n•‡%ÊrÓ dÿ?ýÿendstream
endobj
-1606 0 obj <<
+2024 0 obj <<
/Type /Page
-/Contents 1607 0 R
-/Resources 1605 0 R
+/Contents 2025 0 R
+/Resources 2023 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1603 0 R
+/Parent 2022 0 R
+/Annots [ 2027 0 R ]
>> endobj
-1608 0 obj <<
-/D [1606 0 R /XYZ 56.6929 794.5015 null]
+2027 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [333.4761 684.0956 413.3061 696.1552]
+/Subtype /Link
+/A << /S /GoTo /D (clients-per-query) >>
>> endobj
-554 0 obj <<
-/D [1606 0 R /XYZ 56.6929 543.3808 null]
+2026 0 obj <<
+/D [2024 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1609 0 obj <<
-/D [1606 0 R /XYZ 56.6929 518.2602 null]
+682 0 obj <<
+/D [2024 0 R /XYZ 85.0394 447.7394 null]
>> endobj
-1610 0 obj <<
-/D [1606 0 R /XYZ 56.6929 518.2602 null]
+2028 0 obj <<
+/D [2024 0 R /XYZ 85.0394 422.6188 null]
>> endobj
-1611 0 obj <<
-/D [1606 0 R /XYZ 56.6929 506.305 null]
+2029 0 obj <<
+/D [2024 0 R /XYZ 85.0394 422.6188 null]
>> endobj
-558 0 obj <<
-/D [1606 0 R /XYZ 56.6929 293.2416 null]
+2030 0 obj <<
+/D [2024 0 R /XYZ 85.0394 410.6637 null]
>> endobj
-1612 0 obj <<
-/D [1606 0 R /XYZ 56.6929 268.121 null]
+686 0 obj <<
+/D [2024 0 R /XYZ 85.0394 197.6003 null]
>> endobj
-1613 0 obj <<
-/D [1606 0 R /XYZ 56.6929 268.121 null]
+2031 0 obj <<
+/D [2024 0 R /XYZ 85.0394 172.4796 null]
>> endobj
-1614 0 obj <<
-/D [1606 0 R /XYZ 56.6929 256.1658 null]
+2032 0 obj <<
+/D [2024 0 R /XYZ 85.0394 172.4796 null]
>> endobj
-1605 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F39 899 0 R >>
+2033 0 obj <<
+/D [2024 0 R /XYZ 85.0394 160.5245 null]
+>> endobj
+2023 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1617 0 obj <<
-/Length 3227
+2037 0 obj <<
+/Length 3512
/Filter /FlateDecode
>>
stream
-xÚÍ[Ýoã6Ï_áGW³üþÀØf³½hv7v8´}Ple#¬-§–tÿû›)‰JdËÙ8AàI9äÌü8_”ـ ¬"T890NE™Ì–'tðÞý|ÂBŸqÕi÷úizòãaŽ8Íõ`zѲ„ZËÓùïÃÓÿ¼û4=»¹¢CMFc¥éð§ó‹÷¾ÅùËéÇ‹ç?ÿvùndäpzþñÂ7_ž}8»<»8=³ÆˈB;™â 0r2=?Œþœþrr6­ˆ™dTàêÿ:ùýO:˜¯¿œP"œUƒ{x „9ÇË©QRˆªeq29ù\ŒÞ–C»„&¥Yq3kN„Ö|÷´~
-
-Ó†[¡ˆÕJ=˜uì(È´ 8aB‰Z œEZp $¥ÙÀ(G´à¢ÔÂçmºþ6Y;~H²Šñh³ "¢ewìµ]˜¦™²a–ûëê6ͳü >Ðá_HÕ·@;Ý îäðcžúæÙj¹\…¡ž^RÀ3,
-5ˆ5÷<(H)Õ@2¬›=dÅétqèf)ïAÄhmtMGJ ³eºÚnúö9 ·ñcöI-ZÑóX|(5~<©QK8W=B–1]ŠàçÅ6ýnf7wr4FÈádò­øÜ/»óO8Ew1 0ÏÃ6)|Ã5ÒMÃC–ß­¾¦ó=òmÖþVÅ«A„\;»_¾Ú9b•–ä«Ÿ,_}TùÆ‹?®€·ëµ•D0izl q”‰‡
-Üp 4÷J5Zñ›…­ׯ\YÐF'5{Ûƒ¥ª(ÕhÅoVªšIeOü£µ ÎQW
-é¿#ÆØ0Y¼ÛlÒåíêýÅdrvêev—,²yäþOd¯£%¾Ù-ª”®ÇÑkÅ!xV¶%Æ_Ÿ'Aˆñfi:ß+ÁhuÇ’ Ä,ŽQù’~„Ø%Aé°}^Iboª[¼H¿<EˆFº–MˆB±=O¿@ë]ê[³"éeÔ d=îŠq{1÷<i½ „'ÊŠ>¯Å4a†Š–3®û@ÜkJ£ÅÍPC”ÓO2ÏÕn**‰³¦Ï
-@/ΔwQŸ×ß.1ØŸNóü€\Òû"Èó†üum’«2mÂL-÷cÙiµÍ硤RáÒƒÂßþA½ 
-c3Ööøi¾Á⨰bXܬ¶‹9ÞKOÚü&¿ ¡tNC‡¤è”/l½ÆïtÉ‚KˆÙ på`$;‚|ÅqL²K¾·€1lf.}É?º6²$¶Ž(Á™HfÀfXÕ@‘,Ó$–ð³BwXðoµåÊø¨Új‹ÁÀb{ÛÀâËÚÀâkˆË’…o÷çÀ®Ãõæx¬‹éc]pg1`ËKRf_îp .jŠã˜d‡Q¡Œ®e3ó.¿
-HÑ6ösð4ïWË$Ë=ñ2
-ȲÂ÷;Ö͉¼ÜØp“ÜÞ.²îò~¨±âÖZ5[¬ÃpH^8;ÄJC(Wqä­ÌNXEúz^V §šõÁŠ3¢”±¯ «Gmhµ?ÕÔ…ºm>‚ÂÆæû,˜#À ;ÕðÂNY P ߾UxEz;¼^À‚s'!U¡®^-zMx.0Ë=Ülzg8d¾[)1·Çr%/¡Ë £Êô)ØÒ.|=ùJJù)Ëçß±çË/¯ýõ* OMhVìQY$‹·¬2ˆ¹™¢ªOeF`Ä^u­òü™*›‰t¶y‚Ö¼8ô[×$ÜÌ©¾˜kLùk+­Wa§A-u“˜fÅM•¹tÄn;UÉâX*«> ~ö§Ä‘Ê8'ºõ:,éˆåúUã¡w3L'¿c«)!Ë­¦„&%‘r§as–ÏVËúiV+Ü?קöŦûƒ‚£3YQ#6ôa:<Wí>LgÂÇQUÈ/Ê Ú»C&¦4qN˦TÕ]áZTâ鮿0ëÏ/úb/ü˜Ÿp%E»€R¦ó{@¡åy|QP3«i½vˆA„¨™x}P÷ú¼Æ©&Âi ¶¶C€Àҕꯙ4܃µ+Ž¯âi|ü×·x㟷åunÖÂÝ~ܶiý1M7n!ßÒ¢–Ò±qâX¸}ä”iÈœ”ìKN™±„:õªÆx’æó³õº¸gþ{¨Ö…e­OY× ±­Hñ›/¼ƒ|u]~^‡Yª¶´ÊRáU“¥Ù|fÕ™˜–ß^ufú˜¬qWÕ¾'Ý|€i“LURkj0>në jˆÐ¬äñïm‡ šÖª°{©þXùíKXVØËÚZ݇P% ³êUóÛËtv÷T„r*ÂßÜšÿˆa›Û,-?±Å—- âg‡!(ÇÏÛyžÒ†zR}`ÂÀ|C8PçáØÙ_‚åOCo´¯ž@]‚7hºýljóö”Þ2^…ÿ\%¡´~~úë§ÝVKõKp(É—=%˜X÷Ç2¢‡è¾DŸiG„Œ¬) Å±½Gº|”q°áð
+xÚÍ\[oÛ8~ϯðÛ*Ø5Ë;EìbN.³ì&mâY`13Š­4Bmɵì¤ý÷{ŽHI´#[ÎØ-‚j‰"Éï|<’6 ð(M´åv`¬$Š25ÏNèà|ûù„ù:úÒ0¬õÓèäÝ¥0K¬æz0zdÅ„Æ1Œ&¿EšHr
+hôÓÕõ¹=rE£»Ñ©‘Ñ{ügtu7º:»;Zóèì_ï?Œ.n]-4t%¾ùÙÍõåÕÏ¿Þz7×®øöâòâöâúìâôÑ/'£fá$8ú/'¿ýA˜ë/'”«Á3¼P¬åƒÙ‰T‚()D]2=¹;ùØ ¾VM»@“2¬
+E g¶ç?Y9K–ãG ¥U&º=_Íoû!m[qÃ<Ëy‘—)²Ól²s( F©ûêpí®ÎÿöRÀ_Jìúñ<sê. §£1Ê,J&ߨDBEI>ywÊ"\`XaùèknÈ®Ê6¥Í‹ÅÒ=MŠt£^õŸXA먞6<>?&¾ð9)ÝCúužŽ—nÊ*ŽunÚðÍw‚2V¥º¯¾™H ÷^,º:¯¤[MÒß)åy:ÁWÝsÅ8U§±PÛƆ^À)¬êü¥Z90‡‰r•Šù2+râ–‰4FYéúš%¾³jÄð›äîC–O²q2¬†=d”K©\×
+uk­xp¿‰û'ã
+xœYYäYþÉWX.ÓÙ|¹}=†L?lñ|O»¦ 'BÙ»¦"VjÖè”wX¬òq<ê_‰£S‹«-ŽêshWäÞþ"ñÛõZS"©=¸jA¬¥ÎÎý;™Õ E×[=÷"ëZ t“tš~JƯÃ2åq±dÇÄ%)-ïÁRqBÁ¤UÈܦKôž˜wà0>öƒù±u¸¼å"«™9OÅb¶Ê`o˜–Âm˜òn$%…ðœê–÷÷Ýƹ³ÛÔ«}²òD]uxS,k[äK8NwÀÛüXèBŒkõ;R·ØŠ.8Íã>cÊá+ÙÂ{WŒ?ï(^¡  GÑ»¹ßbžzçDÛà‘b 1þœ.!n_(£›<uÅãb6+|S'/ïÖåÚ0^aVDå
+fùZ@ê¾e¥û’¸× ‚+G·ŠšQ•óôÙ½»¡ºB$LGUÓÇSgšÍ²exoÿ‹AÈ´1åx‘Í—–ì W ¹ÃÈð=W¯ŠcH/DSQ–®¬mù5:U*Êfi±Z¾Ê.]›¸…#z»D AdÜã@T ]PéÈÏÓUz™B ý$172º»ûVîáF®>` D¯Ê!«m"àó9”[›É,*>ïr,áàß®cQ†«û˜ BZ½°~5Âú¸·cÃ
+ê1Ì>ýúbö³l:ÍÊt  ÷s•Ñ¥;L¦­c²–h*͆cJ>#Ó´;ßÄ_ò”æ™÷VPðìëÜ.K'A¡Úèíd„>µÔ$ø—‡“±–8 Ev‘Aä(ahM5!í4uªn'ã¤ïýä)À
+Tr°`š”Kp¬FglØ4¯Î™D,¢ò±XM'ø,<(sk|îC ¨œú
+IÙ‰¯$¼u;]øÂ, W‰§Øh™Ç×K†"»ð…5¦ahMµÊ•üµk!Ó›ˆ| 4K˜áîB2K“ÜÛWf$šq¾±ÅïÜãƾ‚÷Çòqk_±ÐÛW,_·¯ø±±¯øâ²dêÊÝ BìnaàïSºèÐÅæ劺àÁf`]Œ˜_îÕ‰ÃPäK]pHÀô4•¶9u?øìšMëÆc[*¦¦-m.ÔÞë½Tm Ä_èO5jÔÄÀµKH‹ éÀ´È„Wñ^\Éã&†é @6‚u« ¾/(Àkq¥š{ŒŒÈS¼bB£;–…ùçÕ»«ϪÊe6ö›~gE-ÓEÙ¡<ภë³~×yqøPâð}\‹«Þ’öümí^¾ÎÓ…È]~›§ÕU%ÊëÊéˆM,þèÚñþzþAv]ౘñ°ÀµAÅw¸ÕŒž­+¢V VXÕŠÕ¯«·‰KÙ¡0ñúÒuÛ@ÖmL *î¶.Ô.*ë×HÕ{Iý5ϾvI¦è8„ë 98šób–d¹^åßÝ!”eÄĵW¼<®®u¤Eâd#ƒžüñ²ë Ow«|^-Ël’º—6mæ1o^«‹ŠfÅd5­‚ q¸®Ro®tíTôPL§Å³¿ˆ¥ýE5V¶æMÑœª&,üG×40 qÛè.:Äpˆ¿µ¬­è?»#W
+ë;™ßN[>nœ¬gá±{:}¹Óƨ% þ`FÅ÷sbjÄë|Aw«zôˆÍœ†œsÜ|h½µ°k^Ø%pˆd!ˆtæüÛ쾘b¬iytÀ¸ðÁê—Ìbë¶ÃÆ ŠµÛ–‡o·P0ð0ÞöÐg}EÖP
+¡Þ¡ü@Rm9žX'Öúµ-A­ß0¢í…(,lïj[òäÂJ ¹°Ræ%Tä¯o•\ÖŽE®£LäÒ0w%{¸¥5aÒ߈üAä:›bv»¿É›”Ød²C%í\åD¾ƒ?e
+·cÛ£éVìs¯¤’Ÿ²|ò'Ö{øw÷™?nj#²r‡Â(Ž«±ã®!›¦Gc’.èuûgEž¨±1ˆHÇËW(-@ã-+k¢ã¸'Vc°qócÝ**­Wag^-MÚ’–˜ fåc¯tm[U`q,•ízy«2ˆpâà"P·Â €ùÛ¿?HaïǘAþ‰u¦„¬Ö™"J*!Õ2Ãâ,³æmÜhÛ½7çôå²û
+Ì™¬‚§S¹àÞërœ3áâ§:T‚U¨åÝ¡SšX«e»;Õ½!õ¨wº·\@OÖÊþ˜ /ô®äF~_eðÛÝRå0ò}W>ƒ ·ÊôX ˜©üÖÊç^._5ÕÂ-± nì¯2AU¡cyõç—LVršuþ5iòKãB~ü­(‹!eñ)[ýn¡,ío»›²xW ¹9ÓMYÎÌ!þN” ØpàŸ`@ï†kt›–(.;ÿüžz}ê¾ìßþï¤!€Op†¶¾÷«`ÅÃ3 eU§áŒ¾8‹ÁýD<óÕ‚±ÿóÿ
endobj
-1616 0 obj <<
+2036 0 obj <<
/Type /Page
-/Contents 1617 0 R
-/Resources 1615 0 R
+/Contents 2037 0 R
+/Resources 2035 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1603 0 R
+/Parent 2022 0 R
>> endobj
-1618 0 obj <<
-/D [1616 0 R /XYZ 85.0394 794.5015 null]
+2038 0 obj <<
+/D [2036 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-562 0 obj <<
-/D [1616 0 R /XYZ 85.0394 459.6946 null]
+690 0 obj <<
+/D [2036 0 R /XYZ 56.6929 328.1878 null]
>> endobj
-1619 0 obj <<
-/D [1616 0 R /XYZ 85.0394 434.574 null]
+2039 0 obj <<
+/D [2036 0 R /XYZ 56.6929 303.0671 null]
>> endobj
-1620 0 obj <<
-/D [1616 0 R /XYZ 85.0394 378.1456 null]
+2040 0 obj <<
+/D [2036 0 R /XYZ 56.6929 246.6387 null]
>> endobj
-1621 0 obj <<
-/D [1616 0 R /XYZ 85.0394 366.1904 null]
+2041 0 obj <<
+/D [2036 0 R /XYZ 56.6929 234.6836 null]
>> endobj
-1615 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F11 1397 0 R /F39 899 0 R >>
+2035 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F11 1442 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1624 0 obj <<
-/Length 951
+2044 0 obj <<
+/Length 1362
/Filter /FlateDecode
>>
stream
-xÚ­V]oÛ6}÷¯Ð£ L,¿E>¦™ÝºÀ’ÆÖ€]d‰i8–kÊ5öï{)Q
-íÈΊ ’:¼çÞÃÃaø#‘Hjª£Ts$0Qñ<ÁÑ7øöaB<&éAIˆzŸMÞÍYi¤%•QöÄR+E¢¬üKÄÑ"àøýâîw=M¨Àñ*›¦<¾q?Ùb•-nWÓDkEãÛ7Ÿ³Ù²CÉ`b7â§ßÞßÍþ\ú
-
-Œ1ËÚø<«ˆó²Þùœ·úU½íÚõc›é0Næ\øèõ>é\ ›ÁZëSWó}Ym¿%)Îú3$·cÕ‚´Z’ëÅR8ô°:;‹Êª¼ì6h`ÌÓ7Ü ®¸­Gµn»ùkþÊg
-T"T]gíA#¬'–Ä`INNYßr¸5‚cÏu¯{R#¡Hú+'î¯*sN[œ\‚ÁÍ·øìoÀ[-{a¡ÿƘ²Ûä…A—ž‹L ÷ÆÑGý)ùŸŸ’/kO¥èøJÑT!® ˆOª=-ÕkGú7çëÔ6&ÉÁendstream
+xÚ½XmoÛ6þî_¡60±|§ ÒÔn] y±]`C׊Ì$Âɵäý÷;Š”,Ù²³,à "¥ç^x÷Ü`ø!A$fšJs$0Aò4ÀÁ|û8 Ö °z¿¼›0h¤%•Áâ¾¥+B8ŠH°X~^~º¸YŒg£
+<”h
+‰‡ï§WÜí—×W“éǯ³‹‘âÃÅôúʽž'ãÙøêr<
+µŽ(Èó–/;_X!/9_L/ç£ï‹Ïƒñ¢9@û3ëýÁ·ï8XÂY?0b:Á6­ið4à‚!Á«ß¬óÁm£°õµí Ç*X
+Œ8!§­: ¬ú%eH[?»FCÂâBÙ<pŽ°Æû<€ú}g(bLJh$eU"~µQy7¡m¤BŠG
+´[Àâ›±Ãt´Q¸ä̃~;¥%ò€¹É–ãÍÆÃh 1Sšj³ óM1
+™bÃ4³O>,òä/Sºwèr«|m6q™æYù—.S/˜äÛ¬4'äN­ ­`*$i!he³XçÙ²p¬)óž“p8+­rQ¥ÿ”B:EµÆ¼Ušß÷)UˆIRǧ¢~RÈnR¡C
+sà°’’íÔ¿NŒGˆAÂJ HŠ×¨¬%N3GˆÒ
+z%úÿ$èÌ$ϯ%(ÅŽ Ó† öãZbÒgã>vxJ5÷<uòÉj»4~göÚ{ˆ
+<>)_
+jgaåeú'Æ@“®OßýtŽ3÷œ^~¹q«ÆU·}2E?˜3 ݧþmlÚtßf_êÛVFauзÿTí‘1m4¤
+aÕí÷G}Ÿa‰"ªU`û”%^SNÖ3IB{T»°ó 1
+ Æ0ó§5äü.]¥¥ÏÎ.-se{òpÌ&ò¨Åtê$B‚ÀÒ·?x]û*zÊ!$B",™„ss¤9á•à—¼°í™B%”à]Q¦‰íĔԭ°p_ËÇØãvÆÕ‰CÅÏqºŠïVÆ}„²êqÛž)ÅùžÉ •”îÏcÕÅS«"÷®n×ë|SÕÇI£Ç9£¯0ª½Q€â1ßeSU›NÐYÔ-ôø.¯Z‡H6&¶m0‚‡ŸšU5ÙÞ@?Ã@z[úɆ|îÓP©­Ò`W˼QàÅ×k{¡4«á¦8pèð2…p¹°ˆ¸àý7F
+Û¨ÓEРª=Ù-g¿ÌíïCÛD€
+¡´d\w¹¹‹7Ë4{èsRœÕc9.úNKÔ’¼êÒãiš.OsŽiŒ½À¹ê çjTŹ‹ß'Çl#Ð÷%æçÍ6¨»¶Aeœ¨®a?Ø—­/Ǻ“ÆmZu˃2õc:Kò'›¥jw»5›´î\€§ƒ‰5"„¿TÀ-Ô™`Ö¨*˜ÓÛ£Pbè~XÊóFTÕN(á+‹”îšýoC93?¶¦(ÿa,¹Òpç‘â|,Û¨Ó±lPU,¯×eqLL ’€{ÊY³ ªÇn'š–Àö®á¢Ù ‘Vÿ³Û3ýnQõš– ëÉeÍ&™Ø„Sk…þXß–{rmïÁ›Â‹¬Wqr|Ÿ­Ó—Sû—~O„qP·Ë7ÿCaÿ/û×bÑþT1(Æ4©²1"„º× 5U=¾ÿ 16.Éendstream
endobj
-1623 0 obj <<
+2043 0 obj <<
/Type /Page
-/Contents 1624 0 R
-/Resources 1622 0 R
+/Contents 2044 0 R
+/Resources 2042 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1603 0 R
+/Parent 2022 0 R
>> endobj
-1625 0 obj <<
-/D [1623 0 R /XYZ 56.6929 794.5015 null]
+2045 0 obj <<
+/D [2043 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-566 0 obj <<
-/D [1623 0 R /XYZ 56.6929 769.5949 null]
+694 0 obj <<
+/D [2043 0 R /XYZ 85.0394 665.5626 null]
>> endobj
-1629 0 obj <<
-/D [1623 0 R /XYZ 56.6929 749.9737 null]
+2049 0 obj <<
+/D [2043 0 R /XYZ 85.0394 637.9713 null]
>> endobj
-1622 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F67 1628 0 R /F22 737 0 R /F39 899 0 R >>
+2042 0 obj <<
+/Font << /F37 1018 0 R /F11 1442 0 R /F21 930 0 R /F22 953 0 R /F67 2048 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1632 0 obj <<
-/Length 1321
+2052 0 obj <<
+/Length 69
/Filter /FlateDecode
>>
stream
-xÚ•WÝoÛ6Ï_aäÉ*Z$EJZžÚtÝ2ðfOëh™¶…È¢¦¦ÙÐÿ}<)[±à.0 Çßï‹]ÄöG™ 1Ï“Eš'DÄT,ŠÃU¼ØÙµŸ®¨—I'"áÜNfV#Á3"2–.¢SwW«Œ.XL¤dbñ°uÉ4%”³lñ°ùsy·WM¯Û›ˆ‰x™Þüõð nKHš¥¶ÅVEJDÎr·áÝý¯ïQ:Çá“.†¶ìŸqvgê®ÜèVõ¥¥F<šžHæñ¤ BrgM¹‰hÇË·E¡»nDé[SáäcÙõ‰-r’K&=§„3)RØϹÄý74[0Ã’bù9ñÛ»).*'ªýd³ÁiÀ:¨¾Ø#YQú½ê‘ùl$
-U#Ñi¿44(¬ê 2ê²x¬ÕÁ«ÚšÖC?œÚ0tÎ '¤”äB0w²ýyô‚ˆ9eVDTU™§¨6}¹}žq™$IÒÔ ¿™KH&äìïA·³X†”½*2õ Z–‰ü;p£
-CÅó“P±œ°1R;c6~ËF«¹¢$ËSêÅ! ­Ã8ë$žæ¾ýˆd*&í¬ ½ÓÒ(”x?çèurIšÛnz({—" x¾™Ÿovôú“ÎÖ&• Ædžnth£Ú¾ ÁÀô€XèʱAwÑuŒ®1Æ¥ž¦;3]—ªš† l* â.â÷æ^nkßÛÊõºÕN•u׿LS—L¢ô³í„ˀ塿ªCSé©M{ó„„+©ñˆ¦ÑmåïVÕ4„èþ€I‘г;Q¢«• W 7t”
+xÚ3T0
endobj
-1631 0 obj <<
+2051 0 obj <<
/Type /Page
-/Contents 1632 0 R
-/Resources 1630 0 R
+/Contents 2052 0 R
+/Resources 2050 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1603 0 R
+/Parent 2022 0 R
>> endobj
-1633 0 obj <<
-/D [1631 0 R /XYZ 85.0394 794.5015 null]
+2053 0 obj <<
+/D [2051 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-570 0 obj <<
-/D [1631 0 R /XYZ 85.0394 769.5949 null]
+2050 0 obj <<
+/ProcSet [ /PDF ]
>> endobj
-1634 0 obj <<
-/D [1631 0 R /XYZ 85.0394 573.0962 null]
+2056 0 obj <<
+/Length 1238
+/Filter /FlateDecode
+>>
+stream
+xÚ•WKÛ6¾ï¯0öä"š¤ÞÝS²iÚ-‚¢h¶§¦®L[ÂÊ¢*QÙ8Eþ{9R¶lÁ­aR3ß¼‡[Póc‹,&4Ì£EšG$¦,^»ºØšg?Ý0ÇÅ!‰£04›™§Af$ÎxºŽAÞ=ݬ>p¶à”$ O›QW’¦Äe‹§õŸË‡R´Zvwé2½ûëé‹Hš¥ ĨQ‘šç¹x÷øë{äÎqù$‹¡«ôwªé«µì„® 5ⱈ„QÂ^b,I^JØ]À(¥Ë·E!û~„Ѫqó±êµ‡â‹œä ORhÜ£<²H^> ”¿cÙ0à
+Ñ ÑK÷hh‘Y4k<hªâ¥;§j£:G z8¶aè%ø 2Fò8fÖêzˆ‚a !ã†XD]«× QºÚìgB'$ŠÒÔ1¿™‹H'°¿ÙÍbÅ&§üz¨@53h)%<‹óÿ€¯ƒÚë«y@FÂŒ%WÙ7âÍÛ˜%$äqô?!ŸkQ¼”ª–3H‘aäìº<ØŠ"hÍÔ4¹« n9t'š~cúø\U“ˆ%U¶¥¤.âùÇË N…?úªÙÎÄt¥é¤¬Ž¶5„V¸–â‹Dê3¥¼±%aËÂÄ‘-­gê >¥Ë×ÒIÛα:ü @Ž;¨^v FÖ‘$\¾VºTƒv0õ Í0Û'݃1‚fß®¡Œu`íw@ÖÒ ÀEª¶)×ý@ª ®¿áz44dOFíG!}„‘‡ËªÇU`ªÂü(UÜð™Ú*µv"k)æjˆ‘,O™c‡D
+—˜´¶P‡Ý³ìNsǦ¹óVøÔÙå+±?ôésßg©Z|—=*ÿxÂGȬQgÇüìÝêØJoúE“Nß~®
+endobj
+2055 0 obj <<
+/Type /Page
+/Contents 2056 0 R
+/Resources 2054 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2022 0 R
>> endobj
-574 0 obj <<
-/D [1631 0 R /XYZ 85.0394 573.0962 null]
+2057 0 obj <<
+/D [2055 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1635 0 obj <<
-/D [1631 0 R /XYZ 85.0394 542.127 null]
+698 0 obj <<
+/D [2055 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1630 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R /F39 899 0 R /F41 939 0 R >>
+2058 0 obj <<
+/D [2055 0 R /XYZ 85.0394 574.0823 null]
+>> endobj
+702 0 obj <<
+/D [2055 0 R /XYZ 85.0394 574.0823 null]
+>> endobj
+2059 0 obj <<
+/D [2055 0 R /XYZ 85.0394 543.8373 null]
+>> endobj
+2054 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R /F39 1151 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1638 0 obj <<
-/Length 3450
-/Filter /FlateDecode
->>
-stream
-xÚ¥ZëoãFÿž¿ÂßÎbYóÐcŠÃé>®é»½]wEÛ²¬Äº•%W’“ºý‘CÎX²•fb±Ñˆq8>~¤,f!ü³(b#Í,1:ˆBÍòÝU8{„gÿ¼<gá&-†³¾]]-ß«dfËx¶zðJƒ0MÅlµùyž2¸þuõýò}"seDR{œóæ»O?®hÖˆ£N-RÉÓn?¼âR Ís>¿[Ýß½`%¥Uì—¼ýqõîÓõBF!Èx { çßÞÁ
-–bèòùÝ›ûOw«ŸèîÍÇŸïÞ¾ût{èùêîp«w+¯©¡6E¨PM¿]ýük8Û€R¿¿
-eÒhö 7a Œ‘³Ý•ŽTi¥¥ºú|õoÏpðÔ¾:y:" Ärâx¤œ:žÈ±å£Þ7-mn‘Î º+뇦Ýe}ÙÔDp×móLƒ¾¡ë¡ãWnßüÐí-Ǧ/òžÇæÀ«uEûT´¨ÇG`6ý¶àÓ3Ù•A’wz·÷ŸßÀáEÑœ­f´Q© ÏÍ6Oe×´GbŸõßÐbhC ƒN“Ì`&"J"ûêßÏÏ7ÖÖ"™%Z:Ñ =ý2s£Îƽ°¾aF×¿à‹«?ôûo–Kød‡./Ú>hÚG/÷‡õ’IK·»åí 0âpFd‚0ÔÁ¦îÎÅ×
-Œ, åHþ× T&MÓió\xŽ¯lLÔjÆÜ4—F"Í…†Ï,ÞϺ\ut¬—ÜpٰɈ™ÐÒà8ÖÀw`ó)p‡—D»èu½aοm›†í8«7ŠþPn&L0œ-$ƒ!CúˆÞ“FóûwÿÅQÌСõ=/{¢–ÍÛ7]W®«‚¨ÖŸ€Ú^§óCM4U@-™w6á6R$žyB¾%‡œ’YÅAd7¹¨ŸJš^§5~ £ðЕõ# æ|Uµ.Â8Hµî¹U¾ ÿÅÔºi ãÐðô‡Ccر“í¢ë#¾„'dJ >*E”_º}‘—G+“Ò‰• éü)5­6²ÄDBúà°è'"öN–eÝì)"w[‡›ÆIÊoÖÙnZÑa`ŒÏD{âPÎW[<|dg5­·-ª=ÊÇÒ'Þ\wìúbG»"?´e¤»õ‘fì«,÷J!k±œXþŒt
-¾€(‰Ó©ô[îÀÈ×Íï8äý¼-ó-˪¢QUîÊþ¹í`“í²G7nj—RØyF€qâÈ·Ï]Ù‹Е†1ù¶n`!|QÛäóp@I´˜?Yð9L‡äð€ä{pe1ï(»Á}ó@3Ø«€bEÒnS@ÈÖee•l© ]½G—ÙdÅÎ1ΘMÆ÷‡zß–OeU<’eØÝ 4b ÃL˜¯„ˆ¤@l¾š©¡ùb2‰œ?YŽ—6¨I{/@_3T"œÿçÚHºÃãcÑñéÒVkò}<ÆÎÅBÆÃ9dÐ:Ë)ܬÎ3˜2‰ ߈t<¦|H2‘õ Î>à`|”Jã±ñ|W8QÂØ3Æ«õ7¸¿g»}ÅÁw6ÎãMUÖLÆ“·”&ãgì[À¶d>ÙÔ¾
-ñªÅ€!(Ÿm/Ò6rG]ãrÏMû…(f÷E[éYY;IhBÖöe~¨2–tC\Ê[(S0Bù °ïÜL„,f’zbÁÙ
-â(:Kè/Y1à©4MÌ d¡%'«
-Êi”•pTh 8²Ö ³èipà”šq"¼P˜}k›ñ¨¬óê°)858Žý–ój:È«¸b7^’ʦw=Ïyvîö2rdö7ŒªÆ
-
-Òeì".†Å HkuRÚ¾Ü,HSîqŸ¹,Ï›CÍãÁ•Ü`H]àpÄhq–­îkÞ&
-PÑ’nhhÃB–㾄hY?8¨‰‚AƒøF8ùëɈ#`Nâó 4" FEãÊê…S‰dô*>VP‰ù‚ ë³~(yÝ´ßÁ#Úð°Ó(>ËEÛŒÂJ˜`_·Y[ZƒK³ØHŒOÈÂS´Ûg¢8O@`dÒùwÍs1hY¤ Dñ}QoÏÀ| ùRßä@
-„Wª¥1û •Nt.@ÝeGšÍzL-ºACáò*g̽7Ÿú±;÷‚q±)D¸Œ»ÜOË?Š¶™‚*HŒo´M…°LYµà+ÐÎCL!Féט©!³ªy|¡“#Ãä„\\õ=Œ5á=æYô9Áƒ¾ÜM¹iªÐM¥¯Á&
-D§D¸¦ÀýÎracñ¿çböÏ
-ã¯q)ã*!7ð`½iþ TRžÚjÀ‰ä ‡.ˆz_+ Ü–òmV?Žn#¨¥C|,ºŽK&Û\â®Ù”8)wmHÔœfçú APa¢ôy¦hÿ´Â€ëCy¾mž§NGÉÀÈX]ì‡ 3×½OúÓ?ÁYg°Ÿ¥“è‘‚ŠóàrÃ]ŽAƒ•3츓:(½)p -s åÔ¶öóÛ²§Jhª;­@kÚÈè«ÚÓ4a
-ØA{à–
-ˤ2¥=5½IÚÁQa…(lÚñ°ò‡5¬f/bA|†P¶|†±€¹wtk‘=HÉìE¨î±Ú·“N%¿%£õƒýÝP3¡d©*ÔPØÁº`àBæQJ=8[_KHjèS j¼B·S *‡yÏtÓ]ÏBå}Á3÷¶@ÏèèÞv¡Ã–™[U
-­ùt%ú²b7†8LûM¬oûw6ø¹ØÁ/l—Ûr"å­nÖÌ=oû¾yl³ýÖõðqv
-wf Éݯ‰.Eÿ?€ž¦ùendstream
+2062 0 obj <<
+/Length 3283
+/Filter /FlateDecode
+>>
+stream
+xÚ¥ZëoÛFÿî¿Bߎ,Šû ¹,¸‰su¯Hz‰»¢íZ¤-^(RáÃŽú×ßÌÎ,EJt b.g‡³¯yüfVbÀ?±#?Jd²ˆí‡›ÝE°x„¾^æY9¦Õ˜ëûÛ‹õ;/?‰d´¸}É2~`ŒXÜf¿z±/ýåï·?®ßÅbÄ+?”
+Ä#Ï›>~øpK\‰ÚøZÉlWïßÎIŠ|©„fžO×·w7ogD “Ò*†¼úùöúãr%Ã
+°+!ü$ ¥]Wz_æ™?ô?ÒØžwuCǹ«I$½ÕCÝìÒÎÎ î¹­Ÿ©ÑÕôì[þäêÍOí´‹&Ywù¦#¡îy4Þ!ÐœKG`1¸C¤¯Éè´”~l§¯WwŸÞ€º†¡Çv29Zû& ó¦ÙSÑÖÍħÝwô…[ÍJE q»ÍIì§?ÕèHûZ‹xƒ’éÌÌj õ~^¸Ö¿ŽÚè>X¿°Ê¨ÇãŸÉÅѺýwë5üõÓ¾ÝäMç×Í#´×ûþ~ͤµ[Ýú꧘màÙ$~h?«ÚÓékfr2ÿ×LRú‰1fÞ WƒÄWFë‹0™.0«Ïg
+?HÎvøÄÆ®óQ'Çz. ‡ý«ŒXí+ ®Âj
+¶ëÃTâi¸À%· ä÷õWl²‹~Þ›-7‹²¤VYìŠîè¹m#Kwé£kו )l<“@]86µ[ç®h_XWU á‡ÚŸ‡g¢…÷§]?Ä0a@Í l}@‘!lRtƒwŒàÈÁV;%í„ô¾(í&[jMÏÁ"ÇÃdi¾s‚S“ò{_í›â©(óGÒŒÓ@ â=Aƒ™Q_ IÅ¡SßžXB5V_ &¡³'+ñ\'êÁ
+ÐÖ|D÷Ÿe"hûÇǼåÓ¥¥VdûxŒ­ó…ŒÆ+sÈ qš“;®v0ï<dB¼fâ<ælHø2–çŽÎÞggr”2ÑTy~È‚(‘x„õ»|æ_ÓݾäNÐÅõóøR“ñä-¥N¹m Ä,'[—‚phõ ëJÂÄ/áåŒ@­ü@NÞú)mÖ/ù8\ibÇ
+Ö¬Tä ks+b]žuj¡1êÔ©a „H©“çѾÁíÅŽYÎ?²–È@26Óf‚Íø»ÉI®û¶Y—õ&-×í}QñÚÁ“hö ò˜ÐÑól“Äàê)d«ØW&Œ†LMpì¿užm3× 98Î
+ñªÆ€"¨!Úž…m”Ž{Ã=×Íg¢°›Ýç ¦ØWTn&Ä6]±éË”gšœ˜tJ# z¨al;—3.Kš˜„ØCpú£ü( õT^ÒbÀSÆÄÉÈe¡&dz
+Ši•°Uå¨ Ø²Ú3ï¨ÑsHM9žm˜ýj›r«¨6eŸåšs‡nËqÕŒâ*ŽØN‡$ƒ²á]{ï\hWîÖ2A2(ìoèU“
+´ÝÆ€tŸ¶”)òí‰vi”òn~&Bše„O[þˆ.å8µ·­)erƒ_ [bH9f£»dëâI–ÅÀª©N÷ÂÐ3+¥ˆ…6ÖQÕ@†•.N²ý%Åï¯D·•Öмxû:NÖ²7«+>êÙüÔ˜Á‹ýÁåcÃé‚qr±É»¼ÛÖOƒi r×™`æÆçÇ9Zî¶&×1= ñáX#Wd-“lå˜Ai±}÷w7ÄòÉæ3a3L+OÛÂ&1!]ÀXVaÁzWe[óŽ×Ý0ÕÔ‰x˜L>¦SœN:çaìþR Ö*¼x2*Q¾”,|ådVûL^ÃØ"’­–Ð MÓ‚Õrì G[¦OÌ:Ü
+`µŠAV£@ßò¯¤["@ó™R;NÀFR—‚/´{ϦÄqJ»r±fNñ7TÐ&7#C0Z,ksú ä´ëðl3ê¼gj;d‚¡3óPTC34s& »êKjøN W+z¼Fꢋ–Q¼þÞ
+B¼T<±lR\¼^'°N§†
endobj
-1637 0 obj <<
+2061 0 obj <<
/Type /Page
-/Contents 1638 0 R
-/Resources 1636 0 R
+/Contents 2062 0 R
+/Resources 2060 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1603 0 R
-/Annots [ 1643 0 R ]
+/Parent 2071 0 R
+/Annots [ 2067 0 R ]
>> endobj
-1643 0 obj <<
+2067 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[0 1 1]
-/Rect [63.4454 738.9144 452.088 749.0762]
+/Rect [63.4454 707.8911 452.088 718.0529]
/Subtype/Link/A<</Type/Action/S/URI/URI(ftp://ftp.auscert.org.au/pub/auscert/advisory/AL-1999.004.dns_dos)>>
>> endobj
-1639 0 obj <<
-/D [1637 0 R /XYZ 56.6929 794.5015 null]
+2063 0 obj <<
+/D [2061 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-578 0 obj <<
-/D [1637 0 R /XYZ 56.6929 723.0302 null]
+706 0 obj <<
+/D [2061 0 R /XYZ 56.6929 690.9391 null]
>> endobj
-1644 0 obj <<
-/D [1637 0 R /XYZ 56.6929 689.3491 null]
+2068 0 obj <<
+/D [2061 0 R /XYZ 56.6929 656.5891 null]
>> endobj
-582 0 obj <<
-/D [1637 0 R /XYZ 56.6929 552.677 null]
+710 0 obj <<
+/D [2061 0 R /XYZ 56.6929 517.028 null]
>> endobj
-1645 0 obj <<
-/D [1637 0 R /XYZ 56.6929 525.9649 null]
+2069 0 obj <<
+/D [2061 0 R /XYZ 56.6929 489.6469 null]
>> endobj
-586 0 obj <<
-/D [1637 0 R /XYZ 56.6929 411.5673 null]
+714 0 obj <<
+/D [2061 0 R /XYZ 56.6929 373.2709 null]
>> endobj
-1646 0 obj <<
-/D [1637 0 R /XYZ 56.6929 383.9327 null]
+2070 0 obj <<
+/D [2061 0 R /XYZ 56.6929 344.9674 null]
>> endobj
-590 0 obj <<
-/D [1637 0 R /XYZ 56.6929 225.6356 null]
+718 0 obj <<
+/D [2061 0 R /XYZ 56.6929 184.6919 null]
>> endobj
-1330 0 obj <<
-/D [1637 0 R /XYZ 56.6929 193.4614 null]
+1721 0 obj <<
+/D [2061 0 R /XYZ 56.6929 151.8489 null]
>> endobj
-1636 0 obj <<
-/Font << /F37 802 0 R /F71 1642 0 R /F22 737 0 R /F39 899 0 R /F11 1397 0 R /F41 939 0 R /F21 714 0 R /F53 1029 0 R /F48 953 0 R /F62 1062 0 R /F63 1065 0 R >>
-/XObject << /Im2 1051 0 R >>
+2060 0 obj <<
+/Font << /F37 1018 0 R /F71 2066 0 R /F22 953 0 R /F39 1151 0 R /F11 1442 0 R /F41 1208 0 R /F21 930 0 R /F53 1303 0 R /F48 1228 0 R /F62 1352 0 R /F63 1355 0 R >>
+/XObject << /Im2 1341 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1649 0 obj <<
-/Length 533
+2074 0 obj <<
+/Length 846
/Filter /FlateDecode
>>
stream
-xÚ¥TM›0½ó+|©¸6Æ`³IÚ²RÓ4a«ÕxT‚Ó@6ÊþúšŒ“ -{ZEóÆo>Þx€"b~ Ž “!Šeˆ9¡å[‡ µ9ûîPËñ/$¿ÏºK¯ßXŒ$–Q¡ô¥—K`"Eiñ䎌æétáù'nŒ=ŸGĽKfðHx,§ã‡E’>ÿš-“Ét1òâÐMƒ<?D˜xf3Lg£ŸÉøó P§ï²=§÷Î4½
-é‹¥„u*þ:OÏFó½C0“‚££S)´uBÎ0»x*géü¾&ìžC‡†Ç™À\ñÀô‚`hz\âˆì<½¥ÞªNSä6e«0óÖu·º{r÷R;ðdUFqª³m™|ò»"kU“nžgFÖf`•5¤±°9¬
-½ÍÀkRÖ6²P•Z›D¶ö&k{|¿·ÑìSŠ%çÁY€MÂtÊ乄Úe{HeЛ®•¹YF"7Ý” 0ÙÉ£”º_ ‰)§Àßê_©WUÝbÁÊuÝšze½¶x_¶Ý
+xÚ¥UMÛ6½ëWè(KŠ¢,7k'u€n·kå$9Ðc ‘DU¤ã¸¿¾C ½ënÝSaœ>ÎÇ›!Åb
+?—‚P.óx)s"(qÝG4ÞÃÞûˆLz¥×¨·UôË;¾Œ%‘EVÄÕ·+_%¡eÉâªùœÜÿz÷X­Ÿi&h²$‹T4y»yX¡Eâ²]ß|ÚTŸP»ÿýa»Y­ŸîË<©6 -Ò¼¤%œçÁÃêÓÃÝo›{Ä|\!týÊÛ×êC´®ž ¹.–Qî«ø3úü•Æ Ôü!¢„ËRÄ'P(aRfqå‚‘s~±tÑ6úãÙáÕî|ôy‚—D”Ùò{Yv‹=!IÁ3>³÷ÎL‹”Ó"qmµ—É´`e¢•5ƒ}–Œ&' ëæ=3ì»ó5¶6}¯‡æâI9”Žc£œ¶¨ì‚÷z:Îì'5ÚZuè¨HÔ2˜œŽv!F¯Õ`=ÕPoÊ‘Bdsòæ´£È7@Õ®5ƒ7°Ä¶ûA¹#&gô…
+Zm7ïaeaÕœ©ßl}¥Y‘{|$ Ž]QÇdAòd:Ç…¬Í)Åêúšè"#’É2€ÍxÉ+KìÁ»ƒw­ ÁÍàI˜‚üÐö]ŸQ,Q‹”%=ÓÉ`ÜLL£$¼Èò³yÄ9UM8°3 `òýöë ÝÉLßQõ…Ò짶Àg4¹ëœž€Æö‡†ücÉD{Ž‚Ó ²²\ZpêGšÒÑtm}¾Å– bÉ‹×lûZaâ­nÖÍYC\Àг%‘¦ßŸÞš~†Â¤¶+.’ú`Œ fgü*€^=¢z‰BsTZÛàÆÊ¿3B9…R; › Úã®1½B+¸ÂÉFwzïgcã´]ðé­‰Nx‰™r9‡
+´¿Ì  ^’êÐZDžÔK—òK—Àî̘všør¥Ú âµÃ>èSëï_‡ÇBµ>ö±> ¤B¨à»ÄAó¯ 0p9o8w0ØΓޅ1E¨/¿CÉê釞ìeÎt
+¢F/%b^°ä¿^j.ˆ^o¼«ðyÿïWüåû–æ,³Û4§9á\²KRž/ÆÄëÔŸßûçþ7rà_endstream
endobj
-1648 0 obj <<
+2073 0 obj <<
/Type /Page
-/Contents 1649 0 R
-/Resources 1647 0 R
+/Contents 2074 0 R
+/Resources 2072 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1651 0 R
+/Parent 2071 0 R
>> endobj
-1650 0 obj <<
-/D [1648 0 R /XYZ 85.0394 794.5015 null]
+2075 0 obj <<
+/D [2073 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1647 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R >>
+2072 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1654 0 obj <<
+2078 0 obj <<
/Length 69
/Filter /FlateDecode
>>
stream
xÚ3T0
endobj
-1653 0 obj <<
+2077 0 obj <<
/Type /Page
-/Contents 1654 0 R
-/Resources 1652 0 R
+/Contents 2078 0 R
+/Resources 2076 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1651 0 R
+/Parent 2071 0 R
>> endobj
-1655 0 obj <<
-/D [1653 0 R /XYZ 56.6929 794.5015 null]
+2079 0 obj <<
+/D [2077 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1652 0 obj <<
+2076 0 obj <<
/ProcSet [ /PDF ]
>> endobj
-1658 0 obj <<
-/Length 1964
+2082 0 obj <<
+/Length 1965
/Filter /FlateDecode
>>
stream
@@ -8191,206 +10005,210 @@ i ·¥Ý3éÀ–yíˆùðŠ&Â8K<æcø¡›‚hïCû™<»úÐŒ­êhüýÔï Æס\@•‰ó÷w= vV
ýf3GÕ51b‘æi‘diNŒ‘Œâ±ˆ±0·"ð0àâÄßZÕ7’\sÂw"ó‡&0ÍåþF—?$cRÍZº”í(õåŠ:éH^04g¢°û(½À ÙWáÓ7˜¿S,[>°úŒ¹…;î3`ô¦'bÕÀ¤Ö^ ïöEy˜]¹œ­Þv‹íçÞa¯Úák@n@þzh|ÇütÓOÓ0J¿mºã—¿ÞeÚâš(°ÁiÇEðá êÍâÀz҃ѣm§žæˆ§çOŒ$
­è×ØÚ:‰óÎÐÃBYn?z·XdÌqâd¾©Üä¤ÚNí:ørðï»QÕaáƒL·CÕMucVìâªV.Wª4 Û8Hü»Uoy)”@»Zìo+B)ˆ×­©ôD9ƒ©;B.ÊõTyåvÂ)Î6™îZds§¡ÁÓÏMí­µ°r=¶öä&vÓž®é^/yr€¡¶¯ÓP;«y Â1{9B€FãŸà{ËוÂM>p\×-ž‘7>å èWˆÌ¨W
¥Ìrcø-Š¼ûãËü
-“¤%œ¡i±Iæ² —â~ÚøÑŸ/¯6³Âv¡ámÒ¥ß;»è½‡CÀê/aïoãã<,EQ^Çsór4 ÝÅpµö;[ÃïVÎy7G)JΑOü©5­¿|hW°hpk·IQ„"é5¶ÏÍŽûª‡]Ù)C™‹_Ú‘Âõ%KÄQXDñ¯oʬ±]ªÜïʽe×SX{üâññ|>‡¼+¾,}w¸ÉÀdñ:Æ›š¥îãºÊǽµÿ¶Uø]5èTíŠË°ç§ð6hÿ˜ÈŸ%×"ö"Û‹ ½H.ƒ€k(,â2÷†0”2¹õ6¿oÞ»ûq0Œâendstream
+“¤%œ¡i±Iæ² —â~ÚøÑŸ/¯6³Âv¡ámÒ¥ß;»è½‡CÀê/aïoãã<,EQ^Çsór4 ÝÅpµö;[ÃïVÎy7G)JΑOü©5­¿|hW°hpk·IQ„"é5¶ÏÍŽûª‡]Ù)C™‹_Ú‘Âõ%KÄQXDñ¯oʬ±]ªÜïʽe×SX{üâññ|>‡¼+¾,}w¸ÉÀdñ:Æ›š¥îãºÊǽµÿ¶Uø]5èTíŠË°ç§ð6hÿ˜ÈŸ%×"ö"Û‹ ½H.ƒH"h<H# a(Bä·îæÎ{ÿúhendstream
endobj
-1657 0 obj <<
+2081 0 obj <<
/Type /Page
-/Contents 1658 0 R
-/Resources 1656 0 R
+/Contents 2082 0 R
+/Resources 2080 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1651 0 R
-/Annots [ 1665 0 R 1666 0 R ]
+/Parent 2071 0 R
+/Annots [ 2089 0 R 2090 0 R ]
>> endobj
-1665 0 obj <<
+2089 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[0 1 1]
/Rect [348.3486 128.9523 463.9152 141.0119]
/Subtype/Link/A<</Type/Action/S/URI/URI(mailto:info@isc.org)>>
>> endobj
-1666 0 obj <<
+2090 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[0 1 1]
/Rect [147.3629 116.9971 364.5484 129.0567]
/Subtype/Link/A<</Type/Action/S/URI/URI(http://www.isc.org/services/support/)>>
>> endobj
-1659 0 obj <<
-/D [1657 0 R /XYZ 85.0394 794.5015 null]
+2083 0 obj <<
+/D [2081 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-594 0 obj <<
-/D [1657 0 R /XYZ 85.0394 769.5949 null]
+722 0 obj <<
+/D [2081 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1660 0 obj <<
-/D [1657 0 R /XYZ 85.0394 576.7004 null]
+2084 0 obj <<
+/D [2081 0 R /XYZ 85.0394 576.7004 null]
>> endobj
-598 0 obj <<
-/D [1657 0 R /XYZ 85.0394 576.7004 null]
+726 0 obj <<
+/D [2081 0 R /XYZ 85.0394 576.7004 null]
>> endobj
-1661 0 obj <<
-/D [1657 0 R /XYZ 85.0394 548.3785 null]
+2085 0 obj <<
+/D [2081 0 R /XYZ 85.0394 548.3785 null]
>> endobj
-602 0 obj <<
-/D [1657 0 R /XYZ 85.0394 548.3785 null]
+730 0 obj <<
+/D [2081 0 R /XYZ 85.0394 548.3785 null]
>> endobj
-1662 0 obj <<
-/D [1657 0 R /XYZ 85.0394 518.5228 null]
+2086 0 obj <<
+/D [2081 0 R /XYZ 85.0394 518.5228 null]
>> endobj
-606 0 obj <<
-/D [1657 0 R /XYZ 85.0394 460.6968 null]
+734 0 obj <<
+/D [2081 0 R /XYZ 85.0394 460.6968 null]
>> endobj
-1663 0 obj <<
-/D [1657 0 R /XYZ 85.0394 425.0333 null]
+2087 0 obj <<
+/D [2081 0 R /XYZ 85.0394 425.0333 null]
>> endobj
-610 0 obj <<
-/D [1657 0 R /XYZ 85.0394 260.2468 null]
+738 0 obj <<
+/D [2081 0 R /XYZ 85.0394 260.2468 null]
>> endobj
-1664 0 obj <<
-/D [1657 0 R /XYZ 85.0394 224.698 null]
+2088 0 obj <<
+/D [2081 0 R /XYZ 85.0394 224.698 null]
>> endobj
-1656 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R /F11 1397 0 R /F41 939 0 R >>
+2080 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R /F11 1442 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1669 0 obj <<
+2093 0 obj <<
/Length 69
/Filter /FlateDecode
>>
stream
xÚ3T0
endobj
-1668 0 obj <<
+2092 0 obj <<
/Type /Page
-/Contents 1669 0 R
-/Resources 1667 0 R
+/Contents 2093 0 R
+/Resources 2091 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1651 0 R
+/Parent 2071 0 R
>> endobj
-1670 0 obj <<
-/D [1668 0 R /XYZ 56.6929 794.5015 null]
+2094 0 obj <<
+/D [2092 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1667 0 obj <<
+2091 0 obj <<
/ProcSet [ /PDF ]
>> endobj
-1673 0 obj <<
-/Length 2543
+2097 0 obj <<
+/Length 2544
/Filter /FlateDecode
>>
stream
-xÚuYYsÛ8~ϯð[誑ÂûØ7[ÎádìrYÎNÕnö"! k’`ÒŠæ×O7ºyØéTJ@£hôñuƒö.\øç]¤ÑÚ ²ð"ÉÂuäzÑE^½s/°öùÇ<a¬£0`²°ºŠ‚t¥~r±šorýôîÃ'ß»ðÝuûÑÅÓ~<+N’µ¥OÅ«¦‘u¡~]®üÈu®.ÿ÷ô•ÄÂu’&Š¹pD²ã$žKäÒŒÌ^¸ÂØgæ8Z‡A’óÚ»\y® [çϵ>•²8T²îf²Þ:‹¢A6Ö^yƒì$Mú]·JîiøE™N·gšh&vGIƒ›û- D]°èíý ê_dë,öc>Ӈ˹!ë[vGÝŽ d¼ ~ø~gx©óÃuý\‰)´¶»ôyPu­êQ¬6sñ] UÓø^TLÝžM'+Éó¾mñ
-\Ó±8 ØãràÔòD3h Ä“0D,¤É[µ³:Ýê dÐ9 QÔ€EÒÔ'{)Áúrø®óɪ¢«q—µÑ$”ÄêY_ÝÔ'ÿ=>\f¾sUË"' Á_‘k/ƒ“†®
-¦6pkK­é·ç÷'‘s[w²…-@Ø£åÌ­ßp,XBšÎÞ'h7ü•¿Ù*Œpv
-÷Ãa…|‘¥nl Ø-H±ÈZyá6µ¨€÷ƒ(
-RÜŠ1ÏuL~”6`l ¿‚~ZѨ¢<ÓCƒÚ̓
-’ r”OœBç=Á 1j"«¢ºÑpQɧUäzý"GöÄÙ G,ØÝfS6ä ÐBdz˜€z²Ó„Q™DÏ B0q
-ã”U#7Cã@Q²€.ÿ¾ô
-ÝD‘øñðñ^=:\è±æí
-®o¬ƒñ+ñ'E\2}8Ç’;i %Ò‡ï&ª°Wõ\~jÀaÛÍ{³˜¢GË!zeoA_^†NmÞxš^Xð”Ð;’ù‚Ïr{z8Ø'"Hóȃ…×UØNÑô
+xÚuY[sÛ¸~ï¯È[•™µ««e·Äé%í&“‰Ó³3çô<ÐmóDUQŠëýõ  ¤dµÓé˜Äå¨>ü .ÖÉÒ²ø"ÍâeâÉE^½ó/°öù]À<q-“8Š`2³ºH¢õ2Y‡éÅbºÉõÓ»ŸÂà"ô—«U˜\<퇳Viº “õÅSñ_ïªid]¨_—‹0ñ½«Ëÿ=}%±x™®Ó
+#œ‚Ľ;¬/²Ô »)–X+Ïܦð~EAŠC1øžÉÒŒ­‘áWÐO+U”gš€B`hC»  ŸUM”Ä
+FXЭ‚dƒ\#åS¯ÐyOpBŒšÈª†¨n4\Tòi¹^¿È=õvÂÀ3v·Ù”¹<ƒZˆLPO–`š8I9³€øQ &ŽÀ6 CÆg”ñf±Ñu.{4ÐÈ,0ø$rUªNIƒb¼Ã°:Ý>±‹átûÕé°Ûª)å$
+£ÄÁ¶‘¹µ/!. N…Ùzê°Wâ.pl „ÓÁº°â…!R߸“OG•y—²œ ™®Õ+Å cøˆP¾·ëU é6É–+?£ÂôD˜•ZŒnMG“Ñu Æ »Æ51ŒŒl_àêiìYpɼÔ$LK­¹¿JH\ç d`
+¼
+–a“p¯Gkଯ ëÃá5³îǪÿêÄ- ÜȽ¬Í|µ/^ÄwxÒH‚
+D¤<ÐÎÿ—yÇ‘sU@E…ÎqÌ*Š‘×8P”Ì Ë¿/@f4áRÊ}^º¦ÖÒRº#›Úv°/×ˈÖFtÅŒ‚þ[åSr Òéú@Øèªé)ŽL½"Ÿûæ¢@ù<ñpJµÙ>~æÜpËLtGY­Fgá±[A —(-̃ÅÙ¶Ä ˜Þ°)Ëx™AaíF¼¨‚ÕáPâ¥V)§8·º>@ÌÔ4ûôÜÄP‰BÍÞ(dv P&máªëæßFD3zœ`·“¢ÂEàÛ=ÃBj{ †rh®ÔÐq½ ‘®³«zß&Å(uùJ¸8…B×ò5ø?Š²9Òp#ªf'Ë’•ú&_æ ùM_—¢±J6iðU£ª#E}ïãÏ^5X*‰eÃÏÖJ©>KF\¢P¯SSŒo&Œ>Ï! ·LÝ–è@±¸ˆ¤ægH@Ä9³ZI( Ž:ž()6Sq
+UŸiQc¢õFêƆEiX*×5ÔÏ]OÕ-ãÖXXE p³Í‚¥¢o¹‡šMÔºõÁùˆ4òs®øbðج–×
endobj
-1672 0 obj <<
+2096 0 obj <<
/Type /Page
-/Contents 1673 0 R
-/Resources 1671 0 R
+/Contents 2097 0 R
+/Resources 2095 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1651 0 R
+/Parent 2071 0 R
>> endobj
-1674 0 obj <<
-/D [1672 0 R /XYZ 85.0394 794.5015 null]
+2098 0 obj <<
+/D [2096 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-614 0 obj <<
-/D [1672 0 R /XYZ 85.0394 769.5949 null]
+742 0 obj <<
+/D [2096 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1675 0 obj <<
-/D [1672 0 R /XYZ 85.0394 573.5449 null]
+2099 0 obj <<
+/D [2096 0 R /XYZ 85.0394 573.5449 null]
>> endobj
-618 0 obj <<
-/D [1672 0 R /XYZ 85.0394 573.5449 null]
+746 0 obj <<
+/D [2096 0 R /XYZ 85.0394 573.5449 null]
>> endobj
-1676 0 obj <<
-/D [1672 0 R /XYZ 85.0394 539.0037 null]
+2100 0 obj <<
+/D [2096 0 R /XYZ 85.0394 539.0037 null]
>> endobj
-622 0 obj <<
-/D [1672 0 R /XYZ 85.0394 539.0037 null]
+750 0 obj <<
+/D [2096 0 R /XYZ 85.0394 539.0037 null]
>> endobj
-1677 0 obj <<
-/D [1672 0 R /XYZ 85.0394 510.2426 null]
+2101 0 obj <<
+/D [2096 0 R /XYZ 85.0394 510.2426 null]
>> endobj
-1671 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R >>
+2095 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1680 0 obj <<
-/Length 2810
+2104 0 obj <<
+/Length 2811
/Filter /FlateDecode
>>
stream
-xÚ­koã¸ñ{~…¿ÕbEõô²Ù$Í]/—&.Zàö€Òm«+K>QJ6÷ë;Ã!õ°•½ÚäƒÉáp8/΃b3þÙ,0ñ’Y”øNà²`–îÏÜÙÖîΘÁYX¤Åëãêìò–G³ÄIB/œ­6Z±ãÆ1›­²_æWŽçœw~wópótõ·ó…¸óOÏ4xº¹½yºy¸¾¡éýÃíÏO?]Gþ|uÿóÃù"Ž’`~õøxóðéþ_„s…]×B¯ožÏ]ýpv³ê8JÅ\Žìþvö˯î,á~8sžÄÁì&®Ã’Ä›íÏü€;Ϲ…gÏgïVõÖI-1×ñxèM¨Éó¦Ô$NÈ=®ÕôñþáHçÅóY«¼*q’Ì‚½
-EƒúœÅsYH¡dFyI+ÏòÐÈýZÖ4õ\×%QfÊ Að½øOU©¾Öy#i­ÚÐB)E]¼™mEaªƒLCÌb6;³µ-3©é-Ð( ™cNž³xËË-YÑH #¡ñÓŸ6-1ãØÝžë¸Q4Ôì0:R4óáÇ·‚Â<’•4>aòÙu½4IÞhK&„”ŠFfàVœ¹ó‡Êìϲ¼SDAóL¾È¢:ìeÙ@+©T¥=¥<–­·¦ftB%Úï¡ Θâþüµª¿Ð’f~÷"“´v¨”Ê×…$xSeâ†ë7B +@@»U­vùV´qΫµF`’Võ¡ª*I] (2F8"9!u“[WVÆŠ†qIm«MU7ª3žþ-Û=ùVÕš•¼Ìò—<kE¡´žàª±óîÃ=„»§ú‘ãã­4Áè|ÁàjÌïdiä#¹‘µ,ScÎû˜ØkùzâVMœs'öXÜE:fÈß?¾„Õ £4 v÷
-þà—šÃØ€f†à™0Š
-†Li2Za†TüÖ™/ÖyC+yîŸ3íïàLÝhOܼld½iGHÛ ”Ô‡‘Ö8R¡Fó×]žîÌPöçkD²LÖ¦2³çÐÚ‰ Pf ­G 8"ýÂ9y‘7BG!˜«T‚Üf÷ÈJ)š7h œàµM¢ùj×3b8iv4³Ó·ƒ(2‘чú]’ex2° ?Ë 2ÿ2O…j&LÈ™ñ¯E‚Šé² ™Å VAå,xÃF6¾&«¹Ïæ
-ÄD=pßíMòa‚ËØsxÌ=søUùö“ðü“<äšI<mÌ$B´ëàá–4P}#¦Ô
-÷ ×&
- ¶™ìLtÑâÏ©®ÄAÝ€}ºÚòaÁpÙ"âÖ‘ôª» è&~¯ ¡”)üaª »OÕ^XjO]4ƒ “ëûOOE. húÃ|[JúóÇÕÓ”$¤Qx²hº ÀDXækвN‰NÉØ/í
-¹·ÚÖ5 ”FE³Ã¼`Pó«è·c'ƒv51y~+PqgjÍäF@9I“Þ@H{C¿¥„«®Dýv΀¬Å‚x~5Š ?ÈS[ŸŒ[¹QµÏ·;SRUeº×"ÿ"—]»8(GBè9·µ¯çºl™­ã¥¿ÉR¸.Œ¨ñ]ndÌ–Þš{ mÑÑ™(Ù’ã( }¾Öh'J©Q'´jÓèxš`V é»— ËÚâ9Ô BCD‡
-÷ Ín©äIM AïoV·&÷&¶µHâA–ù6ý禟Åó;Óh‘è?ß!}‡0P¥´øε·²Zc¬ÜÌܾý¾ä¦T½]=š;Ù,'²ý¦9,//___QN®rGfíe^.´•.±Õ×®ðaòð¸V¡íŸ¿ÂßÄñ¸“0×"9ÍWó°ÂÆyÈ YdÛâ?:ñ߉’ Ö-; Ÿ¾uÐò—™ýØ÷èv,†[ôwxð)å‘:†ªÀï;äµ—ÇüùÈGGü}‹é°Ny)ã”òô—©¼Ë˜h1ÆDWzíOíÑÐcû³…ŽïZœ\ÙDvÞkÛ–Ø'–n¼Åz1ÍÔÄ·Q(ûIãEäöIuè²½¢SÊõÈT¶ÀÏV,d#=œ¸Qè;¾Ï@¯Œ;. þØ‹ì†ÅpÇ©ÐÕuBÓ;‘l6NUo/ëMzâ;ž9‰Ë¹:ò딕‘"N©½ç;‘ùq4|à9NÏà¦1›$°iš›Œ`¾G¨÷¾pòÀÁÏ’r¸]bþŸ¿~ö€9ÇÞô‡M/ŠJSËJ„'œÛϤ§¬ÿ¤ð endstream
+xÚ­koã¸ñ{~…¿ÕbEõ̲»É6w½\š¸hÛ*K´­®,ùD9Ùܯï g¨‡­ì-Ð&L‡Ãyq”˜¹ð/fA脉—Ì¢ÄwW³lwæÎ6°öéL0ÎÂ"-†Xï—g—·2š%Nzál¹Њ7ŽÅl™ÿ2¿v<ç(¸óO7÷7×;_x;ÿxÿDƒÇ›Û›Ç›û74½»¿ýùñ§ëóÈŸ/ï~¾?_ÄQ̯nî?Þý‹p®‘ ëZ臛§ó_—?œÝ,;Ž‡R W"»¿ýò«;ËA¸Î\G&q0{‰ëˆ$ñf»3?NàKi!åÙÓÙß;‚ƒU³uRKÂu<zjò¼)5‰JO5½¿»ÿÒyñüY5º¨+œ$ó„`/©¦As.â¹*UªUNEE+OjߪÝJ54õ\×%„´Ê T0”à»ô?u3¤úÒ­¢µzM •J›ò•·•%Ô{•µLÌb¶[Þz¨reè-Ð( ™…Nž³|-ª Y‘%†Qjð³-ŸµbƱ»=×q£h¨#ØÁ:Ò4óáÇ·‚Â<’U4>aòÙu½¬
+dþU‘¥º0¡N$;<¼q*¦cÈ2d¬‚ÊYÈ(†b|M VK_Ì5ˆ‰z¾Û›äÝ—±çÈXz|øuõú“ðü“2”†I<mÌ$BŒëàá–4P}#¦ô;
+h»zxXÑGWø ŸøxûpdGS—é³çùŸ˜Œ3;¦`²ƒ€[sƒ›&²K¼C*Ç!@þ®Û(Nê'¨u|6çfÀéà&€S2Z÷ë„c€‹»ÞÐ1Þ<Ós l³ˆú°¢àYcè>§'„)ŽN°ÕEZME‡È ¡äå-W}×q‘t¼@Ú½”î¾ç;~ 7eh˜%¥ç¤×ŸŒô‹#ýU1¯Ô0Mˆ†ÊÒ‰Müñü°×ÈUº’3›‚˜<¸wOçJ¾ sêOLŽc®6ÛòÕ¤:³êö (/rÍG×= …8£?¡prmRXÖ”aÄwâ ´QCɵµÇ¥«°¥«7¾µhÒjƒ—VBF_Z¬Î‘`|΢‰(%[
+KÌÄ­tg¹Ñä äh&ÆZéI¥”»
+À¡ìLLÑâÏ©®ÄA Ý]
+ûLµ³òa¹lIëÈ
+»õ.µÔ»h &î>>b¹`:&Ðô‡ù¶”ôçËÇ)IH£5xrÚv €‰°*V e“ œ’1/ã
+ItdöW9€°;˜
+#";"2ôoÆG‰Fõ
+EЙ­OƭܨŒÚ›-—e]s÷Z_ÔU×.Ê‘zE)míë¹®¸ÊWñ•¿ÉUêº0¢Æ÷j­bqå­¤7‘Љ’-9ŽÂÐákq¢ŒuB«×­‰§ fe°¹{ º ©-žC
+â”mÖöÑëC½Ã
+cåàföí÷¹àRõvùÀw²½šÈöëvuyùòò‚*p
+]8*?\ÕÂXé[}ãú&?kÚþù+üM\O:‰p-’Ó~å‡1ÎCN("ÛÿùøÓ‰øN”±iÙE˜øô­ƒ–¿ÌìèÇþ»G·c1Üb¾{øÃO)Ô1T~ß!¯½<æÏGþã8:âïè[L‡uÊÓH§Ô§¿Lå]ÀĈ90&ºÒK÷ðxj7ˆ†žÄ˜-t|×âÚv ª{ô^Ù¶Ä>±t‹à-Ö‹i¦'¾}¤¥¶Ÿ4žÓÂ>©]¶£÷OtJµùï‘ÊøÙJ„b¤‡7
+}Ç÷èUHÇÁ{‘Ý°î8u¢º¦Nh{'RíÚ©›Íe³ÎN|Çs#'qå1WG¾Óa²2RÄ)µ·|'r"?Ž†<ÇéÜ4†`“6MKÎü=B¿õ…S~–œÃíóÿüõ³ÿ
endobj
-1679 0 obj <<
+2103 0 obj <<
/Type /Page
-/Contents 1680 0 R
-/Resources 1678 0 R
+/Contents 2104 0 R
+/Resources 2102 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1651 0 R
-/Annots [ 1684 0 R 1685 0 R ]
+/Parent 2112 0 R
+/Annots [ 2108 0 R 2109 0 R ]
>> endobj
-1684 0 obj <<
+2108 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[0 1 1]
/Rect [253.7995 149.3637 417.685 161.4234]
/Subtype/Link/A<</Type/Action/S/URI/URI(ftp://www.isi.edu/in-notes/)>>
>> endobj
-1685 0 obj <<
+2109 0 obj <<
/Type /Annot
/Border[0 0 0]/H/I/C[0 1 1]
/Rect [63.4454 110.455 208.8999 120.6168]
/Subtype/Link/A<</Type/Action/S/URI/URI(http://www.ietf.org/rfc/)>>
>> endobj
-1681 0 obj <<
-/D [1679 0 R /XYZ 56.6929 794.5015 null]
+2105 0 obj <<
+/D [2103 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-626 0 obj <<
-/D [1679 0 R /XYZ 56.6929 662.0717 null]
+754 0 obj <<
+/D [2103 0 R /XYZ 56.6929 662.0717 null]
>> endobj
-1682 0 obj <<
-/D [1679 0 R /XYZ 56.6929 624.1661 null]
+2106 0 obj <<
+/D [2103 0 R /XYZ 56.6929 624.1661 null]
>> endobj
-630 0 obj <<
-/D [1679 0 R /XYZ 56.6929 624.1661 null]
+758 0 obj <<
+/D [2103 0 R /XYZ 56.6929 624.1661 null]
>> endobj
-1140 0 obj <<
-/D [1679 0 R /XYZ 56.6929 593.0972 null]
+1515 0 obj <<
+/D [2103 0 R /XYZ 56.6929 593.0972 null]
>> endobj
-634 0 obj <<
-/D [1679 0 R /XYZ 56.6929 294.2701 null]
+762 0 obj <<
+/D [2103 0 R /XYZ 56.6929 294.2701 null]
>> endobj
-1683 0 obj <<
-/D [1679 0 R /XYZ 56.6929 255.4568 null]
+2107 0 obj <<
+/D [2103 0 R /XYZ 56.6929 255.4568 null]
>> endobj
-638 0 obj <<
-/D [1679 0 R /XYZ 56.6929 255.4568 null]
+766 0 obj <<
+/D [2103 0 R /XYZ 56.6929 255.4568 null]
>> endobj
-967 0 obj <<
-/D [1679 0 R /XYZ 56.6929 226.1045 null]
+1241 0 obj <<
+/D [2103 0 R /XYZ 56.6929 226.1045 null]
>> endobj
-1686 0 obj <<
-/D [1679 0 R /XYZ 56.6929 53.5688 null]
+2110 0 obj <<
+/D [2103 0 R /XYZ 56.6929 53.5688 null]
>> endobj
-1687 0 obj <<
-/D [1679 0 R /XYZ 56.6929 53.5688 null]
+2111 0 obj <<
+/D [2103 0 R /XYZ 56.6929 53.5688 null]
>> endobj
-1678 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F39 899 0 R /F53 1029 0 R /F11 1397 0 R /F41 939 0 R >>
+2102 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F39 1151 0 R /F53 1303 0 R /F11 1442 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1690 0 obj <<
-/Length 2825
+2115 0 obj <<
+/Length 2826
/Filter /FlateDecode
>>
stream
@@ -8407,191 +10225,192 @@ Zî–ÁÅ“ž„N(ËEHq¤;#UO«E;õ4:É$£ÇgöHm)7™FJ“>2½Ð-™'ØÃdvÀ›
À´jP'Ïå±îí0ô¾ˆpØ!f
ã3­¤%ä¶B-dU™Ï}¸­ ö‡MÐFžŒ¯ -3wÊ,Ÿw¢^ [ÖŒ*…ÅÈ´<Øû©ÍØ/cŒ ­±ïÖÙN­>Ë^vå›~¾Ñó
åçú«d>C¶K¡`Œidå7ÆÁâU<2³û»I_å Cæœ:& ôÚäLcjKy¨ÖRמZ/´EvÛÁ¶ >-÷{¹ëŠõfëÀ·@09—¬–‡JÊH…‰Åq³N¬é„`ü]þmøèœÆ(æØ>F¢aóù XäýqŸêSW±ïÚôy°Úc +ïÔàT >d mâŒ^·Ãs§÷œ¥ÅùÆgîóÝÎœø~ŸIð‘0Šüa ¹ B µT$žƒnk}àak°‘Ù!×G%ǶÚ4[Y¯†ªLÆ,<=5G±Žö\×~ïGI ¶àÏÔÿ–[áZ¨Íø¾Ï¾|¸­ÂûÀÃ
-·‘÷AŸWÏÙ6}ÍE5#P}m kkôÓÒ9áBŸÔ6"²€ÑÛÇ×H^MÖêD2ì #FEÐ|X|Ö~ѼJyÈ«m^§DRãKá%Jæ./öY®P¯ÙÙC²7Ü…¤jñ î€j“Ûÿò—¾ÖÎaŒh’8Óh¡„ðX¿”ø<ù$øôÕÿ Æ¡bxendstream
+·‘÷AŸWÏÙ6}ÍE5#P}m kkôÓÒ9áBŸÔ6"²€ÑÛÇ×H^MÖêD2ì #FEÐ|X|Ö~ѼJyÈ«m^§DRãKá%Jæ./öY®P¯ÙÙC²7Ü…¤jñ î€j“Ûÿò—¾ÖÎaŒh’8Ó(4Ÿ”r¬_Jü
+LN>D6ߟ¾û#ïbendstream
endobj
-1689 0 obj <<
+2114 0 obj <<
/Type /Page
-/Contents 1690 0 R
-/Resources 1688 0 R
+/Contents 2115 0 R
+/Resources 2113 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1747 0 R
+/Parent 2112 0 R
>> endobj
-1691 0 obj <<
-/D [1689 0 R /XYZ 85.0394 794.5015 null]
+2116 0 obj <<
+/D [2114 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1692 0 obj <<
-/D [1689 0 R /XYZ 85.0394 752.3015 null]
+2117 0 obj <<
+/D [2114 0 R /XYZ 85.0394 752.3015 null]
>> endobj
-1693 0 obj <<
-/D [1689 0 R /XYZ 85.0394 752.3015 null]
+2118 0 obj <<
+/D [2114 0 R /XYZ 85.0394 752.3015 null]
>> endobj
-1694 0 obj <<
-/D [1689 0 R /XYZ 85.0394 752.3015 null]
+2119 0 obj <<
+/D [2114 0 R /XYZ 85.0394 752.3015 null]
>> endobj
-1695 0 obj <<
-/D [1689 0 R /XYZ 85.0394 746.3107 null]
+2120 0 obj <<
+/D [2114 0 R /XYZ 85.0394 746.3107 null]
>> endobj
-1696 0 obj <<
-/D [1689 0 R /XYZ 85.0394 731.5461 null]
+2121 0 obj <<
+/D [2114 0 R /XYZ 85.0394 731.5461 null]
>> endobj
-1697 0 obj <<
-/D [1689 0 R /XYZ 85.0394 728.1497 null]
+2122 0 obj <<
+/D [2114 0 R /XYZ 85.0394 728.1497 null]
>> endobj
-1698 0 obj <<
-/D [1689 0 R /XYZ 85.0394 713.3851 null]
+2123 0 obj <<
+/D [2114 0 R /XYZ 85.0394 713.3851 null]
>> endobj
-1699 0 obj <<
-/D [1689 0 R /XYZ 85.0394 709.9887 null]
+2124 0 obj <<
+/D [2114 0 R /XYZ 85.0394 709.9887 null]
>> endobj
-1700 0 obj <<
-/D [1689 0 R /XYZ 85.0394 651.9592 null]
+2125 0 obj <<
+/D [2114 0 R /XYZ 85.0394 651.9592 null]
>> endobj
-1083 0 obj <<
-/D [1689 0 R /XYZ 85.0394 651.9592 null]
+1372 0 obj <<
+/D [2114 0 R /XYZ 85.0394 651.9592 null]
>> endobj
-1701 0 obj <<
-/D [1689 0 R /XYZ 85.0394 651.9592 null]
+2126 0 obj <<
+/D [2114 0 R /XYZ 85.0394 651.9592 null]
>> endobj
-1702 0 obj <<
-/D [1689 0 R /XYZ 85.0394 648.8377 null]
+2127 0 obj <<
+/D [2114 0 R /XYZ 85.0394 648.8377 null]
>> endobj
-1703 0 obj <<
-/D [1689 0 R /XYZ 85.0394 634.0731 null]
+2128 0 obj <<
+/D [2114 0 R /XYZ 85.0394 634.0731 null]
>> endobj
-1704 0 obj <<
-/D [1689 0 R /XYZ 85.0394 630.6767 null]
+2129 0 obj <<
+/D [2114 0 R /XYZ 85.0394 630.6767 null]
>> endobj
-1705 0 obj <<
-/D [1689 0 R /XYZ 85.0394 615.9121 null]
+2130 0 obj <<
+/D [2114 0 R /XYZ 85.0394 615.9121 null]
>> endobj
-1706 0 obj <<
-/D [1689 0 R /XYZ 85.0394 612.5156 null]
+2131 0 obj <<
+/D [2114 0 R /XYZ 85.0394 612.5156 null]
>> endobj
-1707 0 obj <<
-/D [1689 0 R /XYZ 85.0394 585.7959 null]
+2132 0 obj <<
+/D [2114 0 R /XYZ 85.0394 585.7959 null]
>> endobj
-1708 0 obj <<
-/D [1689 0 R /XYZ 85.0394 582.3994 null]
+2133 0 obj <<
+/D [2114 0 R /XYZ 85.0394 582.3994 null]
>> endobj
-1709 0 obj <<
-/D [1689 0 R /XYZ 85.0394 567.6349 null]
+2134 0 obj <<
+/D [2114 0 R /XYZ 85.0394 567.6349 null]
>> endobj
-1710 0 obj <<
-/D [1689 0 R /XYZ 85.0394 564.2384 null]
+2135 0 obj <<
+/D [2114 0 R /XYZ 85.0394 564.2384 null]
>> endobj
-1711 0 obj <<
-/D [1689 0 R /XYZ 85.0394 549.5337 null]
+2136 0 obj <<
+/D [2114 0 R /XYZ 85.0394 549.5337 null]
>> endobj
-1712 0 obj <<
-/D [1689 0 R /XYZ 85.0394 546.0774 null]
+2137 0 obj <<
+/D [2114 0 R /XYZ 85.0394 546.0774 null]
>> endobj
-1713 0 obj <<
-/D [1689 0 R /XYZ 85.0394 531.3128 null]
+2138 0 obj <<
+/D [2114 0 R /XYZ 85.0394 531.3128 null]
>> endobj
-1714 0 obj <<
-/D [1689 0 R /XYZ 85.0394 527.9163 null]
+2139 0 obj <<
+/D [2114 0 R /XYZ 85.0394 527.9163 null]
>> endobj
-1715 0 obj <<
-/D [1689 0 R /XYZ 85.0394 513.1518 null]
+2140 0 obj <<
+/D [2114 0 R /XYZ 85.0394 513.1518 null]
>> endobj
-1716 0 obj <<
-/D [1689 0 R /XYZ 85.0394 509.7553 null]
+2141 0 obj <<
+/D [2114 0 R /XYZ 85.0394 509.7553 null]
>> endobj
-1717 0 obj <<
-/D [1689 0 R /XYZ 85.0394 483.0356 null]
+2142 0 obj <<
+/D [2114 0 R /XYZ 85.0394 483.0356 null]
>> endobj
-1718 0 obj <<
-/D [1689 0 R /XYZ 85.0394 479.6391 null]
+2143 0 obj <<
+/D [2114 0 R /XYZ 85.0394 479.6391 null]
>> endobj
-1719 0 obj <<
-/D [1689 0 R /XYZ 85.0394 464.8745 null]
+2144 0 obj <<
+/D [2114 0 R /XYZ 85.0394 464.8745 null]
>> endobj
-1720 0 obj <<
-/D [1689 0 R /XYZ 85.0394 461.4781 null]
+2145 0 obj <<
+/D [2114 0 R /XYZ 85.0394 461.4781 null]
>> endobj
-1721 0 obj <<
-/D [1689 0 R /XYZ 85.0394 446.7135 null]
+2146 0 obj <<
+/D [2114 0 R /XYZ 85.0394 446.7135 null]
>> endobj
-1722 0 obj <<
-/D [1689 0 R /XYZ 85.0394 443.3171 null]
+2147 0 obj <<
+/D [2114 0 R /XYZ 85.0394 443.3171 null]
>> endobj
-1723 0 obj <<
-/D [1689 0 R /XYZ 85.0394 428.5525 null]
+2148 0 obj <<
+/D [2114 0 R /XYZ 85.0394 428.5525 null]
>> endobj
-1724 0 obj <<
-/D [1689 0 R /XYZ 85.0394 425.156 null]
+2149 0 obj <<
+/D [2114 0 R /XYZ 85.0394 425.156 null]
>> endobj
-1725 0 obj <<
-/D [1689 0 R /XYZ 85.0394 355.0758 null]
+2150 0 obj <<
+/D [2114 0 R /XYZ 85.0394 355.0758 null]
>> endobj
-1726 0 obj <<
-/D [1689 0 R /XYZ 85.0394 355.0758 null]
+2151 0 obj <<
+/D [2114 0 R /XYZ 85.0394 355.0758 null]
>> endobj
-1727 0 obj <<
-/D [1689 0 R /XYZ 85.0394 355.0758 null]
+2152 0 obj <<
+/D [2114 0 R /XYZ 85.0394 355.0758 null]
>> endobj
-1728 0 obj <<
-/D [1689 0 R /XYZ 85.0394 352.0499 null]
+2153 0 obj <<
+/D [2114 0 R /XYZ 85.0394 352.0499 null]
>> endobj
-1729 0 obj <<
-/D [1689 0 R /XYZ 85.0394 337.3452 null]
+2154 0 obj <<
+/D [2114 0 R /XYZ 85.0394 337.3452 null]
>> endobj
-1730 0 obj <<
-/D [1689 0 R /XYZ 85.0394 333.8889 null]
+2155 0 obj <<
+/D [2114 0 R /XYZ 85.0394 333.8889 null]
>> endobj
-1731 0 obj <<
-/D [1689 0 R /XYZ 85.0394 309.8192 null]
+2156 0 obj <<
+/D [2114 0 R /XYZ 85.0394 309.8192 null]
>> endobj
-1732 0 obj <<
-/D [1689 0 R /XYZ 85.0394 303.7727 null]
+2157 0 obj <<
+/D [2114 0 R /XYZ 85.0394 303.7727 null]
>> endobj
-1733 0 obj <<
-/D [1689 0 R /XYZ 85.0394 278.3282 null]
+2158 0 obj <<
+/D [2114 0 R /XYZ 85.0394 278.3282 null]
>> endobj
-1734 0 obj <<
-/D [1689 0 R /XYZ 85.0394 273.6565 null]
+2159 0 obj <<
+/D [2114 0 R /XYZ 85.0394 273.6565 null]
>> endobj
-1735 0 obj <<
-/D [1689 0 R /XYZ 85.0394 246.9367 null]
+2160 0 obj <<
+/D [2114 0 R /XYZ 85.0394 246.9367 null]
>> endobj
-1736 0 obj <<
-/D [1689 0 R /XYZ 85.0394 243.5403 null]
+2161 0 obj <<
+/D [2114 0 R /XYZ 85.0394 243.5403 null]
>> endobj
-1737 0 obj <<
-/D [1689 0 R /XYZ 85.0394 173.5556 null]
+2162 0 obj <<
+/D [2114 0 R /XYZ 85.0394 173.5556 null]
>> endobj
-1738 0 obj <<
-/D [1689 0 R /XYZ 85.0394 173.5556 null]
+2163 0 obj <<
+/D [2114 0 R /XYZ 85.0394 173.5556 null]
>> endobj
-1739 0 obj <<
-/D [1689 0 R /XYZ 85.0394 173.5556 null]
+2164 0 obj <<
+/D [2114 0 R /XYZ 85.0394 173.5556 null]
>> endobj
-1740 0 obj <<
-/D [1689 0 R /XYZ 85.0394 170.4341 null]
+2165 0 obj <<
+/D [2114 0 R /XYZ 85.0394 170.4341 null]
>> endobj
-1741 0 obj <<
-/D [1689 0 R /XYZ 85.0394 144.9896 null]
+2166 0 obj <<
+/D [2114 0 R /XYZ 85.0394 144.9896 null]
>> endobj
-1742 0 obj <<
-/D [1689 0 R /XYZ 85.0394 140.3179 null]
+2167 0 obj <<
+/D [2114 0 R /XYZ 85.0394 140.3179 null]
>> endobj
-1743 0 obj <<
-/D [1689 0 R /XYZ 85.0394 113.5982 null]
+2168 0 obj <<
+/D [2114 0 R /XYZ 85.0394 113.5982 null]
>> endobj
-1744 0 obj <<
-/D [1689 0 R /XYZ 85.0394 110.2017 null]
+2169 0 obj <<
+/D [2114 0 R /XYZ 85.0394 110.2017 null]
>> endobj
-1745 0 obj <<
-/D [1689 0 R /XYZ 85.0394 95.4372 null]
+2170 0 obj <<
+/D [2114 0 R /XYZ 85.0394 95.4372 null]
>> endobj
-1746 0 obj <<
-/D [1689 0 R /XYZ 85.0394 92.0407 null]
+2171 0 obj <<
+/D [2114 0 R /XYZ 85.0394 92.0407 null]
>> endobj
-1688 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F39 899 0 R >>
+2113 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1750 0 obj <<
+2174 0 obj <<
/Length 2889
/Filter /FlateDecode
>>
@@ -8609,484 +10428,742 @@ id„ý4¦Õ0m¥Ñ¡¥
¾šÈÖϺ`]Ë4OòJv‰šU N«µƒiqLË2í«ÿ
ŒÛÏiueK×±ôƒƒæÏBŽãŒÄaÓj˜¹¶jÞLpð0s«tÃüD»—yK[ÏÇ"ß»ø+Vý,/MÓ­ ~‚é;üd'DÄñCK˜ýl~h½u Äë!ÍTò'/Ø‹PˆÇª¦•…’²j(ÙöK«´A©«ÝOÉÔ^³ïÇTìq{–«íPo‘Í#/þéºÐ湚»×,Ý…ô¦¬+#wŸ[<¹ÂùÅ!Ù±r¹
…º#õ:ÓÊEYi(^ds›´¥«ÝÅÔOï7ÕḭD˜d™7žmôl‘‡ü€ºíÉÿ ã
-.Wçñ|¾FñZD—øw¦~TЙìkUUIw9SAèJ6î$Í«z꾅щlÍ£ü~dÃÏu1dwGÛ›VdÊJ# ‰å4i•6uµû‘™ÚËøBm¼DÁ¶Ï9„§L½Î´ç1NîC݇MyúýȺ‡ лéz~ÐÛ–±DÇÊŽ§^I§‚ö;•“~f8ö–…a4LK5eb©TÛtV]á^T¦°Žqn¨bœñ7ƒ´ºsnÔ©b‚å2^Åâêr…tÇÉÐû¼¤é“ÖÓ?±N©áv3¥†f#¥æÒè¢.lå¹x òüßµ·eYšìÕ‹Z¤uö×ÎÚyÍnð i©³xˆ¿OÛ3ùŽ>“þϯíUñ
+.Wçñ|¾FñZD—øw¦~TЙìkUUIw9SAèJ6î$Í«z꾅щlÍ£ü~dÃÏu1dwGÛ›VdÊJ# ‰å4i•6uµû‘™ÚËøBm¼DÁ¶Ï9„§L½Î´ç1NîC݇MyúýȺ‡ лéz~ÐÛ–±DÇÊŽ§^I§‚ö;•“~f8ö–…a4LK5eb©TÛtV]á^T¦°Žqn¨bœñ7ƒ´ºsnÔ©b‚å2^Åâêr…tÇÉÐû¼¤é“ÖÓ?±N©áv3¥†f#¥æÒè¢.lå¹x òüßµ·eYšìÕ‹Z¤uö×ÎÚyÍnð i©³xˆ¿OÛ3ùŽ>“þϯíUñ
endobj
-1749 0 obj <<
+2173 0 obj <<
/Type /Page
-/Contents 1750 0 R
-/Resources 1748 0 R
+/Contents 2174 0 R
+/Resources 2172 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1747 0 R
+/Parent 2112 0 R
>> endobj
-1751 0 obj <<
-/D [1749 0 R /XYZ 56.6929 794.5015 null]
+2175 0 obj <<
+/D [2173 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1752 0 obj <<
-/D [1749 0 R /XYZ 56.6929 748.5056 null]
+2176 0 obj <<
+/D [2173 0 R /XYZ 56.6929 748.5056 null]
>> endobj
-1753 0 obj <<
-/D [1749 0 R /XYZ 56.6929 748.5056 null]
+2177 0 obj <<
+/D [2173 0 R /XYZ 56.6929 748.5056 null]
>> endobj
-1754 0 obj <<
-/D [1749 0 R /XYZ 56.6929 748.5056 null]
+2178 0 obj <<
+/D [2173 0 R /XYZ 56.6929 748.5056 null]
>> endobj
-1755 0 obj <<
-/D [1749 0 R /XYZ 56.6929 743.7078 null]
+2179 0 obj <<
+/D [2173 0 R /XYZ 56.6929 743.7078 null]
>> endobj
-1756 0 obj <<
-/D [1749 0 R /XYZ 56.6929 719.6381 null]
+2180 0 obj <<
+/D [2173 0 R /XYZ 56.6929 719.6381 null]
>> endobj
-1757 0 obj <<
-/D [1749 0 R /XYZ 56.6929 711.8197 null]
+2181 0 obj <<
+/D [2173 0 R /XYZ 56.6929 711.8197 null]
>> endobj
-1758 0 obj <<
-/D [1749 0 R /XYZ 56.6929 697.0552 null]
+2182 0 obj <<
+/D [2173 0 R /XYZ 56.6929 697.0552 null]
>> endobj
-1759 0 obj <<
-/D [1749 0 R /XYZ 56.6929 691.8868 null]
+2183 0 obj <<
+/D [2173 0 R /XYZ 56.6929 691.8868 null]
>> endobj
-1760 0 obj <<
-/D [1749 0 R /XYZ 56.6929 665.1671 null]
+2184 0 obj <<
+/D [2173 0 R /XYZ 56.6929 665.1671 null]
>> endobj
-1761 0 obj <<
-/D [1749 0 R /XYZ 56.6929 659.9987 null]
+2185 0 obj <<
+/D [2173 0 R /XYZ 56.6929 659.9987 null]
>> endobj
-1762 0 obj <<
-/D [1749 0 R /XYZ 56.6929 635.929 null]
+2186 0 obj <<
+/D [2173 0 R /XYZ 56.6929 635.929 null]
>> endobj
-1763 0 obj <<
-/D [1749 0 R /XYZ 56.6929 628.1106 null]
+2187 0 obj <<
+/D [2173 0 R /XYZ 56.6929 628.1106 null]
>> endobj
-1764 0 obj <<
-/D [1749 0 R /XYZ 56.6929 601.3909 null]
+2188 0 obj <<
+/D [2173 0 R /XYZ 56.6929 601.3909 null]
>> endobj
-1765 0 obj <<
-/D [1749 0 R /XYZ 56.6929 596.2225 null]
+2189 0 obj <<
+/D [2173 0 R /XYZ 56.6929 596.2225 null]
>> endobj
-1766 0 obj <<
-/D [1749 0 R /XYZ 56.6929 569.5028 null]
+2190 0 obj <<
+/D [2173 0 R /XYZ 56.6929 569.5028 null]
>> endobj
-1767 0 obj <<
-/D [1749 0 R /XYZ 56.6929 564.3344 null]
+2191 0 obj <<
+/D [2173 0 R /XYZ 56.6929 564.3344 null]
>> endobj
-1768 0 obj <<
-/D [1749 0 R /XYZ 56.6929 549.6297 null]
+2192 0 obj <<
+/D [2173 0 R /XYZ 56.6929 549.6297 null]
>> endobj
-1769 0 obj <<
-/D [1749 0 R /XYZ 56.6929 544.4015 null]
+2193 0 obj <<
+/D [2173 0 R /XYZ 56.6929 544.4015 null]
>> endobj
-1770 0 obj <<
-/D [1749 0 R /XYZ 56.6929 529.6968 null]
+2194 0 obj <<
+/D [2173 0 R /XYZ 56.6929 529.6968 null]
>> endobj
-1771 0 obj <<
-/D [1749 0 R /XYZ 56.6929 524.4686 null]
+2195 0 obj <<
+/D [2173 0 R /XYZ 56.6929 524.4686 null]
>> endobj
-1772 0 obj <<
-/D [1749 0 R /XYZ 56.6929 500.3989 null]
+2196 0 obj <<
+/D [2173 0 R /XYZ 56.6929 500.3989 null]
>> endobj
-1773 0 obj <<
-/D [1749 0 R /XYZ 56.6929 492.5805 null]
+2197 0 obj <<
+/D [2173 0 R /XYZ 56.6929 492.5805 null]
>> endobj
-1774 0 obj <<
-/D [1749 0 R /XYZ 56.6929 467.136 null]
+2198 0 obj <<
+/D [2173 0 R /XYZ 56.6929 467.136 null]
>> endobj
-1775 0 obj <<
-/D [1749 0 R /XYZ 56.6929 460.6924 null]
+2199 0 obj <<
+/D [2173 0 R /XYZ 56.6929 460.6924 null]
>> endobj
-1776 0 obj <<
-/D [1749 0 R /XYZ 56.6929 436.6227 null]
+2200 0 obj <<
+/D [2173 0 R /XYZ 56.6929 436.6227 null]
>> endobj
-1777 0 obj <<
-/D [1749 0 R /XYZ 56.6929 428.8043 null]
+2201 0 obj <<
+/D [2173 0 R /XYZ 56.6929 428.8043 null]
>> endobj
-1778 0 obj <<
-/D [1749 0 R /XYZ 56.6929 414.0996 null]
+2202 0 obj <<
+/D [2173 0 R /XYZ 56.6929 414.0996 null]
>> endobj
-1779 0 obj <<
-/D [1749 0 R /XYZ 56.6929 408.8714 null]
+2203 0 obj <<
+/D [2173 0 R /XYZ 56.6929 408.8714 null]
>> endobj
-1780 0 obj <<
-/D [1749 0 R /XYZ 56.6929 382.1516 null]
+2204 0 obj <<
+/D [2173 0 R /XYZ 56.6929 382.1516 null]
>> endobj
-1781 0 obj <<
-/D [1749 0 R /XYZ 56.6929 376.9833 null]
+2205 0 obj <<
+/D [2173 0 R /XYZ 56.6929 376.9833 null]
>> endobj
-1782 0 obj <<
-/D [1749 0 R /XYZ 56.6929 350.2636 null]
+2206 0 obj <<
+/D [2173 0 R /XYZ 56.6929 350.2636 null]
>> endobj
-1783 0 obj <<
-/D [1749 0 R /XYZ 56.6929 345.0952 null]
+2207 0 obj <<
+/D [2173 0 R /XYZ 56.6929 345.0952 null]
>> endobj
-1784 0 obj <<
-/D [1749 0 R /XYZ 56.6929 321.0255 null]
+2208 0 obj <<
+/D [2173 0 R /XYZ 56.6929 321.0255 null]
>> endobj
-1785 0 obj <<
-/D [1749 0 R /XYZ 56.6929 313.2071 null]
+2209 0 obj <<
+/D [2173 0 R /XYZ 56.6929 313.2071 null]
>> endobj
-1786 0 obj <<
-/D [1749 0 R /XYZ 56.6929 298.5024 null]
+2210 0 obj <<
+/D [2173 0 R /XYZ 56.6929 298.5024 null]
>> endobj
-1787 0 obj <<
-/D [1749 0 R /XYZ 56.6929 293.2742 null]
+2211 0 obj <<
+/D [2173 0 R /XYZ 56.6929 293.2742 null]
>> endobj
-1788 0 obj <<
-/D [1749 0 R /XYZ 56.6929 267.8297 null]
+2212 0 obj <<
+/D [2173 0 R /XYZ 56.6929 267.8297 null]
>> endobj
-1789 0 obj <<
-/D [1749 0 R /XYZ 56.6929 261.3861 null]
+2213 0 obj <<
+/D [2173 0 R /XYZ 56.6929 261.3861 null]
>> endobj
-1790 0 obj <<
-/D [1749 0 R /XYZ 56.6929 199.468 null]
+2214 0 obj <<
+/D [2173 0 R /XYZ 56.6929 199.468 null]
>> endobj
-1791 0 obj <<
-/D [1749 0 R /XYZ 56.6929 199.468 null]
+2215 0 obj <<
+/D [2173 0 R /XYZ 56.6929 199.468 null]
>> endobj
-1792 0 obj <<
-/D [1749 0 R /XYZ 56.6929 199.468 null]
+2216 0 obj <<
+/D [2173 0 R /XYZ 56.6929 199.468 null]
>> endobj
-1793 0 obj <<
-/D [1749 0 R /XYZ 56.6929 191.7053 null]
+2217 0 obj <<
+/D [2173 0 R /XYZ 56.6929 191.7053 null]
>> endobj
-1794 0 obj <<
-/D [1749 0 R /XYZ 56.6929 176.9408 null]
+2218 0 obj <<
+/D [2173 0 R /XYZ 56.6929 176.9408 null]
>> endobj
-1795 0 obj <<
-/D [1749 0 R /XYZ 56.6929 171.7724 null]
+2219 0 obj <<
+/D [2173 0 R /XYZ 56.6929 171.7724 null]
>> endobj
-1796 0 obj <<
-/D [1749 0 R /XYZ 56.6929 157.0677 null]
+2220 0 obj <<
+/D [2173 0 R /XYZ 56.6929 157.0677 null]
>> endobj
-1797 0 obj <<
-/D [1749 0 R /XYZ 56.6929 151.8395 null]
+2221 0 obj <<
+/D [2173 0 R /XYZ 56.6929 151.8395 null]
>> endobj
-1798 0 obj <<
-/D [1749 0 R /XYZ 56.6929 137.1348 null]
+2222 0 obj <<
+/D [2173 0 R /XYZ 56.6929 137.1348 null]
>> endobj
-1799 0 obj <<
-/D [1749 0 R /XYZ 56.6929 131.9066 null]
+2223 0 obj <<
+/D [2173 0 R /XYZ 56.6929 131.9066 null]
>> endobj
-1800 0 obj <<
-/D [1749 0 R /XYZ 56.6929 117.2018 null]
+2224 0 obj <<
+/D [2173 0 R /XYZ 56.6929 117.2018 null]
>> endobj
-1801 0 obj <<
-/D [1749 0 R /XYZ 56.6929 111.9736 null]
+2225 0 obj <<
+/D [2173 0 R /XYZ 56.6929 111.9736 null]
>> endobj
-1802 0 obj <<
-/D [1749 0 R /XYZ 56.6929 97.2091 null]
+2226 0 obj <<
+/D [2173 0 R /XYZ 56.6929 97.2091 null]
>> endobj
-1803 0 obj <<
-/D [1749 0 R /XYZ 56.6929 92.0407 null]
+2227 0 obj <<
+/D [2173 0 R /XYZ 56.6929 92.0407 null]
>> endobj
-1748 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F39 899 0 R >>
+2172 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1806 0 obj <<
-/Length 2545
+2230 0 obj <<
+/Length 2542
/Filter /FlateDecode
>>
stream
-xÚ¥ZKs㸾ûWè(U€ øÈM¶l&3¶#y²IÍî–`™ŠTHʳ³¿> âA" É¦|0 4ñýu7º›ÂxS‘$˜DIàQ„éd{¸B“=ÌÝ_a)3WBsSêúùê/w$š$^úáäùÕX+öPãÉóîÛtñôtû°\ýs6÷)š.¼Ùœ"¤Fon7³y&|‚ð©M¯WןW÷ëÅÓlj‡~E-–âfóõþþvó|+o×·‹åêáDðì·çOW·ÏúµÍ­aDø;ÿçêÛoh²ƒ~ºBIb:ù7ÈÃIâOW% Q#ùÕæêïzAc¶}tLU”ÄýhDW>ž`ì%”ú=eÑÄ ‰OZe-6b[GV¥MVµuWÃ[\ KˈðÇÈ2ýÛúîE~bbŠ¼8÷w€j™!*\v¨˜R/Ž5a—å!Í
-±ïtwÈŠ¬n`óeU‹±²ÓE{¿?e;æñwl ‡Ô â0†âë~â_<ñÿsÙÀš³(På;;¼°JÜá$Ž<«²8_ÚC݆”CáJJ«œ’È¡r´¡ô!¶Eí&øMy8”RñÚò–i“Š«»,gâê¦,~EÈߟbð¶ªf8žršF¨
-i’|œ8Hrà €-È_k©îòuà8‹<KkV˜z`Í÷²úwGQ¶eã…±ùA0~’|LYÞ(§Ó$­åô/ܪlÿÖXŠd/!˜û$ñ(…¼bø¼ˆ°ÂU6WH;Ìþ`Ì<4¹ÙYó%^Œð…LÁ”²³®¥4í±Oí´;¡;Þϰljï/`ça8}žaŒ}Þê%Œ@ù>š²—¿Îæ$𧫺>µV
-)ÒI8² ×à|
-ý¨ŸF,<•Âÿ”³Ÿå ØÅ%È<Aœˆê„YмbyÚ¨dµæœ!4ò/䦔Ì””®¦ t˜‘ Ú0£!¶ÅŒLð¯ukâ ‡*«suÈLn~
-örÚï9 # <‚ÍÄÃ^yÞ,¡´t’À®â
-¬¸ulH9”¬¤:-'WqBjb[ôl‚k}nNÇcY5u.ÓjðÃÊ¢oxaLýžg^ ©C•Õ[¥ôűÊr­qj׸{(Š/´zL)‡Æ•TW³Ž<Ö mh|ˆmѸ ¾še{ÕY¸NëìÌΞ*lóR¤³£­×´O£n$þ4=íßDR:fúö(Al8¾PN˜R"””&‚Ž*Ò m1Ķa‚ë!Ô9
-.¤¦”ƒ(%¥™‚³ÙÁ” Ú jˆmáÊ_ò/o<“mÝ$ átqjÞ@å œ8ïL ‰8ȯd“›ßDÓwÞoGßD!Ë~Ï«²´näz»˜¬ëQ§" s Ì8 :Ô’¯ðQ¬¾kÛß|Rä¢y¦žîB Ò· U”P¾ì™R"•”&2A.—sAD±-Dšà:§[=½‡*ãGG•u—ä}á¸çŸVó¬`ãßô—ð£s4§^ž*í©úB¹ÚêM°®œmÃŽ‘z
-Æâ¶SÊn Zʨ¢‡¢º³…3ìq[è [ðÃém×4»6zÂÿ{Vî«ôøNš‹‘ÏŽ3ô½˜ÒÄlŽâé'¼KÅ÷G–çr¦ýbâCµ¼};å09º‘òO9Ëš‚éïŽK.an)e èØ•EöAf:
-¿×ùJ8Œx ½àƒb%¥óž0rÊNhƒâ!¶…bü:+ô±õ9}aªfÎÎNÚÑšB¶@,õD$ãŸÁnªôû«è‘ìT08íOu£yH¬<@(A@¤›CÈ΂ê>IEŽ:Ú…Ûq0§ÀDNc8 Ï*D²÷MÉÿ›Å5 ʨ WÆy(ö{1°Wßõcå°Êš'néãE8›@Qd6=âDÐ÷éê–•ç¦|°çV7êsç)3~§ñé”ÿÌç'žVQ[G:Àÿß?È2ú“‘Gb[Ï… 2õ$R/Å7—$Ã7׿Ü:õÿo÷±endstream
-endobj
-1805 0 obj <<
+xÚ¥Z[w£º~ϯð£½Ö˜Jqé›'Og’ÔÎô´kÎy ¶â°ŠÁœ9s~}·Ð‘<=]yH>Øß¾c<Að‡'1õI‚I”E˜N¶‡+4ÙÃÞý–2s%47¥®Ÿ¯þrG¢Iâ%¡Nž_{ÅŠc<yÞ}›.žžn–«Îæ>EÓ…7›S„ÔêÍíf6„o¾¢éõêúóêñ~½xúø/qѯˆ¢ÅÃRœl¾Þßßnžoåéúv±\=܃žýöüéêöY?¶ùjþÌÿ¹úöšìà ?]!$1|‡äá$ñ'‡«€„¨•üjsõw}Cc·½tLU”ÄýhDW>ž`ì%”ú=eÑÄ ‰OZe-6⵬J›¬,jë[ Oq.-#À#KÈpôoë»Pùmˆ‰)òâžßªe†¨pØ¡bJ½8"Ô„]–‡4+Ä{§»CVdu/_VµX+;]´çûS¶cÆÁ+ázAÆð@ü¾„øOüÿ\6pÏY¨‡ò^X%ÎpGžUÙ@œ/mÈ¡nCÊ¡p%¥UNIäP¹ ÚPúÛ¢vü¦<J©xmyË´IÅÑ]–3qtS¿"äïO‚±x[U3O9M#T€2ƒ0 }*žfØO¦’kƪ†R¹÷¸mJƒŒ„XÉ èB¨2¥ìdh)MF‚};N莌3ìq2zà£dè0æÒ?ŠÝŸ¥ÄÇÔ ãØïS²Tl¤•éw쥚ÅÓSZýÐŒ„vF"xsŠâ ŒRF””bÄG9qAŒ ±-Œ˜àgÊ¿©²†U™t×Rëº,QÒƒô˜ «ÞYUF©(ŒÃ>×’‡/iQdÅ~ÀvÏqþ1£tšýž1‹ç8x}„¾@S'ä`I
+i’|œ8Hrà €-È_k©îòuà8‹<KkV˜z`Í÷²úwGQ¶eã…±ùA0žI>¦‡,o”Ói’ÖrûîGU¶k,E
+²WÌ}’x”B]1|DXáª
+)ÒI8² ×à|
+D}`k°ùzH‹v;–<óç‘<k˜¹mP7,ÏKÍt ²}Ó|Û«"
+éÿBp7¥Œ+)ƒrì Ümp>Ķn‚sF…‹±#ø4¥ w}vÓT`j¯K‚^ñÒ•‹µ±ŸïÄQ¾¯Ì‡‹è8:4‰8Œmúp€ÂŽq~ƒqq¯–p¾óE®nÒ#ü:O‹íkþáAL ƒº”ÍM);áZÊ ÜQ;¡;ÂÏ°Ç ï?ŠÛrÇx
+ÈLíª¯ÝƒïüÂÙ)óWy~„{¹ÿý_ýò£ Šòr,4æ0[ÄV>ýˆzQx)]˜Rv>µTÇ'uNèŽÏ3ìq>{à =}gE7½S.%«‚ó©êÏrjÇtå¬Q„Gõ1þYoÓm»›x1xé„´H!]Ò£ÈÑùp RÀN ä5ƒnŒ°­Q3+ZÄpEdôºP•:¢ þ0yCA»/ÁóêÁЯ%k”"J¼8 õ÷'IQ猣o(À±&B½
+endobj
+2229 0 obj <<
/Type /Page
-/Contents 1806 0 R
-/Resources 1804 0 R
+/Contents 2230 0 R
+/Resources 2228 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1747 0 R
+/Parent 2112 0 R
>> endobj
-1807 0 obj <<
-/D [1805 0 R /XYZ 85.0394 794.5015 null]
+2231 0 obj <<
+/D [2229 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1808 0 obj <<
-/D [1805 0 R /XYZ 85.0394 748.4854 null]
+2232 0 obj <<
+/D [2229 0 R /XYZ 85.0394 748.4854 null]
>> endobj
-1809 0 obj <<
-/D [1805 0 R /XYZ 85.0394 748.4854 null]
+2233 0 obj <<
+/D [2229 0 R /XYZ 85.0394 748.4854 null]
>> endobj
-1810 0 obj <<
-/D [1805 0 R /XYZ 85.0394 748.4854 null]
+2234 0 obj <<
+/D [2229 0 R /XYZ 85.0394 748.4854 null]
>> endobj
-1811 0 obj <<
-/D [1805 0 R /XYZ 85.0394 743.3452 null]
+2235 0 obj <<
+/D [2229 0 R /XYZ 85.0394 743.3452 null]
>> endobj
-1812 0 obj <<
-/D [1805 0 R /XYZ 85.0394 728.6405 null]
+2236 0 obj <<
+/D [2229 0 R /XYZ 85.0394 728.6405 null]
>> endobj
-1813 0 obj <<
-/D [1805 0 R /XYZ 85.0394 723.1655 null]
+2237 0 obj <<
+/D [2229 0 R /XYZ 85.0394 723.1655 null]
>> endobj
-1814 0 obj <<
-/D [1805 0 R /XYZ 85.0394 708.4607 null]
+2238 0 obj <<
+/D [2229 0 R /XYZ 85.0394 708.4607 null]
>> endobj
-1815 0 obj <<
-/D [1805 0 R /XYZ 85.0394 702.9857 null]
+2239 0 obj <<
+/D [2229 0 R /XYZ 85.0394 702.9857 null]
>> endobj
-1816 0 obj <<
-/D [1805 0 R /XYZ 85.0394 688.2211 null]
+2240 0 obj <<
+/D [2229 0 R /XYZ 85.0394 688.2211 null]
>> endobj
-1817 0 obj <<
-/D [1805 0 R /XYZ 85.0394 682.8059 null]
+2241 0 obj <<
+/D [2229 0 R /XYZ 85.0394 682.8059 null]
>> endobj
-1818 0 obj <<
-/D [1805 0 R /XYZ 85.0394 668.0414 null]
+2242 0 obj <<
+/D [2229 0 R /XYZ 85.0394 668.0414 null]
>> endobj
-1819 0 obj <<
-/D [1805 0 R /XYZ 85.0394 662.6262 null]
+2243 0 obj <<
+/D [2229 0 R /XYZ 85.0394 662.6262 null]
>> endobj
-1820 0 obj <<
-/D [1805 0 R /XYZ 85.0394 599.7666 null]
+2244 0 obj <<
+/D [2229 0 R /XYZ 85.0394 599.7666 null]
>> endobj
-1821 0 obj <<
-/D [1805 0 R /XYZ 85.0394 599.7666 null]
+2245 0 obj <<
+/D [2229 0 R /XYZ 85.0394 599.7666 null]
>> endobj
-1822 0 obj <<
-/D [1805 0 R /XYZ 85.0394 599.7666 null]
+2246 0 obj <<
+/D [2229 0 R /XYZ 85.0394 599.7666 null]
>> endobj
-1823 0 obj <<
-/D [1805 0 R /XYZ 85.0394 591.7571 null]
+2247 0 obj <<
+/D [2229 0 R /XYZ 85.0394 591.7571 null]
>> endobj
-1824 0 obj <<
-/D [1805 0 R /XYZ 85.0394 565.0374 null]
+2248 0 obj <<
+/D [2229 0 R /XYZ 85.0394 565.0374 null]
>> endobj
-1825 0 obj <<
-/D [1805 0 R /XYZ 85.0394 559.6222 null]
+2249 0 obj <<
+/D [2229 0 R /XYZ 85.0394 559.6222 null]
>> endobj
-1826 0 obj <<
-/D [1805 0 R /XYZ 85.0394 534.1777 null]
+2250 0 obj <<
+/D [2229 0 R /XYZ 85.0394 534.1777 null]
>> endobj
-1827 0 obj <<
-/D [1805 0 R /XYZ 85.0394 527.4872 null]
+2251 0 obj <<
+/D [2229 0 R /XYZ 85.0394 527.4872 null]
>> endobj
-1828 0 obj <<
-/D [1805 0 R /XYZ 85.0394 502.0427 null]
+2252 0 obj <<
+/D [2229 0 R /XYZ 85.0394 502.0427 null]
>> endobj
-1829 0 obj <<
-/D [1805 0 R /XYZ 85.0394 495.3523 null]
+2253 0 obj <<
+/D [2229 0 R /XYZ 85.0394 495.3523 null]
>> endobj
-1830 0 obj <<
-/D [1805 0 R /XYZ 85.0394 420.5376 null]
+2254 0 obj <<
+/D [2229 0 R /XYZ 85.0394 420.5376 null]
>> endobj
-1831 0 obj <<
-/D [1805 0 R /XYZ 85.0394 420.5376 null]
+2255 0 obj <<
+/D [2229 0 R /XYZ 85.0394 420.5376 null]
>> endobj
-1832 0 obj <<
-/D [1805 0 R /XYZ 85.0394 420.5376 null]
+2256 0 obj <<
+/D [2229 0 R /XYZ 85.0394 420.5376 null]
>> endobj
-1833 0 obj <<
-/D [1805 0 R /XYZ 85.0394 412.5281 null]
+2257 0 obj <<
+/D [2229 0 R /XYZ 85.0394 412.5281 null]
>> endobj
-1834 0 obj <<
-/D [1805 0 R /XYZ 85.0394 388.4584 null]
+2258 0 obj <<
+/D [2229 0 R /XYZ 85.0394 388.4584 null]
>> endobj
-1835 0 obj <<
-/D [1805 0 R /XYZ 85.0394 380.3932 null]
+2259 0 obj <<
+/D [2229 0 R /XYZ 85.0394 380.3932 null]
>> endobj
-1836 0 obj <<
-/D [1805 0 R /XYZ 85.0394 365.6884 null]
+2260 0 obj <<
+/D [2229 0 R /XYZ 85.0394 365.6884 null]
>> endobj
-1837 0 obj <<
-/D [1805 0 R /XYZ 85.0394 360.2134 null]
+2261 0 obj <<
+/D [2229 0 R /XYZ 85.0394 360.2134 null]
>> endobj
-1838 0 obj <<
-/D [1805 0 R /XYZ 85.0394 345.4488 null]
+2262 0 obj <<
+/D [2229 0 R /XYZ 85.0394 345.4488 null]
>> endobj
-1839 0 obj <<
-/D [1805 0 R /XYZ 85.0394 340.0336 null]
+2263 0 obj <<
+/D [2229 0 R /XYZ 85.0394 340.0336 null]
>> endobj
-1840 0 obj <<
-/D [1805 0 R /XYZ 85.0394 325.269 null]
+2264 0 obj <<
+/D [2229 0 R /XYZ 85.0394 325.269 null]
>> endobj
-1841 0 obj <<
-/D [1805 0 R /XYZ 85.0394 319.8539 null]
+2265 0 obj <<
+/D [2229 0 R /XYZ 85.0394 319.8539 null]
>> endobj
-1842 0 obj <<
-/D [1805 0 R /XYZ 85.0394 295.7842 null]
+2266 0 obj <<
+/D [2229 0 R /XYZ 85.0394 295.7842 null]
>> endobj
-1843 0 obj <<
-/D [1805 0 R /XYZ 85.0394 287.7189 null]
+2267 0 obj <<
+/D [2229 0 R /XYZ 85.0394 287.7189 null]
>> endobj
-1844 0 obj <<
-/D [1805 0 R /XYZ 85.0394 272.9543 null]
+2268 0 obj <<
+/D [2229 0 R /XYZ 85.0394 272.9543 null]
>> endobj
-1845 0 obj <<
-/D [1805 0 R /XYZ 85.0394 267.5392 null]
+2269 0 obj <<
+/D [2229 0 R /XYZ 85.0394 267.5392 null]
>> endobj
-1846 0 obj <<
-/D [1805 0 R /XYZ 85.0394 252.7746 null]
+2270 0 obj <<
+/D [2229 0 R /XYZ 85.0394 252.7746 null]
>> endobj
-1847 0 obj <<
-/D [1805 0 R /XYZ 85.0394 247.3594 null]
+2271 0 obj <<
+/D [2229 0 R /XYZ 85.0394 247.3594 null]
>> endobj
-1848 0 obj <<
-/D [1805 0 R /XYZ 85.0394 223.2897 null]
+2272 0 obj <<
+/D [2229 0 R /XYZ 85.0394 223.2897 null]
>> endobj
-1849 0 obj <<
-/D [1805 0 R /XYZ 85.0394 215.2245 null]
+2273 0 obj <<
+/D [2229 0 R /XYZ 85.0394 215.2245 null]
>> endobj
-1850 0 obj <<
-/D [1805 0 R /XYZ 85.0394 149.4956 null]
+2274 0 obj <<
+/D [2229 0 R /XYZ 85.0394 149.4956 null]
>> endobj
-1851 0 obj <<
-/D [1805 0 R /XYZ 85.0394 149.4956 null]
+2275 0 obj <<
+/D [2229 0 R /XYZ 85.0394 149.4956 null]
>> endobj
-1852 0 obj <<
-/D [1805 0 R /XYZ 85.0394 149.4956 null]
+2276 0 obj <<
+/D [2229 0 R /XYZ 85.0394 149.4956 null]
>> endobj
-1853 0 obj <<
-/D [1805 0 R /XYZ 85.0394 144.3554 null]
+2277 0 obj <<
+/D [2229 0 R /XYZ 85.0394 144.3554 null]
>> endobj
-1854 0 obj <<
-/D [1805 0 R /XYZ 85.0394 120.2857 null]
+2278 0 obj <<
+/D [2229 0 R /XYZ 85.0394 120.2857 null]
>> endobj
-1855 0 obj <<
-/D [1805 0 R /XYZ 85.0394 112.2205 null]
+2279 0 obj <<
+/D [2229 0 R /XYZ 85.0394 112.2205 null]
>> endobj
-1856 0 obj <<
-/D [1805 0 R /XYZ 85.0394 97.4559 null]
+2280 0 obj <<
+/D [2229 0 R /XYZ 85.0394 97.4559 null]
>> endobj
-1857 0 obj <<
-/D [1805 0 R /XYZ 85.0394 92.0407 null]
+2281 0 obj <<
+/D [2229 0 R /XYZ 85.0394 92.0407 null]
>> endobj
-1804 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F39 899 0 R >>
+2228 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1860 0 obj <<
-/Length 2121
+2284 0 obj <<
+/Length 2928
/Filter /FlateDecode
>>
stream
-xÚ¥YIs㸾ûWèª*B°pÍM¶ÔŽ»=¶cy*™t÷¦`‰eŠÔˆ”»5¿>x J$5•”Äòà}x 6¢ðc#Ï'~Ä£Q¹Ä£Ì%›+:ZÁÜí34“šhbS]¿\ýí“F‰|î^Þ,Y!¡aÈF/˯Δ2 Ô¹¾»¾¿{¼}ž>ýã·ñ„{ÔùF=:}˜agñëíí|ñ27Ýçùtv÷p $l< üˆ:Ó§§ùÃìîß8?URi3z3_Œ¿¿|¾š¿4˶·Æ¨Pkþýêëw:ZÂ?_Q"¢Ðý€%,Šøhsåz‚x®õHvµ¸úg#Кլ¦b”páó[q6bŒDžÇ[Æò"â .´±_Ë"“•\âg c™ìwiu0¦ùtSönV¸Ð Ñ-*\ﱦRKû
-Z9õ½ï§šç`/VÝPë‘¥›ñ€x<hëž›8ÍÇ—Sç!ÞHÕbÎâPVrƒ£G©™ùÏJæeZäÚL'»c!%Aø°.%û¯Àâ gF k\VYü.Ç g\GìÆ,t–¨'ÎMãÆЉ÷o›87R>Çù>Þ”VØr­hÒÀúà\¤=ê’ê
-›ª‹†ªÃ~4¨úˆÆ™îN8Zº/Û¿h†ý($Š¼ÿƒ_bÝMÖ Q?~H"\ÈK6Õ
-¸÷‹Š{Jð/qYÊŽéZA/‰E©¢
-\§Il‡·îLx‹j
-aÜo汆ÆÙ3¨¢sõd¥Ë*^ÉÛXxùÎR~ȬتýÁŠüˆ9w›m&U¿Øé½cïU¢Àâ,pò¢2ª‹ö6°L@ÎU\¿²q8.€6býN}×I?âL¥°Ž ®üHU®‹}fFµVÕx•øý}_à»*ê¬cIj†\m­17ÂÞÔ©ÏpÐƺû<3ú$)6“.|¶qžjéŒ:¯ü≀Æ2-“,N7:‡ê‰¸jH ññBçç®:s%võrá‹(+$-K¢èp
-uüa„ÄøÉÒ7YÂò°§O+|Ëô'66E^­ /œ÷z‰?Ö)\6;6jVìÙ+†ÎRZ/ÙÉT[?뙉WÃ
-BRSOÄú1£ì ô<(AD]­Xx©°óZìM¬¸¾{˜åºP¬ú\J"VßCÞäN¹Qï3;¡Ô»pý²©Î“ ì‚
-ÓÙ„õç‘A­Ç<r¦¶3´´b¡žq+êÛ–²íC@ …ñç)ÞgÈ4ÍàÂõlj¤8Nš¼ëøýût¯™ çö°KWk\F,an¨þ^¡æ9Á%@?.aÂIàG°O‹îe^×å€ÃúúdQâÚò5.«b[èhAöfúwœyüË3¤™yÂçžÒur¥kª‘)\+’ÎrÙ[tÀaUuàE›cýÿ/eU/aßU„f¿^”6 ¥gK¯ÿÁ:_ûl«½endstream
-endobj
-1859 0 obj <<
+xÚ¥ZKs㸾ûWèºjÅ
+<ÃL[µFÛ„¦2q¦âØ—r“§Ôùm»”m6dÂ]ßK, Õ\—¾HMÖ(êÞl[ç5Gñcᆰñq<l®Óxt\ñ¦QÕ<ÞéÄ£§ûüù÷Ã͸7EÂM’àÀàW©ºéºÃ!9Cè»O£38X\#8.ƒƒ`,ÁaLµ…ñîalÝÇlT»ÃAÄ‘ó 2Ââæ
+Z\sä«2/WÔ™íÚu¥øßãä…’Vb=Ïs>¸4ñŸ—^³¢
+>4°îëEáz—S×綹e¦%]×ò¹*©^a ÆT6Z³âÀÌ‚6•}·×>”Ý!AGµ«Ýj=]â"¾Uõ‹*Aqþ²Jw¨LÿªúÄñ¾æ›r•—YVëéú°eóBÌpÜäÂøÚÄatÑãë{‘^£*abG]*£ÈÉ 
+-S¢&ôjô°§Š[š^@-]âó•"6­\e µ©ü
+eöšÕ÷+
+îÜn¶E†ýªÖÒ»ó‰©Üa¢ -rʪժ«þ6š¹’æÅÍs,¨!ÕW8æÆ“¿Êm)61!Rõÿž¸šuµ+4UiÅÆSFß?v½±£Êj@KsMòÕù(¥öŒV_Ñƺ»²€cÖüiZm¦Cøle™+éœ9O{ú’E@c™7i!óÊ¡j@¶‹f>!t¾yž6×PW-¾„bµ"Ö¦q‘†è¡±–¯Zˆ¤O‘?g ,zÊZáÛä?¨±©Êv­ç‚½›%¾­s¸rlT¯8°W ef½jwG†mõ¸§žôT’ëzBª'f08°÷AAè p"Lµbá…aç©ÚéX¡~èäÂÄ;¹ž véëÈsV£|s÷"Ïeqäg›ë}6᜹À&ÂT:á§ɨÖC"y§v0‘ô´R"aö+ÚGe/:„ì +äÃœ¹+hÒ¬€{ןG’®À,œ<}Qú_òNä>”œÛ}¯Ö*»LxÃükaú‘Ò
+¥ë,ž'šž^¦°ƒŽ_R‡­„>+²(»¡°Ä¼Õ2r•´0b¯P+Ê3=ØTô¥¸E-ŒØJ¥VŒ¡—'/ôvEÙæœâýt+ëVåv[äôzÖ Å™MÕ…À)“M^à 1ÊßošžÊ¢ *¬hC´ÃFuxZ‘ƒQv{BŠŠ© ÓvÞ÷±0Àª& •kã^.õS…RUiªÑ½‘ÿQIh
+® ,¸è«ª íEšN¡hKÂsÚZ–LµYÃÈ[Þ®©%éƒÞš§»BÖÔo²úõPá óAÖ²û9Ø(ããûÃ÷VSì¡Á ø9-]@ öné>Ã
+\˜šE©º¬ôxéæ‚Þ¯ý¿Ô! Jendstream
+endobj
+2283 0 obj <<
/Type /Page
-/Contents 1860 0 R
-/Resources 1858 0 R
+/Contents 2284 0 R
+/Resources 2282 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1747 0 R
+/Parent 2112 0 R
>> endobj
-1861 0 obj <<
-/D [1859 0 R /XYZ 56.6929 794.5015 null]
+2285 0 obj <<
+/D [2283 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1862 0 obj <<
-/D [1859 0 R /XYZ 56.6929 749.4437 null]
+2286 0 obj <<
+/D [2283 0 R /XYZ 56.6929 749.0089 null]
>> endobj
-1863 0 obj <<
-/D [1859 0 R /XYZ 56.6929 749.4437 null]
+2287 0 obj <<
+/D [2283 0 R /XYZ 56.6929 749.0089 null]
>> endobj
-1864 0 obj <<
-/D [1859 0 R /XYZ 56.6929 749.4437 null]
+2288 0 obj <<
+/D [2283 0 R /XYZ 56.6929 749.0089 null]
>> endobj
-1865 0 obj <<
-/D [1859 0 R /XYZ 56.6929 746.6461 null]
+2289 0 obj <<
+/D [2283 0 R /XYZ 56.6929 745.2843 null]
>> endobj
-1866 0 obj <<
-/D [1859 0 R /XYZ 56.6929 722.5763 null]
+2290 0 obj <<
+/D [2283 0 R /XYZ 56.6929 721.2146 null]
>> endobj
-1867 0 obj <<
-/D [1859 0 R /XYZ 56.6929 716.7581 null]
+2291 0 obj <<
+/D [2283 0 R /XYZ 56.6929 714.4694 null]
>> endobj
-1868 0 obj <<
-/D [1859 0 R /XYZ 56.6929 701.9936 null]
+2292 0 obj <<
+/D [2283 0 R /XYZ 56.6929 699.7048 null]
>> endobj
-1869 0 obj <<
-/D [1859 0 R /XYZ 56.6929 698.8254 null]
+2293 0 obj <<
+/D [2283 0 R /XYZ 56.6929 695.6096 null]
>> endobj
-1870 0 obj <<
-/D [1859 0 R /XYZ 56.6929 684.1207 null]
+2294 0 obj <<
+/D [2283 0 R /XYZ 56.6929 680.9049 null]
>> endobj
-1871 0 obj <<
-/D [1859 0 R /XYZ 56.6929 680.8926 null]
+2295 0 obj <<
+/D [2283 0 R /XYZ 56.6929 676.7499 null]
>> endobj
-1872 0 obj <<
-/D [1859 0 R /XYZ 56.6929 656.8229 null]
+2296 0 obj <<
+/D [2283 0 R /XYZ 56.6929 652.6802 null]
>> endobj
-1873 0 obj <<
-/D [1859 0 R /XYZ 56.6929 651.0047 null]
+2297 0 obj <<
+/D [2283 0 R /XYZ 56.6929 645.935 null]
>> endobj
-1874 0 obj <<
-/D [1859 0 R /XYZ 56.6929 636.3 null]
+2298 0 obj <<
+/D [2283 0 R /XYZ 56.6929 631.2303 null]
>> endobj
-1875 0 obj <<
-/D [1859 0 R /XYZ 56.6929 633.072 null]
+2299 0 obj <<
+/D [2283 0 R /XYZ 56.6929 627.0752 null]
>> endobj
-1876 0 obj <<
-/D [1859 0 R /XYZ 56.6929 609.0023 null]
+2300 0 obj <<
+/D [2283 0 R /XYZ 56.6929 603.0055 null]
>> endobj
-1877 0 obj <<
-/D [1859 0 R /XYZ 56.6929 603.184 null]
+2301 0 obj <<
+/D [2283 0 R /XYZ 56.6929 596.2603 null]
>> endobj
-1878 0 obj <<
-/D [1859 0 R /XYZ 56.6929 579.1143 null]
+2302 0 obj <<
+/D [2283 0 R /XYZ 56.6929 572.1906 null]
>> endobj
-1879 0 obj <<
-/D [1859 0 R /XYZ 56.6929 573.2961 null]
+2303 0 obj <<
+/D [2283 0 R /XYZ 56.6929 565.4454 null]
>> endobj
-1880 0 obj <<
-/D [1859 0 R /XYZ 56.6929 558.5914 null]
+2304 0 obj <<
+/D [2283 0 R /XYZ 56.6929 550.7407 null]
>> endobj
-1881 0 obj <<
-/D [1859 0 R /XYZ 56.6929 555.3634 null]
+2305 0 obj <<
+/D [2283 0 R /XYZ 56.6929 546.5857 null]
>> endobj
-1882 0 obj <<
-/D [1859 0 R /XYZ 56.6929 540.5988 null]
+2306 0 obj <<
+/D [2283 0 R /XYZ 56.6929 531.8211 null]
>> endobj
-1883 0 obj <<
-/D [1859 0 R /XYZ 56.6929 537.4306 null]
+2307 0 obj <<
+/D [2283 0 R /XYZ 56.6929 527.7259 null]
>> endobj
-1884 0 obj <<
-/D [1859 0 R /XYZ 56.6929 510.7109 null]
+2308 0 obj <<
+/D [2283 0 R /XYZ 56.6929 501.0062 null]
>> endobj
-1885 0 obj <<
-/D [1859 0 R /XYZ 56.6929 507.5427 null]
+2309 0 obj <<
+/D [2283 0 R /XYZ 56.6929 496.911 null]
>> endobj
-642 0 obj <<
-/D [1859 0 R /XYZ 56.6929 477.5928 null]
+770 0 obj <<
+/D [2283 0 R /XYZ 56.6929 464.7873 null]
>> endobj
-1886 0 obj <<
-/D [1859 0 R /XYZ 56.6929 453.2532 null]
+2310 0 obj <<
+/D [2283 0 R /XYZ 56.6929 439.0859 null]
>> endobj
-646 0 obj <<
-/D [1859 0 R /XYZ 56.6929 369.7201 null]
+774 0 obj <<
+/D [2283 0 R /XYZ 56.6929 352.4521 null]
>> endobj
-1887 0 obj <<
-/D [1859 0 R /XYZ 56.6929 345.3805 null]
+2311 0 obj <<
+/D [2283 0 R /XYZ 56.6929 326.7507 null]
>> endobj
-1888 0 obj <<
-/D [1859 0 R /XYZ 56.6929 310.6805 null]
+2312 0 obj <<
+/D [2283 0 R /XYZ 56.6929 290.6891 null]
>> endobj
-1889 0 obj <<
-/D [1859 0 R /XYZ 56.6929 310.6805 null]
+2313 0 obj <<
+/D [2283 0 R /XYZ 56.6929 290.6891 null]
>> endobj
-1890 0 obj <<
-/D [1859 0 R /XYZ 56.6929 310.6805 null]
+2314 0 obj <<
+/D [2283 0 R /XYZ 56.6929 290.6891 null]
>> endobj
-1891 0 obj <<
-/D [1859 0 R /XYZ 56.6929 310.6805 null]
+2315 0 obj <<
+/D [2283 0 R /XYZ 56.6929 290.6891 null]
>> endobj
-1858 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F39 899 0 R /F14 740 0 R >>
+778 0 obj <<
+/D [2283 0 R /XYZ 56.6929 241.4457 null]
+>> endobj
+2316 0 obj <<
+/D [2283 0 R /XYZ 56.6929 201.7704 null]
+>> endobj
+2282 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F39 1151 0 R /F14 956 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1894 0 obj <<
+2319 0 obj <<
+/Length 2294
+/Filter /FlateDecode
+>>
+stream
+xÚ¥]sã6î=¿Â9yf­"õÕ·ìn¶“¶—Ë9éLov÷A–¨˜]Yrõa×ÿþ
+S ÃH:t Eô[óRít¦2pRîú´VZìKE–
+NP˜d»¤L•%ÎUÒvVž%Íi¯93"(èŠéA·¨û M—®iKb1i’®AÐÆ„žº >y¨OøÆ&™sgg$rjñÍØ°r?„Z.ÒªL»šø”-úbQæ~­Jz#aÿÈÏìi’î÷h+¾+'¯¤ÙªTaÌSjã¾”~‚X¸’ þz"S½œª7Á«R‰àBìd"8{ƒF |GýµUµÆ8N
+Âä5DÒ¾ª¿ákà´¡›n»­0iàKï¡È`{ »î\'VˆuJ€â4hHuÙ˘À®¤ù6åuÍ¡iÕÆÜè6ê/1Ÿ-<0 ÈÖÓ†PˆÀ;9ƒ2õP«ZýÙéF·Êr[Dy¾x>íüéþ78‹' U}Có<ò"ÀŸ'2ÂÁsÕiÌ°œp``2Àc ºsoIX¥œŒ‰jxZ»iLˆÔX€¦ÕEAK+un÷ïµ 5ädØOø}{Øâ1¼( 
+
+(„bzØŽàr^CWbøà5sr
+|4
+bsب–
+7™06— z[_ÚT(c›¹$³­4;E+X& ›%‡"óÀÐ 5Ô H²RÏu‡l»‘ ù© èj$5.’û4-È¡ƒì1á<k´“Žˆôã;%Lטn ©Íyåi_„xr0\HŠ¦"he%ØÌj8ÑÝöœ&RÐÈþ9eCñzzÇ…®Û(E/+UTû¡ùŽ 6¨ïJ輋ÿ1ªÓŒž¯ûå8X ¤IÖ÷F®çÖ°õ›ÍK©æ¥Zýv!˜œÌlö{s#žÊ
+²y<ChR µJH%âWÇ«jØb€;WP§ªbu8›ZÎURC—iÑÁ„&L^š
+P#¢ &6æ0wV}-±b]íO«–í%9µ2¶žTû¾Ò“žAäíEÑѣ̀~ãÊ»Ì^¹¾'åe ±)ìúŸ`ÖnqaSx¿áÄ«¶´¥$ÓÕå„á#áQàY1Ó½|Os‘ï¤Íw¿”Æ
+惒ÊáNšë¥jÚZÓ‡„—8@Ääܘêån zs€{Uêq€»;9Àˆýp2ßh0á–ÂCP˜XÃg‰±ˆ€âLî€×Û Èwƒã´‚ðYÝ26iàÞ.‘ØO|)Úˆ8ñKD˜‰••@Åt"'%M_ñX¨Ù«9÷}WúL¾qŸ#ªWzû>_“:ºÏs±Ó÷9K^"áÐtÀ¼¿TF¹ ‘Ë¥é:$ã˜b¯¦m‹ì›ýpG'ßNìWšèäúÍÖ’žm/zèᢋÛYìÜå´dF+ö‰™Ú¡¾™ 8¢oX/dîpŠ³:áØ8Ò WÐBi:–Ž™ .Ó>÷7ŠCßfœÈ²‰œ#„‰¸§Ú¯ua‡H;B£x“kéƒÞqàõÁûxÁÏD‚…¶êÚ³IÙªJ¹’Ì Exêìc…±dÐż³@©ß•%±3Hqøñ….oÔ~½9»åη¨ks“ÓÛ;‚W%0þ5=ÿ}Ï ÷Âòÿ?]¾}¾‘Ž_§œòÕVx*åW1ùQž %ìoÿ{☻dèŠ(ò¦sˆ€\Sï…
+qÏ??º/ PG^8qöÿIì»äendstream
+endobj
+2318 0 obj <<
+/Type /Page
+/Contents 2319 0 R
+/Resources 2317 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2112 0 R
+>> endobj
+2320 0 obj <<
+/D [2318 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+782 0 obj <<
+/D [2318 0 R /XYZ 85.0394 662.3711 null]
+>> endobj
+2321 0 obj <<
+/D [2318 0 R /XYZ 85.0394 634.4781 null]
+>> endobj
+786 0 obj <<
+/D [2318 0 R /XYZ 85.0394 566.8617 null]
+>> endobj
+2322 0 obj <<
+/D [2318 0 R /XYZ 85.0394 536.3186 null]
+>> endobj
+790 0 obj <<
+/D [2318 0 R /XYZ 85.0394 411.7882 null]
+>> endobj
+2323 0 obj <<
+/D [2318 0 R /XYZ 85.0394 386.7645 null]
+>> endobj
+794 0 obj <<
+/D [2318 0 R /XYZ 85.0394 230.2565 null]
+>> endobj
+2324 0 obj <<
+/D [2318 0 R /XYZ 85.0394 203.9874 null]
+>> endobj
+2317 0 obj <<
+/Font << /F37 1018 0 R /F14 956 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2327 0 obj <<
+/Length 2527
+/Filter /FlateDecode
+>>
+stream
+xÚ¥koÛ8ò{~…±8àd bùгßÒ6=d»Èöììí.Ú~-Ù*K^INâýõ7Ã!eÉ–®*r8œçI‹ ‡?1ñÄ2ž„±Ç|.üÉr{Ã'kXû×08®ErûXïoÞ~Rá$fq ƒÉãªG+b<ŠÄä1ýêÜ2MwÞß?|œºÒçNLŸsürÿ~v;›ªÐù“
+íp_¦Y]ô>œÓš,“’8Naväí,ö- €Á ˜Ýee–÷e²èv—mV¯’¥™¶'ë¡t²­²¤ÝeY°KFÄ!SxòU«êc]6«ë5»ºÊ´3¬3¦£–5`:û·+Eà€÷ ù¤Q€h‹@€±ˆ,%x^˜4
+¦Â¡[
+Žù¡FÏ -iÇ(Êš¤OU²Ôœ Vσ¢D;3 NŠ„® uú‚…Ö
+A! zBΪª zÊaÄwIl3H’ ²R7IK#«pˆ1‚¾‡JʤM.“]²È‹¼=Ð<QÊF,\zÔya`,öºu1ƒâA\R ²¾ræ»l™#d ^Eæ
+ÑPùB‡w䟛a
+‡P€bPœÆD”µO†mÇhJS¾N°ò,§&§Í“íÎ64·ý*íÕ„6¯Ð
+×–¡ià¸WéÀDÆ5·† ¶ûã]ÈÒï ÷†€u½Þf «)AôÑq@h+ÓÑA‚Ę$M˜EQ=w¬ˆ‘À"§‹:ÏVcy-ÍšeïŽ×lm¡±¾ÑSñt © S’Ü?ê› £qÒÖ;2éÄøO~¼S€Ã¨>ö?Ø·”+_½˜{ôBJ7È^ ‘ ôáí)
+)‚Mþ//€’ÅQ¿ÿ¹E·Oò<8Â
+ävXíÐð0Išõ›  ±ÕFM-‡ÇJ ðk¿ãètw«é¬÷˜Øšwg=§
+
+H¨ã
+e0ì>Ùr${ÑÁãÍðÍtÜŠzéÙüDñùîÏ¡9rP#nßÔ“±ÏOè(µ”GµMo£g~ÿÑèþ¾–Ž¥4úøôyyyI´î KyÅK¶˜¦C7c§±¯ë)ÆãØ£‘8hyøíÎ,|¦ïO ðOcŸõ;²2ˆm–h CnÚwš‡i3ÁE HèówUfÿ4ûðU‚ð`¡É×%Ý(í6O!•î‰%[VÏ¥!Ø£Ò``Û.X»+ÛÚÐÝUù‡ž×]DÎïa38îÈË­-Õ6oé+ª&i6‰ ‰yÊÄ_ì E\áê⃣òþR5âѼ«ÃÿïÄŽ/—T•Ñ¥^A†Ð±Ä06B¡„ Î#©ùéì\öÿ=- endstream
+endobj
+2326 0 obj <<
+/Type /Page
+/Contents 2327 0 R
+/Resources 2325 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2333 0 R
+/Annots [ 2330 0 R ]
+>> endobj
+2330 0 obj <<
+/Type /Annot
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [344.9397 501.3201 406.1397 512.7122]
+/Subtype /Link
+/A << /S /GoTo /D (trusted-keys) >>
+>> endobj
+2328 0 obj <<
+/D [2326 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+798 0 obj <<
+/D [2326 0 R /XYZ 56.6929 609.3932 null]
+>> endobj
+2329 0 obj <<
+/D [2326 0 R /XYZ 56.6929 583.208 null]
+>> endobj
+802 0 obj <<
+/D [2326 0 R /XYZ 56.6929 484.1849 null]
+>> endobj
+2331 0 obj <<
+/D [2326 0 R /XYZ 56.6929 454.463 null]
+>> endobj
+806 0 obj <<
+/D [2326 0 R /XYZ 56.6929 405.4622 null]
+>> endobj
+2332 0 obj <<
+/D [2326 0 R /XYZ 56.6929 378.8348 null]
+>> endobj
+2325 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F14 956 0 R /F22 953 0 R /F21 930 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2336 0 obj <<
+/Length 2458
+/Filter /FlateDecode
+>>
+stream
+xÚÍZ[oÛ:~ϯðÛq€c–w‰yKÛì"»9Ù&vÑöA±åD¨,¹’œË¿ß!‡TD[¶Hv±(ZÓähøif8ó k6¡ð‡MRE¨0r’Iej2_ÐÉ=¬ýõ„y™Yš ¥>Þž|ø‹H&†Íõäv9Еš¦lr»ø6=¿¾¾¸ú|ùÏÓWtzNNgŠÒ0ûéâætÆdb8¬H»¦éôãåÕg”6øñùê»üøåüË©H¦ÿ‰›¯×׺‰ÛÓ·œ\Üö ‡/ƨ°ˆ|ûA' x¿?N(&U“'øB 3†OV'R ¢¤a¦<¹9ùG¯p°ê3”T)Q\êÉ „ÁNlÜœ”Pæ™%’™jÙ›“³1s)kÎY‹o¾¨WYQee·ýâLJ’JÀ0Ô~ìÕ91išŽ¿ø¬×x08’¤B¨q›7y³ƒ2Ñà–„½#Ê ñÊÄj”‰Qf‹E“·í6LÎ1JšæŽC{©‘­ù`kÎRb„[Zçóbù~fšÁ‡¤`´uÖd]Ž“Í)K§ù|Ó´Å£ŸòVu»“h[\\Ö º‡Üë³{|§”Ïqá;çCÈŽàà šL/žgöýÁ”p843ÆàÅG­Öe~¢Œöa˜?»Y2¯WgœRv¶¸KÏÎrç<ú ×Æ)ð@î?C©ý'£—:gàÁD´íÛÂÌ+<‘1MeiŒqO”A¢ LÓô°qz©‘­‡QÆ SñÖzìòú;UôQ~xÔ0`8GLÔKüÄ
+‡P¡‹¾¶Ù}ÈœC¡‰¿…d:žÁ8gD =QüL¾=}³Â‘RU˜Œé· é˧‰{‡ƒ/_vpJ©Ìû
+ 7‚$B¦òîe{ÈEµÞì&!ç“wÛ+< VHM4$ì¬QWŠ¹o%š‡€2NâÏuWÔUÈ­.Œ-¹vι߬ ¿¶gû¬Œ¤F¡¦C©ý ¶—RÓ=…˜[ú,U´ÿÛ*qÐx,ãˆ{„v_){ Ãåa3õR#[Gõ@ H IŠ·¶9Kj(ÅGqý• f=XðNïÔ_©0ÁL s¡þÂðµþÚ úúë´õ(ŸqY`è¹tÁÄBò$‰aUûÐnÖëºéòE8g¡ª>0\²Á™Ùèuy|OŒÊÔ@3æpŒ¥öÇh/åbtoºbÔÀù‚`j}[|G€2Æ ‰Ž‘ÚŒµƒQpB5OÛ§—Ù7&+ ¡R²xß×ndÈHÀ^8aQ3DoËÜmÏyòe¶)½ÙC$ôõ{ù ¤<Hçé±PH… e_t´0Fm®ÐѶoì¼Æ#m_¡ êÆ _KAœKbh*§—Ù9ŽNÒÔ¤ñΞ5z"6pø6‰mãà.j§Zø˜È³Ð”EåÅæPÆ`‹­¶£§¬Õ}¹‡;{Ͼ-uÌTFl,ŽË p ÅÜûôôDMë³[=; ¨ò.@UKžŸŸƒš1ž.4I5³'P‘$õi‰ºˆ‰z“ùi»ýT½¿üꚬj³¹MÞte¹ô8%¿td6í/œ9îÃ|Ÿá†è¾~¥¿/ÀlÎC±I$v ,°>]7E…þcá\³àý5x7G±§¢{ÀµUQ«¬Ä/kdÐs(9àlçTÕ#^Ôy[ýæ¿À«{ˆã|ÜòuŽ­v7ðm„]3s£§E‡ËmW¯[zÂÏ·
+¤px—í¾¾ã bzéQ×Nñˆk¡!µíïÛŒbÓeÑùbq¥‘Gåþ`…¸Þ=·,M‰N(
+É)´ ½ n»v—?dEÈ€Ò‰£~v›.û™±)8±sY©F)á ¨
+endobj
+2335 0 obj <<
+/Type /Page
+/Contents 2336 0 R
+/Resources 2334 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2333 0 R
+>> endobj
+2337 0 obj <<
+/D [2335 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+810 0 obj <<
+/D [2335 0 R /XYZ 85.0394 650.8348 null]
+>> endobj
+2338 0 obj <<
+/D [2335 0 R /XYZ 85.0394 625.7398 null]
+>> endobj
+814 0 obj <<
+/D [2335 0 R /XYZ 85.0394 378.0874 null]
+>> endobj
+2339 0 obj <<
+/D [2335 0 R /XYZ 85.0394 350.2627 null]
+>> endobj
+818 0 obj <<
+/D [2335 0 R /XYZ 85.0394 153.7325 null]
+>> endobj
+2340 0 obj <<
+/D [2335 0 R /XYZ 85.0394 128.6375 null]
+>> endobj
+2334 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2343 0 obj <<
+/Length 2393
+/Filter /FlateDecode
+>>
+stream
+xÚÅY_sÛ8ϧðtîAž]sùWsOé5·“Ý6—xgî¦ÛÅV]m˵”¦î§?€ eÊ–Îv(Aø€ÅˆÃ12)K­´£Ìjf¸0£ÙòŒ`îç3áy&is½žžýôw•,³©LGÓûHVÎxž‹Ñtþ>¹`šAO^_½}3žHÃK7ooiðÛÕ뛋›±Ê’áö÷ëëwŽ0O„άL.®¯/ß¾¹ú'1\ LÎõo—·ãÓ_Î.§ÒñÆW¨ñ§³÷øhûûåŒ3es3z†΄µr´<ÓF1£•
+”ÅÙíÙ?:ѬûtÐP‚3©R9`))‡,e,K•TÎR¿7ÅCy>ž(Á“¦X®å䡨h¿uÓ®Še‰»Y"’ÅG¥™ÍyÚÙ;eÌÆy'çi=/Ú » ‘M…S4žoAx5£b¦ñlQ•«–ÆëMý°)–^ÙWA›¡\á©NŠÙ¬\· ¾(·*КjõàV…q·ŒgõrY¬æž·ñzs“EµòÜÅf,òäái Êýˆ¤,iÊÕ<|¶"1±|÷Aùé©l¼r˲A{ÓK[ã®pB0kŒtûhaZ©4)žÚÇzSµE[}ö¤¦Ü|.7ãL'°¾2Yâ”w3õsCÃN
+ùÔi߽3¬XÂu…xìœxyiu¿ï´û Îî‚£é¾1vâž«Ù㞬ØýûeTDP~µÇãA@6¯sõB<D\'â!p¹xøJ«còÊã~ú @™eö´×€
+=GƒjÁ‘žÓ`§y½„´ÏŸV‡;äf‘9}¢Øƒ"Ÿ26Ç ¨rÅR®ÒÓŒ¹Ž°ãBåW`’CØ+¹W€‰o(À΀3+2qz×À.úg`XŽÖÛÆ-Þ(AÐn×{‡»r½.7…OQ0£¸¬¨Äå#˜ÅUŒÄMø­vs˧ !V£ îhL(£˜0ù ÙdÌuâH—;Ò¥o?ÕàPÀʜԤãP¥Ÿj(ØSÓ×¥;%C“¨‘'Õô¼ó3¤÷K È.<Óv]ÍŠ½”_
+j[á ëÉϾh’Y²¨¡ò«?ú—ê£çE›Ì€ÈWL+¸½zØ;þF6¼¹ÙùÒÍ› ¬¦øç…°c­GÈ\™Jõ7ÝÁZÀ-l¾…¡pqÇeÑwdùaøbïBïš¹Òõì²^ u»¿Ám¤2ðAiS&”²Î"o£FŒIáÎuU3J xõ«À¶m*“Ë}Ë€LžÉlW ìÖ:_} @S,ìS4v{ÝÙÀ~ºZÊÑ›v4Š6ObÉnSi쥬Ÿq@ß÷q-6ž»¼³Á¶š•c¸½±½&²¤ô¸€,ØÁg½¡ºdâéKüÒÁ
+ÔGÏ^¬×›zí¿éú¨ ™"ù<–&qp‰¬¡që?ÖÉW4`Vö·!ŒîÇÊé@5Nßfy
+—„oÍ98ŒÍ již–î•.¡UÔèj”ëй^ÖQ›ENj¾×¡ËÚB-3s½h˜£üG®ù…ßQ‹GC.ý9òÃtRr.Îçwùù9”ªúG ½ÿ«dZgNÂ_
+endobj
+2342 0 obj <<
+/Type /Page
+/Contents 2343 0 R
+/Resources 2341 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2333 0 R
+>> endobj
+2344 0 obj <<
+/D [2342 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+822 0 obj <<
+/D [2342 0 R /XYZ 56.6929 740.3318 null]
+>> endobj
+2345 0 obj <<
+/D [2342 0 R /XYZ 56.6929 714.7319 null]
+>> endobj
+2341 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F14 956 0 R /F62 1352 0 R /F41 1208 0 R >>
+/XObject << /Im2 1341 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2348 0 obj <<
+/Length 1890
+/Filter /FlateDecode
+>>
+stream
+xÚ­ÉrÛ6ô®¯Ð‘š‰l\Оœ&í¸ÓI\Çi'ñ"!‹.*Iyé×÷ H‰¶;“Ú>oß
+‰ÖRíŠ%®š{Ý¡viY"p}íV¶Më†äOuZÑiµ/5Éš
+7]Qß!Øï4wŽ®ü¦ŸVŒ±€“`l$]®… ŒyçS"(8­îöm³Ñ?¬Ö‚Ñ oª´¨ß‚ ŽE§Û{íäËv:ûæŽq¯ÛÊ)Òlf?ÿ„€¤±tòð©<\%™´ò\öÀ;
+‘|‡pj>¸»=CÚ|Q>‡Ô7K»…P~¡ü"z*Þ„ÜFïÒ{·‘5-z.ëË'<l¶‡Qá±TFaPÓ(ÆQaÈ­bF}©dp³+ÌÆü2 —•‡\çþî¢d°€šÃŠåal< ¼·²5wmZ9ªÖk×< ä€Iý¸oZGµ,6mÚ>áF–Öl4îºS¹Ò9ý …×h¥2íÍ ßû}Ydi_45ÅD H sè.½óÑfbÏj²qÑöeßzèþØÀ&äö}Yg. Sˆ™ÓÁÈP‰eysÿ—*Á‰J’d¾F¬Šë1ÉóÀa—Š9…Ó<G#u×­¨÷‡þTnÁ#’Êþ?¹Š¯È-¸" KÔTòRßZB¾JÇ*ô¾L,ʧ½qswV¥)¡!›È UóÝÇá¬GH(›)©É0]ç§ü *K)_æçqÎù-¡‘<œòkWIp¨OŠž¯À_9—¹Þî €KU“k‚úPô; ðEÒÚ á³ø(|wÈÕ! õëé¤e=~]ÒÐ:òœ wÊ{Ùc¬ç1`YOÜŸyBDE¯°ôH3,'¾HHÇ',¡j¢ÎiçLÖÙ4]Ñ?M{P.rªnÚ*uf-×C+HG(DóÔÍà[ à}ÒíuV˜dð®:”}ak±õl¤ž5}È ‚¿búÖ ¦÷XÖô/U@Æ)‰£pÊþ»*É@ñY$Od5¬}&e˜ˆ‰—mä‘føŽc…E0Æ))¦Œ­ç¶¶É©Àö8NƒË+÷ûX–qÃ6Zø¦¸ïRëÐv…
+`ç+ ©18 b
+‰ù<Û¡#ÓD¾lœk†ó$“'I¢’)g“Ty,ì}5¨©{ˆ/{=1;¹,º!‘ð=Æ!æÒ?M­]"9‚‚6äá»q¼†4ÊM€%Ið°3÷K»*z;{Ús;'RקõÚM.à)’“HL-E[Ð#ç| ú¹ò™œ…ô2Œaê >ؤ2ëeQ; l9‘
+&ô¼ÅxŽI‡›)~ÌÅ®tG½‰ ì/a€qð\SwÔŒ抸žæ6Iwo48Vl\Z’jH­[ì…r˜I䈫¸Jès]kíOh\H÷ú—Žèht_qW|Gã’qû¡.‹oî·ëÍ3ÅÂH¿k¬Šap¸KQoØ°¯Ù{xxX)ŒïÎfÙ„˜‰ÁO.s ÜÑ"¨C¹®û£‡`Àj¢èPÍÞÛÇXxŸ«|>ò9ºõ €2rÅÖ:]ç¶ĶóÑ–«Å°ó÷A·…MX¶)ÂmÐu÷W]XÇbmH7•Û·&í…–ÛÈÎѤfÓo&šuî'©aì5ýñd<ÊÒ²Ä7ˆ7î&˜çÓ…sÏqJ¶úùm¿?îÍΘ¹Id<>p Þâ{ ®Š@‘‡‡ŽØ=süæ/¼vŽÖ[Ýê:C…_~¸0ÞXÄÌ×e€"Ô=(h´•6pd@´Â«üný
+®UZÒÒi=!ïà üíèëÇLï{$àe0%5;Tµi§St–ðźó?Bj#aÆÁ~dÖî­É%É=ËxA÷~ÊÎ5TüÒÄúq_¦µ½òw&ÙÞœ¸Ø?]œ<LxÙ· òÜ{xÕ<ÒÍ46:„Áw¿_DeLD’<3k
+*¡1*æ…2&d\Š>¼žËþ/+bHÐendstream
+endobj
+2347 0 obj <<
+/Type /Page
+/Contents 2348 0 R
+/Resources 2346 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2333 0 R
+>> endobj
+2349 0 obj <<
+/D [2347 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+826 0 obj <<
+/D [2347 0 R /XYZ 85.0394 741.6375 null]
+>> endobj
+2350 0 obj <<
+/D [2347 0 R /XYZ 85.0394 716.9352 null]
+>> endobj
+830 0 obj <<
+/D [2347 0 R /XYZ 85.0394 420.5643 null]
+>> endobj
+2351 0 obj <<
+/D [2347 0 R /XYZ 85.0394 393.2598 null]
+>> endobj
+2346 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2354 0 obj <<
+/Length 69
+/Filter /FlateDecode
+>>
+stream
+xÚ3T0
+endobj
+2353 0 obj <<
+/Type /Page
+/Contents 2354 0 R
+/Resources 2352 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2333 0 R
+>> endobj
+2355 0 obj <<
+/D [2353 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+2352 0 obj <<
+/ProcSet [ /PDF ]
+>> endobj
+2358 0 obj <<
/Length 1945
/Filter /FlateDecode
>>
@@ -9102,44 +11179,44 @@ FU—¨UÙ‘[¢–õ„/
c˜"v¨¯]¿x /¨¦zŠ©,ƒ‡“jì^MÈ=n´B$ŽÌÿ/Š™AÃozrm@ £óÀ’O#°ã—_ØäƒcÒú:ƒÄl²«Ö2[PCçB‡A|ßöÀ7z WQ@x©k†ÿˆŽ=]LÈw›{Šh( Ï`žÙ±¥|ßd³ø)¼Áº.4h@õ
Ôζ–ú‘*ÁŽ––nU@€u´ŽÂMô©…2&ô5»XžG»<•Å”?
iô¦?ÿûãçOþóšÞn1˜)f3+NAÍï7QUÊñ§êgCí r õ(G§ÀM¡É\3-äY=òaoø‰ëà¤m!.cÖAs/ç˜S¤à¬“içÞ7˜P²nïèK]- Þ}¤/ýÞà[fÌ)Qˆéªhij;Œú«p}ÓXåž\E4z%d˜^§ÙüCIMÒ©s gLü¬
-§g=42¾ûùÁC#j*u[ø a;xs»icŸì½‡ÁKØù;üø<fø³ìäC;°$GúEöÔfГ/U\œ7üÀûò¼ÿSçžqendstream
+§g=42¾ûùÁC#j*u[ø a;xs»icŸì½‡ÁKØù;üø<fø³ìäC;°$GúEöÔfГ/U€Îâü¸áÞ—çýTnžtendstream
endobj
-1893 0 obj <<
+2357 0 obj <<
/Type /Page
-/Contents 1894 0 R
-/Resources 1892 0 R
+/Contents 2358 0 R
+/Resources 2356 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1747 0 R
+/Parent 2333 0 R
>> endobj
-1895 0 obj <<
-/D [1893 0 R /XYZ 85.0394 794.5015 null]
+2359 0 obj <<
+/D [2357 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-650 0 obj <<
-/D [1893 0 R /XYZ 85.0394 769.5949 null]
+834 0 obj <<
+/D [2357 0 R /XYZ 85.0394 769.5949 null]
>> endobj
-1896 0 obj <<
-/D [1893 0 R /XYZ 85.0394 573.0107 null]
+2360 0 obj <<
+/D [2357 0 R /XYZ 85.0394 573.0107 null]
>> endobj
-654 0 obj <<
-/D [1893 0 R /XYZ 85.0394 573.0107 null]
+838 0 obj <<
+/D [2357 0 R /XYZ 85.0394 573.0107 null]
>> endobj
-1897 0 obj <<
-/D [1893 0 R /XYZ 85.0394 538.4209 null]
+2361 0 obj <<
+/D [2357 0 R /XYZ 85.0394 538.4209 null]
>> endobj
-1898 0 obj <<
-/D [1893 0 R /XYZ 85.0394 504.6118 null]
+2362 0 obj <<
+/D [2357 0 R /XYZ 85.0394 504.6118 null]
>> endobj
-1899 0 obj <<
-/D [1893 0 R /XYZ 85.0394 432.7569 null]
+2363 0 obj <<
+/D [2357 0 R /XYZ 85.0394 432.7569 null]
>> endobj
-1900 0 obj <<
-/D [1893 0 R /XYZ 85.0394 303.3232 null]
+2364 0 obj <<
+/D [2357 0 R /XYZ 85.0394 303.3232 null]
>> endobj
-1892 0 obj <<
-/Font << /F21 714 0 R /F22 737 0 R /F41 939 0 R /F53 1029 0 R >>
+2356 0 obj <<
+/Font << /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1903 0 obj <<
+2367 0 obj <<
/Length 3825
/Filter /FlateDecode
>>
@@ -9159,29 +11236,29 @@ bÎDü…îR
”®DXð9I;܉
ô½¿ù@„0È•œåñú¹X¶åçbã?^¡€™ À° õW¶ÖƒMw›gÂW%fèÂphðRØ.]¡Ã‰h¾,¤ª\,6<ÏËe³8´Z9ÿký¾ÅEÓèâ}ÂÆLÁ©—îÀS7ØQóëEÚP8d½¡é“löá»—)Rú±-Ú5˜³Àe’ù¸Ÿ9.¯nè­NmÆÇácÕyW­ µãrâÖK…zº÷¿
"BV˜ñI§ë†¾xÀfHÏqàÛw/çï^%cÁ8`–Y(bOud)ú O¨&y¢álD ×Tˆc÷Âà)†Ì‰HÉ´ õ0QÉÓÁù âþ“I‘r5Æ|Äï4K‹0ANEÞóTS_Q-ëÁ'ï Ñþ´ôŸõnx’»¢ÂK2œvE”'0«
-‚ÕrœÀ4d‹VM}­°¢Æ¾ÌáK‰ÿù{éã×àÚDÊÚ‰o|b‰amfÊ¡Ÿ~ËÄ_VŸòþ_dsÈkendstream
+‚ÕrœÀ4d‹VM}­°¢Æ¾ÌáK‰ÿù{éã×àÚDÊÚ‰o|b‰amfÊ¡Ÿ~ËÄ_VŸòþ_dúÈnendstream
endobj
-1902 0 obj <<
+2366 0 obj <<
/Type /Page
-/Contents 1903 0 R
-/Resources 1901 0 R
+/Contents 2367 0 R
+/Resources 2365 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1747 0 R
+/Parent 2371 0 R
>> endobj
-1904 0 obj <<
-/D [1902 0 R /XYZ 56.6929 794.5015 null]
+2368 0 obj <<
+/D [2366 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1905 0 obj <<
-/D [1902 0 R /XYZ 56.6929 752.1413 null]
+2369 0 obj <<
+/D [2366 0 R /XYZ 56.6929 752.1413 null]
>> endobj
-1906 0 obj <<
-/D [1902 0 R /XYZ 56.6929 501.191 null]
+2370 0 obj <<
+/D [2366 0 R /XYZ 56.6929 501.191 null]
>> endobj
-1901 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F48 953 0 R /F53 1029 0 R /F11 1397 0 R >>
+2365 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F48 1228 0 R /F53 1303 0 R /F11 1442 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1909 0 obj <<
+2374 0 obj <<
/Length 3111
/Filter /FlateDecode
>>
@@ -9199,26 +11276,26 @@ X&dÜ‘Lr­2KU=Æ
Í©ßpª'uÆ©Vª³nuÞ©ç”{NjŸpª¯ÞdÁRÇÄ£X0<Š…¦hï©dЇ…ëúÅèæžà¨j•·9=ÿá×CɃ”Õ`ÀóP‡|èÆ&ô²Ol¦²öÅÛþ:sày]|Y¦pªÇ#mÈ—ò!¿“š{ oÊ+’Ââ«Û‘ê½{}ø¢«F#F£âÓªy³„ÒK¾)WL˜!=Ë¢$Œpp‰"Ö/—|wJ¡-ªIôä¹@òûŒÀe³]½¹‚d|yôg•u³b¯¥‘¹ 
ÖïIMeµÂÇÓ¢±]Ìm¯ï#ÞåxoÖ“ÍüÉ‚qÞ|³Î³o=†hI9üRX‡‚÷à¬)ö@å—Û¾®Í¿|]PÅ>¯žð 9Rf¶‚ãÙÒOV»ç¨Ûå{Öc¼¨%{
¾U¯ycGôsd*ö6Åe%ÎK“ƒ÷¦€}žb|©iŠqRŽb–ç)æ¬òŽbN´SLO½¡ؘœªevM3Ƀ%ò6>ÜÐ/RÌr],Ÿik@ͪlðD¸â?2€Ã2X0aÒ¥Ç2 ŸX›ú,fa×Ë=äãPõVæšôqóùîîã‡Þr»býØK,ébh
-p2£·RKOhV¨ÃÁfòÞöœÖîÚv¨vüÖÖ×{C¸Sù:¿ñÞ2¿\ßÝÙ;ò¢ò^F]Þîdû\5éVˆõ*|ãY¥“™v*Ët7½-,ö‰[!wÉ$
+p2£·RKOhV¨ÃÁfòÞöœÖîÚv¨vüÖÖ×{C¸Sù:¿ñÞ2¿\ßÝÙ;ò¢ò^F]Þîdû\5éVˆõ*|ãY¥“™v*Ët7½-,ö‰[!wÉ$
endobj
-1908 0 obj <<
+2373 0 obj <<
/Type /Page
-/Contents 1909 0 R
-/Resources 1907 0 R
+/Contents 2374 0 R
+/Resources 2372 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1912 0 R
+/Parent 2371 0 R
>> endobj
-1910 0 obj <<
-/D [1908 0 R /XYZ 85.0394 794.5015 null]
+2375 0 obj <<
+/D [2373 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1911 0 obj <<
-/D [1908 0 R /XYZ 85.0394 679.319 null]
+2376 0 obj <<
+/D [2373 0 R /XYZ 85.0394 679.319 null]
>> endobj
-1907 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F41 939 0 R /F21 714 0 R /F48 953 0 R /F53 1029 0 R >>
+2372 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F41 1208 0 R /F21 930 0 R /F48 1228 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1915 0 obj <<
+2379 0 obj <<
/Length 2837
/Filter /FlateDecode
>>
@@ -9236,119 +11313,112 @@ arFáàJ6ò±´Ð‚c9<™‘m›î} Œåºn0ÝzE½ÂA¨=Ÿ‘Ð Hãœ/çˆÇVt°RÈ=UA‚©Z€Æ-Ä»`>cÝ{ÿ
^f¢óá^žÜ¥›õl(š˜9{™a–f9]Ü&QÎÖ¶I<åLø‡ùtgÚ(0v{$W©Ã´:ÇÃÓæx@  8ùø`zÍ|º© cZFhûß ©Ó†Óª\€ ¯Å&åtsÈÖ¨]-¯3ZÈYZÐŒÇé±×v‹ÞwgÍmïšÆ¸‚ @Æ4ªåL£cßÃtÂÅôzÝ·Zö5í¶kžz/rz!‘†Tžä¨ÆDjbo¿îI[ìOšò_ñ¤P€°†Ž´2nk%GY¢©[ÙÇ!Êm²çÿBÖí•(¿`€jÃŽjÌ1°åìWsÌ&ï1Ç̘/瘈»MÇ4÷ÉšÎÉU{ðuzÑj…FP÷(úóT«¨û¡Þ÷V§9L… ¨~ÚÉÇ'S‚BãPVòµÚŒâ‘®¯JÏ`}Oã`œøؼL¼¸·æîÚMtÜK¨^j·Íý#)3¨‡Æ¥¯"ˆŠ,eŒ\È!Õ:‚<•GÐ÷Ó”o‘§œ^`kiæ\'U1…ê¶ÀÛ›Q#_*«%“½ºîÖõå¶õÄ5{pBk¥wqõ÷z}2÷qÌ}ãtÒ,ÅPåo[b$Ú0„%í 2˜òžµÈºÅ{ ¬SæËq5äîÌ¡*mW™ø}Š2‡ ãN‹ªßz¹_ÌN†êÐPj]CÓ¾Â<¥¥õ…#´µ%„ÛþçSk
Vh§[/Vþër5^Ãf?¾8l•Qh_2¯@èB¦ ©Öáà©<Æ2-¾ë àH‚n3÷Tsî“ÐnI`Û±¦Ó¹‡Úl{·± ˆ´êr9 ¶öã§Ý(Ï׆,(»rCª Ã8ªÑ0ö¬w¾›`(¥Y·ù{ª¹
gÚGXûkŸÌÛGSQ¤Í'цÑpAR$.ĺ€hÝdŽh´XÓ¬Îm±Ïæ¦|—æBÆŸ¤1®lÛ7²´M%Ï<Þ|Eˆ–ëUê
-éVìÍ)OHjŽ}>«CŸ¦þ¶tê ž€Òœ4>¦5qféø™«ÿß8Oð˜th«:9Ýü×í¾9WÓÃE}ç þýjåwÀWý[nhçœëÿþSÞø—C–AÆÌÉ2žHÆSøX8¡”&
+éVìÍ)OHjŽ}>«CŸ¦þ¶tê ž€Òœ4>¦5qféø™«ÿß8Oð˜th«:9Ýü×í¾9WÓÃE}ç þýjåwÀWý[nhçœëÿþSÞø—C–AÆÌÉ2žHÆSøX8¡”& Ï¥„BÚËþ'ƒþ‡endstream
endobj
-1914 0 obj <<
+2378 0 obj <<
/Type /Page
-/Contents 1915 0 R
-/Resources 1913 0 R
+/Contents 2379 0 R
+/Resources 2377 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1912 0 R
+/Parent 2371 0 R
>> endobj
-1916 0 obj <<
-/D [1914 0 R /XYZ 56.6929 794.5015 null]
+2380 0 obj <<
+/D [2378 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1913 0 obj <<
-/Font << /F37 802 0 R /F48 953 0 R /F22 737 0 R /F21 714 0 R /F53 1029 0 R >>
+2377 0 obj <<
+/Font << /F37 1018 0 R /F48 1228 0 R /F22 953 0 R /F21 930 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1919 0 obj <<
-/Length 3266
-/Filter /FlateDecode
->>
-stream
-xÚ­]sÛ6òÝ¿B3}¡§‚O~<äÁ©ÝœÛ4Ik§w7m(‰²9¥HU¤œº¿þv±
-9ùýâç_ùl|{Á™ÊR3û ÎD–ÉÙæBÅŒVʯTw?„½·vë”
-%Ys1ëãQPcÒRöH •°T‹#ÚwEw9W*‰ºÇ‚õ~³(v8Ž£fMkÈŸË݆ÇüÉíèzæÛmq)¢|GӲƽúƨ’g,NµÞ‘|o
-‚ð*&ãX8 À?F$$ãZ9ˆë S
-I
-`â¨nH*É@‰àèNdçŽU™Ë*œÆq‹+¥{³…eo¡Ž´ðì\k½p ŸËîG:ZŸQqÑãÖ¨Xx;mÝ»-­t(J áÑr•wåSAoꕼvП˪¢¥…UBÄàjÛ‚(.-~pWVp
->ý¼Kö ¡Ô²> z˜°‘0­´‡°²ÝŸv® :…âæîAÑitz—Õ¸:„ÔQ%ñyÒjLû(QïdCÚ×X$i(EšŽ:¥öÚWÅî][ìžlݨ]Ù
-›e⛜w7?^ýôÍe¢£«ÛwŒ–ï=úCQHl%¥]í6Á–/ž
-W
-¡»-–£ë4*™ž' ÆÔ‡× iM’h1$ÿcÉG‹w$ j†€wó5GÁKPYmŸ­mØ•g¿âr%œX8Føá;·£t[á†_€ÿÍ12Š,>ìþðñ~ŠºsmÀ­¥G½›QŸ¯Ve©K°m,8šzQz‰¥ü'AehR.Ï+Bê´"¨ mù°|ÌÛ‰LG²pœ¥îÆÔ‡Š
-+±·Ù–•5´Æàh~=ÑÖ©d:SzpÒ—ZÂ’eišN7„çã bÑp+
-†±<#úsêT}ÿéV¥÷·ßÝš>Ýüx{s7á}Á+ʘ)‘¾xJ(²ßܾG†ue´Pn¶•ýò—»¬YÛ
-ÿt>Å5#¸öüYŽìúô÷>ô¾†û:Ÿút&4Ë’ÌËf‘w˜• L.E„§Äi³E.° Â/©‰pù ·ßí¤{´ÍB\
-2Áõeî¸_î«Ò~‘†Uò0¸n‹ñsí íˆ HÄŒcÀxUùCû•K{,«­·†Õ¨‘í
-xƒ~iG`°ºßVn¼´Jƒ
-!4]§ãmÛ¡éI _ôtf¤’\ždŽ;?õK1UºšüÐÃCˆüÇ¿";üFNC€_Þ'óðžLáïÇS(vÁÍ1ëcc*“ Þÿ:ÇÀTendstream
-endobj
-1918 0 obj <<
+2383 0 obj <<
+/Length 3255
+/Filter /FlateDecode
+>>
+stream
+xÚ­Z[sÛ6~÷¯Ð̾ÐÓ
+!®òàÔNÖmš¤±ÓíNÛJ¢,N)RI»î¯ßsp)Rr§Ýx2ÀCœà;WˆÎbø£3-IÌS1KRAdLål¹½ˆgðîÝu4sO4ïS½¹¿xõ–'³”¤Š©Ùýº7—&±Ötv¿ú9ºúôéæÃõíO—s&ãè ¹œË8Ž¾¿úðåê½ût™²èêÝÍt•ŒQ$Sqt}ûîò×ûo/nîƒ0}iÌQ’ß/~þ5ž­@îo/bÂS-gOЉ MS6Û^ɉœû‘òâîâ‡0aï­ùtj„ÔD2¡fs ¦\&ÓÛ“X²牠„+©Ã6 =µMž
+·é«jU·ÍëëãåRΈV1õçqTcÖŒõXSž-èﻼ½œsžDí&·ªÛ.ò=¶UT¯íÊçÉ2÷Á&{t_´µ}f»]~I£lo»E… zõVòž,N‰Ò‚ìȾʶ¹¥ÈÊ”¢ŽæOD‰w×s¤„s&ÁºöBµ}™U´pkXÖUS¬`ÝTGùÊ­gÑÔe×ægŸÍ™V„1Š[NI*%33ß›}“°Gù:ëÊÖv³²sãEcŸnç å/qÌ*ú]SÀ®UžÌ}W¹M‡fÓfm¾Í+÷½ßXAû[¦a€-·àWy»|µÏaÖ¶žÚ I” ~ ¿†¹µˆÌ>êX!
+Ø>,Y³³8-Ÿ/)¥Šœ&ÑB ¹õ\»-ù€µŽ£}ûG /è ›vÝU«|5eºU ¯û«úÉé48<ûín_€…îÉEã¡\ø9`aïmAæføÓzœÚöœA‚Ö2맙}à©ÛÖï]¾v¹ŽÖšÕSºÆ(¡B½¤k=ª3ºæ©Œ®å«ªyý¯‘¢1E
+ƒnñ±jžDÐŒ(T°³(èSFA 
+(XgE9®h<,užu ó>Šf9D½é÷5¦ÊÒºµÝΆ™Wùî]“ïMõ@¸äžÏugéÝ6æ&×À7™}ÜÝ|¾”2úñíe"¢«Û÷Äßûé©5Lbòiá2ø ±|
+ ¤F,¸Âº>4^TymŠ¥H1íðЩåCÓR¡½-=šºEŸs#?ù"ßd€Vw:"&B‹s :Gp³È!]ƒ¢µ#ô$œ?Ï=Ø™KSÙ‘þWm›ow¨´Êz
+¦@“‹fWfÏnÐl34 ‘lÑéX³Ç0êÒ¥Æöü1)Ú‹É*+ÑŽä+ƒç±ðÅÁh@§hœ„”k9´>”2p2a~:·Íàáäaò²ì2¬³§Ù§:}œ*œ'„nM¾<é Î2?xƒ÷io0`ÿ9‡à³Á3¢©Œ à»»ùƶGÁ µeólL1ÈŒ<û+cÇ@àxÂß¹/
+÷):šëÖÅPS
+bXœç¨Æì%‰¤Éÿljnw2W5 éÁ™Á‹cgF½3³m—»ÚNf?‡Í]y˜šb±ÊZS
+“Ã >pú
+¹9%:–G˜ý{£XëÓfœ0moµÿÆüŒóþ”­–‚Éç¿„1šr+¥Ïc¬Ouc*` ¯uO&ÍgY’æïɤyÀû¶Z–Ýʇ•Õq‰ÔÜ{»ó…Þ^÷SHjûô4¯B…÷PŸÈ&ãP㠌ր- Š¾zÎñÛâÿû/ï1½¿ýôþÆÎòכϷ7wÆŒ"xyÁir¸ñf^¿¹ý€‹4Jí@±Ý•ææ7sQ³0—@c§…[+£/Ößhê½VÓívÁ6–Scëþv'€‹)…îJ'nHaT ¨ì õ0€ÕM[î:²ÕSla~Q8¡1pÞ¡TS~”-šõñ˜Û2D,¼|F"3>}ßSÀsì]ê|êê”
+’&©ß›EÖbT‚,0¸¤®»õ¥À„oÒêâdn~·$íÆ‹q(ì Ž/3'ý"?H_æ 0j- Ž›ÀÅÌøT9JóƒËÃnU$F‡?0] +Ïš¯]ØcDmŽJm½‹ G0á¡pîïò µ„ gæÊ–šÇw ‰$2öA‘å3qJ¬ýFÛ‚ÂCç~¹
+endobj
+2382 0 obj <<
/Type /Page
-/Contents 1919 0 R
-/Resources 1917 0 R
+/Contents 2383 0 R
+/Resources 2381 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1912 0 R
+/Parent 2371 0 R
>> endobj
-1920 0 obj <<
-/D [1918 0 R /XYZ 85.0394 794.5015 null]
+2384 0 obj <<
+/D [2382 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1921 0 obj <<
-/D [1918 0 R /XYZ 85.0394 179.5067 null]
+2385 0 obj <<
+/D [2382 0 R /XYZ 85.0394 147.4749 null]
>> endobj
-1917 0 obj <<
-/Font << /F37 802 0 R /F48 953 0 R /F22 737 0 R /F53 1029 0 R /F41 939 0 R /F21 714 0 R >>
+2381 0 obj <<
+/Font << /F37 1018 0 R /F48 1228 0 R /F22 953 0 R /F53 1303 0 R /F41 1208 0 R /F21 930 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1924 0 obj <<
-/Length 1913
+2388 0 obj <<
+/Length 2054
/Filter /FlateDecode
>>
stream
-xÚ¥X[sÛº~ׯÐCgJ͉`Üx;oJlçøLŽãFÊ´Ç4 YœP„BRVÔNÿ{X¦$jt:=
-?6öÄ<‡±$>eþ8]èøæ>Ž˜[3mMû«Þ/FW·"Ç$x0^,{º"B£ˆÙ£÷žp2 Ôûíó|1™r?àÔ›=<ÜÜ_ßýÃŒ)¬”zÌî¿Î>¡ìasoöñf>yZü>ºYtÖô-fTS~ŒŸè8ÃQ"âÈï`@ ‹c>^¤/ˆ/…h%Åh>ú[§°7kÿ:ˆ
-©^¯“2Ci‘—
- 4òfå¼ú9)pþÇVUN¬7M®ËåߨOÕÏTmœ4Úµ«[Éz¶ñ(&”q<2VýòXê§táÊC/ÀY?n!n{0grâœxv>èWUUy–©ÒèO…ˆ ¢h<eŒÄ¾Ï­šç=6ÁÆú2­7*Í¿QÊS”ÖªÁŽ^ö–9ºl
-ÑJwñCÈTU&&“"ÿV—éu’»‹ºLÖª½¿¯Þn6ºjÞáÈFÚîVOÒ¶¼®2ÉòzS${”–ºœºø*#ÿðÈÌæîîÌñ‚rkDMb¨²æVq@Ûü&ÂË 26iT±ÇíR]÷75n˜®’*IœTeª³¼|Á‘½ ,Dé³Zb2ºq­JûW$
-N 놇Imø!ˆ]*Ã9©Ø{5ˆ¼k›ì ¨Uõjl2}íZ/¼èÛÍ°w§Ýö r§î^‚÷áÝ'özû× ¹½Ø;“ ÝV%.4@íò@kìÒ̘Œcݧ‡n#ír×.49©uin
-Þ)˹ªÆ•ÃÕ)ƒ*€†]ujö>*ü9…ãûñØç>
-‰}¨¤ŽØ¶Ý y-¯
-mËã÷ ÔdŒ_ä/)d±jyÛ²>Cµ€ •!R-ãØþåöî¾ïNëö½^©&½ªT­‹W'|Ù¦!à ²+þòïß>ÿqóŸ+vVéôpãùÍ z?û4ÿ|‘ßWºn Ó2áïð†+2#Œz¬¬k•N¿«ý‹*{“v÷¡  “v_n?ÀSÖ* "úݺap9¨ÏÞ®±÷_?Î/º9×rœ}—õŽ^Ÿ!qÜë«Ñ;kûF:÷6ëìSdÐaxew&ðn2¸¶Á?ááìÛ÷†‡Ï=§B&ã.*¸ù7ÎCì]·E[÷›þ¶É‹¼ÙŸO Äl¾/õ¦†óqD;‚‘0‚ÇpAE•ÇÀçFrß\NÃßÀh§²§á”cº/nÑ›‹æ‰ù8M>dEYÕ‹ÝëS+J‡
-Maž²½LÓ"©ëÁW ±´hu
-ï
-ŸDß&`™é款0>Vøå²ÂíúY >¹dÇ›‹›ýfðë‡ 1£òXßß/êÛ%ysVŸèôáƒ,‚·‚Ãø8]ìrhвH^†v‘D†Ñ
-²ë®‡µ‹•a1ðtî»xg>v d*íŽÆÿýMíí“¡4Enć?—ñÐ'ðç 5Ê8ÉhpbzûõíÔöÿB"endstream
-endobj
-1923 0 obj <<
+xÚ¥XKsÛ8¾ûWè°UK×D0^|ÍMŽíŒ§2Ž7rjwËñ&!‹ŠTDÊŠvkþût£Z²¨r¶¶x Ðh6ýøºA1âðˆQ±(•é(N5 ¹Gùâ„ž`íÉp<cÏ4Þå:¿;9»Rñ(ei$£ÑÝlGVÂx’ˆÑ]qœ3ÉNA~û4½;Ë0’<˜ÜÞ^Þ\\ÿ çx€ƒóàÉÍ—ÉG¢Ýž¦2˜|¸œž>Üý~ry×k³«±à
+Uù~rÿÀG(þû g*MÂÑ&œ‰4•£Å‰ µRžRLOþÑ ÜYµŸZ@p&U$L å ”EJ*k‚ œHEÁSÕ<fŽã 5›½¿¯ÍjëHË®lêöÎÒ`3/ó¹ûhÞ¬«‚˜ ½³å²*MA ]ãˆUõ"µ4^TžÕ~½mè /¦]“p„âap77­!§58,1‚¥a(í±œÊŠ ¯2Nd°X·‘—«S‘&7…¡¥nnhå+çrEl@]/+GGs ©Î´VBy•µ­wÛ%‘Ã+áÈSÙ“ŸeuAbŽ©ÇÉÛRë A[éTFBÞ,V0R«²6ÖVI0©·ÄÐûÖ½;Qßé_yÈÍÜ,;ZDé ÇÙ•;Q$“”q!CPµúå¾nòEAœûñaFÊ1ÒV°‡p*gîî ͳY­Ê¢0µ=ýX©”É(I¼(e·”‚½ìYÆíÒä%º-'*E0 l{6G¢#£®š‘ÍlžþuàÄàˆ„2¦(ŸNÇ Â/ßW4Øl6¬lsÖ¬ÜJ†fÇÁø½…Œ‡GÐtÍoÅÕ <4c¿=…$Úë
+
+ÕîN ïa`0t¥€P½Î$ÌU4¹´kˆÚͳn ˜ɤ?Α`N<Ë’ihPÖeWړäÇ] wô^d…ã$_ÁÀdXÙpDÎKêDcñAjl‹D½/ÒSD!H—ûq8Ï0e•|UMNÕö%â•îMnÇC&ö¨Q†’LŠ— ñ5’ÒdµÓ㘹!¢ÞÂHÏÈ‹/+wºéh°\•uç·14è=ðêÈ›¹±VÖdšæ›SRÎÚTꘅ±ŠömJ²º1›ð}MHF+­¹üŸ³É[¬×c:IÍd‚ÈÜ)©å½¾¸!¦_no?}> ¡qwÀ‘: új6à”” ù6ž«$õ.§hÓЈ
+
+úî¤(Ûe•m‰Z7õØù8bÐdžû.žLß__cŠ©^ ߀µlÀR‚\@ä¼e«4â>ƨÀAÔf©¶´]ÞÔ€ÿkÉòy¶Êr0-š:oŠ²~¢µ…‡õÑÌ( ݼ5µý”ÀBrDÞxÿÔˆQêÂr[Q$ØÚ%Á… x ´fõŒ:á¸qog^PDODÚ“·Äât§®£l›L ÜÉ„ú˨&^ÏhaÛ¬ÿ^sUÚâÞ«ïõª&6°ˆíIM]˜¡Ê1ûý-‚^) $XãAq •³¶©±ZÀ-¡0wMKœÃª€N€Ç}‡Š{¿º¦I)›†)´¨ÓØØýÄEM²4ntðš6î%ŽwEÚ;Ø~瀞‰Ž_vF/®§“ó—C
+q‚Ž:#ª3(8& ¡›z…¸~'¶²}Õl[,¨)З ù&~i¥½ÇV§I°®Û#p ä:öpKš]]¤Ëøaë¾ ¯g¦ËÏV¦mªg>ëÿ Wüí¿¿}úãòÏ3Š®ò! øÞÎÓËK:ýäãôÓÛ
+$&;Ä¢n[“¿™í“©wí lÇv4bº7Þç«÷‚«p¨/HXö|ÃÖ•€ :M÷ŽxþåÃôí“AÜyœ³÷³Ý‰ƒØGw 뚆 {W:vGëUÔLé¨7?D€Gs&O!&àþ„¦õUp¿Q©¶7ˆÅÇ®UQ$’Þ1´ùW)c]øÎÂ÷ÿ8^weUvÛŸˆŒmÝ,[È’Wà»Æ D[œ@o¼¿t0eˆ%jø‹…€ÜÜ‘pˆ4ýßÇôrH¼lÞ³÷EU¯Ú»Íóƒ'åC-§ÂËö%Õþð¼Ÿ0 Ž–©x3 P…,‰B…uÑtGåÅékŸß¸^<šÁ‹cĤÔâµÄîM‰ø_gHCwr®_Ëûç›ò6YÙ•§zyt5KÁÑë¶è~¼Øe_¡Y•= í¢™Ž“+è~¹u0–F-Áñp:üA9©¼OŽÿû?èËo^­n"‡qÊ8dðqä•ÂC
+¨îÿ˜êþŽâšendstream
+endobj
+2387 0 obj <<
/Type /Page
-/Contents 1924 0 R
-/Resources 1922 0 R
+/Contents 2388 0 R
+/Resources 2386 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1912 0 R
+/Parent 2371 0 R
>> endobj
-1925 0 obj <<
-/D [1923 0 R /XYZ 56.6929 794.5015 null]
+2389 0 obj <<
+/D [2387 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1926 0 obj <<
-/D [1923 0 R /XYZ 56.6929 581.7741 null]
+2390 0 obj <<
+/D [2387 0 R /XYZ 56.6929 562.0317 null]
>> endobj
-1927 0 obj <<
-/D [1923 0 R /XYZ 56.6929 460.6765 null]
+2391 0 obj <<
+/D [2387 0 R /XYZ 56.6929 444.3852 null]
>> endobj
-1928 0 obj <<
-/D [1923 0 R /XYZ 56.6929 366.7195 null]
+2392 0 obj <<
+/D [2387 0 R /XYZ 56.6929 354.5963 null]
>> endobj
-1929 0 obj <<
-/D [1923 0 R /XYZ 56.6929 293.4426 null]
+2393 0 obj <<
+/D [2387 0 R /XYZ 56.6929 284.7704 null]
>> endobj
-658 0 obj <<
-/D [1923 0 R /XYZ 56.6929 247.3727 null]
+842 0 obj <<
+/D [2387 0 R /XYZ 56.6929 241.0985 null]
>> endobj
-1930 0 obj <<
-/D [1923 0 R /XYZ 56.6929 211.2315 null]
+2394 0 obj <<
+/D [2387 0 R /XYZ 56.6929 206.0104 null]
>> endobj
-1931 0 obj <<
-/D [1923 0 R /XYZ 56.6929 172.539 null]
+2395 0 obj <<
+/D [2387 0 R /XYZ 56.6929 168.371 null]
>> endobj
-1932 0 obj <<
-/D [1923 0 R /XYZ 56.6929 96.3402 null]
+2396 0 obj <<
+/D [2387 0 R /XYZ 56.6929 95.6233 null]
>> endobj
-1922 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F41 939 0 R /F21 714 0 R /F53 1029 0 R /F39 899 0 R >>
+2386 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F41 1208 0 R /F21 930 0 R /F53 1303 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1935 0 obj <<
+2399 0 obj <<
/Length 4190
/Filter /FlateDecode
>>
@@ -9373,1103 +11443,1652 @@ p˺ëæ‚[À‘ r8ô >ð >­EðI‡<ãt
ì`WAŠõÉóõ82ÒþÀ˜Ï9Ì7ÏÜÌÞ¶óMŒŒ® N“:å“ÄÔgÚ_ó€Íu2±@0°_¹šT‡ÉÙ’›ê’o:æ¤ËHÐŒoi!Ž,«ë4¸«Tz²ézVÿ–N{ÖJf†Nb‡÷ûW³¦nòD&3çMg,Âù²×/‹op…}ŽRcpõ7+z›@
‰PÍ}n@© rüƒva¢ ±}qM›ï9îîþ@™3}]}9O!£…ìX"B¾gøzPТZ†C1ÿ8ú|ãOù7›úyü]Wï
DrÐYúûé8ÆEôȵî9'ÝȇH¥ã$5öäq2U*tìJ, ÕÔ>çÎh¾P@N WNœq‚Gbˆ¦š³CÔUK–iC'vbÂ×<Ítþ”¨È¤q8`ûùÄ9‹íÎY&ñUfÂ0ϧ†!»³{i' k’fŸAÛ‘ÖñÉ¿T‚“L?óVÜHi‹ðæäÊŸ¤‹t˜™„Ã{ì=mtÀNr§”¯rŠ—$Ùtõ)Ñ’u×*?gT2ez¶aóäjkA3;ê•Pݺ\©ú‰ÌÃ4¿¦kn ÿÉgêù.—Ö'ë¡I¤cm?%%˜EE‰µ£"]x•r(`Nß겑LSs>ÛSbxW/V¨6+*gS8`¼jÚÔG¸UáúäôÜé*ß,ˆeÆZXë¡E„ã¡Óv;ÐþÆSi8¤KÝÆ8Ù‰ⵑ¸ú”ú“EE@zp~ü„q\ó5
-¾NQü­ñ—ÿ(·‡-_às¤þ*o‡Q¶ýô`“«¶»€qâ§ÏÍôÔDømÂ_þ™D÷+Ø
-Æendstream
+¾NQü­ñ—ÿ(·‡-_às¤þ*o‡Q¶ýô`“«¶»€qâ§ÏÍôÔDømÂ_þ™D÷+Ø
+Éendstream
endobj
-1934 0 obj <<
+2398 0 obj <<
/Type /Page
-/Contents 1935 0 R
-/Resources 1933 0 R
+/Contents 2399 0 R
+/Resources 2397 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1912 0 R
+/Parent 2371 0 R
>> endobj
-1936 0 obj <<
-/D [1934 0 R /XYZ 85.0394 794.5015 null]
+2400 0 obj <<
+/D [2398 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1937 0 obj <<
-/D [1934 0 R /XYZ 85.0394 751.6872 null]
+2401 0 obj <<
+/D [2398 0 R /XYZ 85.0394 751.6872 null]
>> endobj
-1933 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F53 1029 0 R /F41 939 0 R >>
+2397 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F53 1303 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1940 0 obj <<
-/Length 1972
+2404 0 obj <<
+/Length 2028
/Filter /FlateDecode
>>
stream
-xÚ½XKsÛ8¾ëWè6RÕÁƒ £ËYÍdl¯¥líV&Z„$ÖP¤†¤œñüúm
-Ù/veÝ&&ûš)’,tb‹²ñ©ŽãØò4¥Q[«"µÀžÚÁŸGU½XZ9X““BýÕR‘ìU­ªgU™y¶1ï¤xq’O‹Õ”ˆ‰ªe‘Ö†ò-kvömë8 T"΄€A’sÚš¹œ?N9Ÿüëv‡“ÙÂfÒI\­~6¤o»l½3ì6ïÖè;S[B¹1öInÆus|H/óÖ|MyR»ä9++mjÍÅ`¦@àYz%ˆD$Š»|Øû‚¢0ä.pë¤p
-ÍûX«Ôn¦´fªælw{µ/u¼ ²µäT=·Û¬Øšéï³dkŒ³~î°r2r‰Q©uY¥SG"âܲýì‘B¦fŒ)1±¸Ëç¤H=‚ÀqŒÇNRS%kŸ$H!œëPW:]úlÆ“ E„@¹Ã&C†Mõ.nîŒS–ŸîÛ[yäCŒ)‡6¸ØxªS@MaqQœC; $6#Ž)ÑéIbˆ±Òц\{:fycˆ¦,4Ñ ¤ß1ÇYѨªH4Z$yöw›°”–û$³Bt=+1+õñp(«F '™•nò ˜“õZ,Q‡ÀHËêCž¼Xqe˜Âd
-õ§ŽÂ»m“ pFÒ"àdÝB[‘Ї£!8ðÓãÒ¾­Á2ÙÒ@Þ¡Ý!L7fÛ{+»-ô¨ÔƒÅ:#Û…—òøSj˜óìÕ7 ÞǪ0là »H•6Ï´É&e:xëE[û)`\Tjç1J­ÉI]cŒÁî û0-Tm8?"BÍâ˜:ѺÏzŠCD%—ãXád–ßÓ P}D
-/tƒ¾Èö ?;½cDá„<iÖ&Þ,–³÷Ÿæžd 9ÂaHíVTñœ™°{U4Æ Ï dîS®t3e¸ÚYçµ>oýi}ÞN²Ú¬BžèRKݪu(FrhD¢ab:Mð;,¾í
-eþ=Þ{)ÊCÕç%È‚šÁê€ø/°$)×'´¿·ÖBŠöE\Vœk­;®3gXGDàë/Á³¯O º–®QÈ¡ÇË}}¹nº þê$’nD»QâÑ¢ë-ìúš$ßú€MÀGC`ý&ËÕ«þÅ.XšðoOÄÿ:®×ý —•k~ÒÕðnÿw/ ÖqÃnu'uýý™‘¾)0°÷ÚG% ;q¦…P‚CÀ†0'lÂ(…Fú aµÞÌ—«ÅýÉÏ‘ÎMg$8‚s]iylǶ§¢Üö4šÜ¨\m°ÀÂ2ÛmWc š7KÛq¯»5ÛÁZ.C]›>+=}ùøè@>M¬^×BX¾¶cƒåÇÛ†À".ÌÈ^ÆÛÅ ]1
-n1{wïäøħ6É1oήéew×µ—ß²Ù]ê,Òò¨ •7
-endobj
-1939 0 obj <<
+xÚµËrÛ8ò®¯Ðm¥ª!‚A‚G%–³šÉØ^SÙÚ­L´I¬¡H I9ãýúm<H‘,';µ¥ƒ€F³»Ñï™bø‘)PÑhF>â˜ðéæ0ÁÓœ}œ‹ãµH^ëýzòî–…ÓE ¦ëm–@X2]§_fïCs €g7wq¼üàÝÄ·÷¿þ²ü÷Ü#¡ÀÑlñð°¼»YýkîQŽ°1žýº¸û¼ød`óˆÎ—ñüëúçÉrÝIÖ—ž`¦Äúcòå+ž¦p‰Ÿ'±Hðé7Ø`D¢ˆNŸ3Ä}ÆZH>‰'ÿèöNõ§NmŒ( ¨C”ºÔÁ#0Ê´:Ö{©.ñîÖ'=T
+}?ú
+Ç« Ê€áˆS*,Jyl²²˜{Œ‹Y#ó¼ý¢O® Ø/öeÝ$õ9S1¿%[”‹u€„†§) ÛZ©
+š¥WüDˆaç—Q|äû¼5Ü&)Z†æÿTËÔ^¦´bÊft»ƒ<”Ê^?ÙYp*ŸN»]VìÌö7ŒY²³ÆYßwX>´ŽQÉMY¥QG"àÜ¢ýä äƒ§fŒ(2±°óç¤H„@qŒ‡-¥¦J6.Jà0B´ªC]ètî³z,b( Â.é3l¢wusg”~x¸×¶vÐS;lRàjëˆN1…ÅEpå$àØŒ´H‰rO‚¥²6øÚÓ)Ë4a¡€FH
+È¡'‚1Š|ö–¦(ÂA—¢’ãQ‡by¬²Òã‹á±) ̦¶»}îÑèH…­,6ejœv:Î"šÕ“Ü–&ÖÍ^¥Bõ©MG aEÁ^Ûø@˜Ad3äɺ1
+òÌY‰x³Šï?-Îês„}ŸÚ«Èâ93f+²hŒžðܧ\ªfÂp½·ÊÓ:×ú´:×›¬6§à'ê£ÔB·j
+†‰84"ÁÐ1[NÃ
+Ø‹o{È5Žì- ¡o§/Á»*VÍÅìTÔît ™ù!‡éövõÉô|#…òë;ÙlÞUºî"ˆñ­‹RŽ—Ks¿Å§øþí žf;•L‰J“¶mPÙ U@¡€½[ùˆùAËÓ§ˆ ÆÛNZ^ ½mZÔµÜxi½­ÊÃïò¥(”AÈ}§²[0Ð}$Œ\gB&ð1Sµ) ÍÊ´Ýv›ÿÇGó¿“…¬ÓJš^¡Ì¿G{/Ey¬³z‚Œ (Ð þ!ˆ{˜€£ˆrU¡Ý½µú\´Oâ2âÚÖºÃ)Ã*"
+9ôx¹«/WBçÁ_[Š¤[Ñn•8¸¨xó»¾&Éw®Ä&`„ÀÁ˜Eî 7ì£liº¤8D³AÛ,—¯Z ÙÀØÁb=W,Öb½n1~PÏ3˜È:;ý¢y[Ñt¶ê”/‰rZyNþßÖûâÕÝjã ­&,„9ó‡¹}“'uýýn½}SêÖ…Æô`ÒTã÷ˆÞâëµ 8
+9ãÿK‚ßçô8¬$TMç„Œ*ÉÍ2þð¸zX¯îïÕlœíéy”†G&$ô0~jŽ'ÝVRnÛ#Ìnd.wmn…ƒ8Ûº±ƒµª7±mº·Oz±‘Ë@7¦ÕLÏ_>>¶u>M,߶‹²xºi…ãÇÛÀ.ÌÊNNSÏ^bа|(>Ç‘-uº‰LŽ»ìYÚ’úQ2Õ£*øjí¸×F¸|ɱi„0¸"ºžkúXæáÅ•k:,=D“1Ë
+ ='ùIœrë¬É!
+ê¼áø55D$¤m¥=œZÞO–UYœé
+endobj
+2403 0 obj <<
/Type /Page
-/Contents 1940 0 R
-/Resources 1938 0 R
+/Contents 2404 0 R
+/Resources 2402 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1912 0 R
+/Parent 2414 0 R
>> endobj
-1941 0 obj <<
-/D [1939 0 R /XYZ 56.6929 794.5015 null]
+2405 0 obj <<
+/D [2403 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1942 0 obj <<
-/D [1939 0 R /XYZ 56.6929 684.0716 null]
+2406 0 obj <<
+/D [2403 0 R /XYZ 56.6929 684.0716 null]
>> endobj
-1943 0 obj <<
-/D [1939 0 R /XYZ 56.6929 572.8605 null]
+2407 0 obj <<
+/D [2403 0 R /XYZ 56.6929 572.8605 null]
>> endobj
-1944 0 obj <<
-/D [1939 0 R /XYZ 56.6929 509.4701 null]
+2408 0 obj <<
+/D [2403 0 R /XYZ 56.6929 509.4701 null]
>> endobj
-662 0 obj <<
-/D [1939 0 R /XYZ 56.6929 470.2699 null]
+846 0 obj <<
+/D [2403 0 R /XYZ 56.6929 470.2699 null]
>> endobj
-1945 0 obj <<
-/D [1939 0 R /XYZ 56.6929 433.5878 null]
+2409 0 obj <<
+/D [2403 0 R /XYZ 56.6929 433.5878 null]
>> endobj
-1946 0 obj <<
-/D [1939 0 R /XYZ 56.6929 401.47 null]
+2410 0 obj <<
+/D [2403 0 R /XYZ 56.6929 401.47 null]
>> endobj
-1947 0 obj <<
-/D [1939 0 R /XYZ 56.6929 335.1577 null]
+2411 0 obj <<
+/D [2403 0 R /XYZ 56.6929 335.1577 null]
>> endobj
-1948 0 obj <<
-/D [1939 0 R /XYZ 56.6929 244.1508 null]
+2412 0 obj <<
+/D [2403 0 R /XYZ 56.6929 244.1508 null]
>> endobj
-1949 0 obj <<
-/D [1939 0 R /XYZ 56.6929 168.8052 null]
+2413 0 obj <<
+/D [2403 0 R /XYZ 56.6929 168.8052 null]
>> endobj
-1938 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F41 939 0 R /F21 714 0 R /F39 899 0 R /F53 1029 0 R /F55 1037 0 R >>
+2402 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F41 1208 0 R /F21 930 0 R /F39 1151 0 R /F53 1303 0 R /F55 1311 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1952 0 obj <<
-/Length 1659
+2417 0 obj <<
+/Length 2162
/Filter /FlateDecode
>>
stream
-xÚ¥X[wÚ8~çWð'±ª»å¾™„´i“4èžîiûà`A}jì,†¤Ù_¿#KœÐ=›<X¶G3ŸæòÍÒÇðOúJ Ì"Þ#Ž&¢?[öpïÞõˆ“ ¼PДM{o.XØP$©ìOç ]
-a¥Hš~Ä··ã›óË/À
-<¡a 0\Ç7Ÿã+ûìvÑAün<D(%Aˆ1‰ç7“Éø,ø8þëâîÓõU<_ ¿O?ôÆÓ-¸æfÙß½¯ßq?…s|èaÄ"%úOpƒ‰"Ú_ö¸`HpÆü“¼7éý±UØx[oír
- Êe?`•cÕí6Œ°
-)˜¥¯çDCèå”ðBuF̺ª#Ê€ÃlÍò¤ª«H ÃE¯ÂÚ
-âj×6AZÀ&z–÷ëýRª£iX½ü†Nõ<Ùäkç\÷âò^‘S{³©ô|“¿gÀ'Àñ0ŽB*Ø‘˜4¤^ Š—ª£’vs›Š„ç¶4[éÙº\=DF`9¿
-Î u€kEFÎÚè®Êò'”–ƒy¹²@yóH(1‚B±@7k±–r¦PD€%¬˜­´Êê…ªeÀBDŠ®óïi).C'™8¥–`[ e¸í„AÍ) ‹¢´¯R+ùôCvU”ë-´¶¶Ýùú% 艞#l*os¨ýöÍä9Š°„&Ã"$”%Ìñ—øúöjÜq, $lpsÃÔL¥IS2¸ßdyj–Ô§1LÞÇp•öéùÄ>¼»³÷óúœåÒ>5{¬ÃU3úR!…¡bÇä¿’å°á¬\¢ŒÙ ¶Ç@!ª(RQ´Ë
-Áà"ö<š©­Ï§r“»å½ö¥_mtú¶ã@à@A[j«S¨¨*= Òj¾*—
-¦×ã)]»Ž‘VÊÀí,1ͨ1<HuÅjÊÔÜÝ?Û뺱Ý.²¦‚ºÌÓ™;hÄÜóÊÇþÐI’$'™ùë
-‘
-Uزo“Ÿ“É0Tí‘c‡ ™sâS‘Pªý™ÜZèB¯’µöÕ⺟+Ц*Ó0
+xÚ¥Y]{›8¾Ï¯ðÝâ§c„$$z‡§“Išvã´;;ÄÈ O1d N&ûë÷è &Nf·½@Wç¼çC™`øO&’#Lc61C>YmNðäÞ}<!Nfæ…f]©ùÍÉgTLbGa4¹Ywö’KI&7ÙoAòåËâêôü—é,ä8˜£éŒc|J®¾&—víË4ƒäãb9!q BT‹E88½Z.f§Ë³ëÏŸ.ÿžþqóóÉâ¦EÖEO0Õ°þ<ùí<Éà?Ÿ`DcÉ'O0ÁˆÄq8Ùœ0Ng”ú•âdyòÏvÃÎ[óé˜5—ˆ‡,šÌ@8b8·F˜ƒ f‚a$#µ6 ɘͼ”¶ÙìBôÇ3Î;’ñ6×Y¾U«¦Ú>-BxÈ£hÒU{
+ycumÒçÖ,ÆÀReÄHè-lKBµÉ›Fe/SÄ9bq$SWêå`j¥L0%C•quCˆã*½ÐˆÊ^˜`e/î«</WÅ.ÓD¤qðëòâµ>ãéÑ*Õ6mòòÎÎO—öi)µªÌ3«‘¶¬þ5å
+ipsïö¬Ô*×N
+—W×p ÅD_!©€æ0²wÃÅ/ɧ/—‹‘$'Ð|#"¨¼ÑùÑ4$¸Ýå…Ƀ¡ÇA‚åO <#»j;â’h§¿6«ú[{d¯Ñ†æ3_U.Ô_éæ¢uUmÐ;èpÞ…ŠðPtŽeï/ž{‘}’i±œª(ª'g3¸T›™/HPÙbƇ ßó<U»"ë÷Py]ïTö~ä@`@¸¯ A¬³²®Õj–Õëmµ1÷ïã`ÚçÛ;ض-zðá(PÓ§¹RYm´Ÿ-Wòïê À»È¦À_¬£Ý¢Ö~ÖO‹Õ ¹[±šEršˆD°¹<ÅóDF"ŒæøCŠ$‘<™Ëùü4œÃ¦ Zx-ÎÎ̹ ŽŽ>ðE‚ç1#7î³úìür±<Æiѱ%=ÎPw[ ©½-ê(þù]ij?ÌnŸí³é|nÐf”ɦ+Û_ŒµXztæóþE ÿл4Mßåúßh¨Â1kãÂdÌ®rÈ´…EkŽ0%²SSH¤¢§ß²Ÿ©FÈþåo ésâ“Ú¢‘ÿ='u ÊÝ’|¿t늀‹Ø t5‘¶n
endobj
-1951 0 obj <<
+2416 0 obj <<
/Type /Page
-/Contents 1952 0 R
-/Resources 1950 0 R
+/Contents 2417 0 R
+/Resources 2415 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1961 0 R
+/Parent 2414 0 R
>> endobj
-1953 0 obj <<
-/D [1951 0 R /XYZ 85.0394 794.5015 null]
+2418 0 obj <<
+/D [2416 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1954 0 obj <<
-/D [1951 0 R /XYZ 85.0394 575.4191 null]
+2419 0 obj <<
+/D [2416 0 R /XYZ 85.0394 463.2352 null]
>> endobj
-1955 0 obj <<
-/D [1951 0 R /XYZ 85.0394 427.1073 null]
+2420 0 obj <<
+/D [2416 0 R /XYZ 85.0394 318.8302 null]
>> endobj
-1956 0 obj <<
-/D [1951 0 R /XYZ 85.0394 329.3834 null]
+2421 0 obj <<
+/D [2416 0 R /XYZ 85.0394 224.0131 null]
>> endobj
-1957 0 obj <<
-/D [1951 0 R /XYZ 85.0394 262.8864 null]
+2422 0 obj <<
+/D [2416 0 R /XYZ 85.0394 159.9229 null]
>> endobj
-1958 0 obj <<
-/D [1951 0 R /XYZ 85.0394 196.3893 null]
+2423 0 obj <<
+/D [2416 0 R /XYZ 85.0394 83.8775 null]
>> endobj
-666 0 obj <<
-/D [1951 0 R /XYZ 85.0394 155.0304 null]
+2415 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F55 1311 0 R /F22 953 0 R /F41 1208 0 R /F48 1228 0 R /F39 1151 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-1959 0 obj <<
-/D [1951 0 R /XYZ 85.0394 117.4002 null]
+2426 0 obj <<
+/Length 2546
+/Filter /FlateDecode
+>>
+stream
+xÚµßs›ÌñÝ…fúPy&û \Þ[Iü%±]K™6Mò€²#P²ëþõÝ»½C€”Nç=°ÜííîíïEtDàGG2ðÅÔ(T—„ÊÑbuFF°÷ñŒZÏ!ym¬÷ó³·x8R¾
+X0š/[´"ŸDÍ“ã÷¾ðÏ_^ÏfÓ ïóôû‡»›¯_&ï§_Î=*£(Ono§×—Wÿ8÷˜$p2þ:¹þ6ù‚k·çŠ'§³ó_ó?ΦóF¸ö(áZ²ýøEF Üã3âsÉÑ ¼Ÿ*ÅF«3!¹/çn%?›ý­!ØÚ5GB‰ÏxÀ4Âèˆ
+Ÿ Øl«D*ŸE!s*‹¸aRTUºðžÒ×å¦\åñ}šëûK_­W8p¯R½ÔYK߀Ŕ/‰šn;§ÑØ4úûÉXˆšaÀEà!-ÒM\geïuYæ–#܇úJJfYòÀ”Š ËÙkQ®«¬ê…S?Œ>
+4 AÚ%R¸“ æöCJƒ‘×&a,è€Ë5X}E4J@Ýž½pÝ‘ <ôE$ðÕ‡#ô8=¢@J‹õÃã¿æ/
+>QÀ-vœ?”›¬~\ ÐL%ÂÀb6D'D»"$q¾-—Ë*­ÈôÁEŸìb€,¸ZèGâÕk, gy\U”Áå¢(ê¾üsäž$›Y‘ž4XCqy’â2†î-|F¬Oïc] Pî^ëSNWRçRѵÍï©aûù¤û%Ù&]ÔåæuÈý„0Iû·*Nj©€œT¿®‡4/À û4oÿYŸ$»Þ”u¹(óßõn0LBHT„Îô·eÞsÂú¤ÌTË [è*×£÷|’^ž>¦µáh~µP±+<2à1ø4R•eÎ_NgwW·ó«›ëæT·\:XHféý­Dgô‡´®Î!_Q]¹,ô‰¡ú1Eà!{N 2›Îͪ«Šøãc±y]×%±ÁH^ði‰ÅE‚Àý6Ë“{~Âò´BfËrƒQë¤îm»ðþ$’ÌÒÅÖ1²…–é|‹+|&©fQ¤ ¾f¶@ß}°” „J{¢Hz{‚ph¾lCA#hB¬óÇ!ç‚ŠL¹ˆZ>`ø<p8å‰5ÏD`
+XÉ*|Vët‘é˜
+žÓëùÕü;îîdPXõÛtãª*™uox·=©¢ˆÉÆ¥¹éN„ïvïÛlz§/ËÚ7G®³\ƒ× áP‡ …zÓ㇎âÍüS›ÓN->.â°hÀf<ÔŒ›ñ^ìxû×ÖÌ8²aè³0 Ç#¶…t8`’‰×‹½Îv Gù9œ}~m?™O#uø]tg]fWe’¾Ãßµ¶ˆm.óÄ«ê×ÜÖv×;j—$hÑr[»#ŽjZÇ0|Ķڿ·Ëͼÿ•´È]€þÞgTý­Ògj÷?^ÓN¦¦¿b‘o“_lù2ŸóþZáÚýÄþG¨WÓ8ãáÞ9w+\®`¶2‡|·_lw$Ô®ìÙ’ ÚŠãÜ}€¤óŠFIŒöü¬ÿ:僟¯Hóîÿþ›x÷§¸}ElعX=„Ø
+¥µNÙû‡ò¾ìÿ‚Ê¿Áendstream
+endobj
+2425 0 obj <<
+/Type /Page
+/Contents 2426 0 R
+/Resources 2424 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2414 0 R
>> endobj
-1960 0 obj <<
-/D [1951 0 R /XYZ 85.0394 84.3344 null]
+2427 0 obj <<
+/D [2425 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1950 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F55 1037 0 R /F22 737 0 R /F41 939 0 R /F48 953 0 R /F39 899 0 R >>
+850 0 obj <<
+/D [2425 0 R /XYZ 56.6929 769.5949 null]
+>> endobj
+2428 0 obj <<
+/D [2425 0 R /XYZ 56.6929 744.4739 null]
+>> endobj
+2429 0 obj <<
+/D [2425 0 R /XYZ 56.6929 712.5891 null]
+>> endobj
+2430 0 obj <<
+/D [2425 0 R /XYZ 56.6929 647.0402 null]
+>> endobj
+2431 0 obj <<
+/D [2425 0 R /XYZ 56.6929 551.5126 null]
+>> endobj
+2432 0 obj <<
+/D [2425 0 R /XYZ 56.6929 446.5077 null]
+>> endobj
+2424 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F53 1303 0 R /F55 1311 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1964 0 obj <<
-/Length 2625
+2435 0 obj <<
+/Length 2973
/Filter /FlateDecode
>>
stream
-xÚ¥Z]oÛ¸}ϯ0p_ fù!RÒ¾¥MÚdÓ:¹µ Ün·Š­ØBdÉ×’dý9¤$ʲ³À"¤ÈáÌs8<¤ÃFþØH*¢bÂ8 ’29ZlÎèh}ŸÏ˜•™8¡IWêÃüìý'Žb+®FóÇŽ®ˆÐ(b£ùòçø È9h ãËélvõqr{õãÓ·»¯_.>\}9Ÿ0Ej|q5½¼ùßù„K
-C`
-&BDA
-Ãá,±}€ƒxg¤8QÿUZWç!Ù†ÙÚ l¬Õë+«ì9-t•ŒŸ³qŽ_»sË Š%X,v¯ÛºÄú:1Ë,­¾¤XbåaŸåËÖ¬üI)ÏÓÊZ(wz£‰sÜæfÌ´RIgébï é6è‡fö¿’
-ËeªMé?³ËoŸ¬&ÈSÒŽ(–½¾€
-8BHýÐÝ™¨f}›è¤ŠHL!ŸÌ†])—¤³a#eÒ”Kz²›¦($èXå¼®sŒ3Â#€ÓIï©÷ºHcœÐé¹7Kót¡1Ç9G|é
-"fµK¶ëlM“p¦
-ÊÆs'ûœä{[-‡¶äd Ùi8Á{ÂRƬàf_Õ¨öÁ©/Z;¦ü6»øz)ß!‹Ø
-}@‚ÈìúBNDl|9»Ð5)ÇS€©èvrlj%°“KeÇâ·d»a˜òòKöËìQc]ƒÙl,5¾Nó|bü£Î/d3›¤ÐA/&£z1+»CÌrÚ}‘t·Î"q"YQ¥E•ÕH£;" ‘Üèå £qQê2î,¹iÎ*l®¶é";Çí.õ–(PÌ.ʾdyŽÍ&Pî+³]¡ïá[–éc²Ïk«h_@ʨ°GãjàbRæNŒ‰@ HÈ›¤]në¬,g1±Ppz
-*}dÍüªLn¡¿
-ŽœvÌ 8æçP˜@,Bß³›b ÇOmV4îÀ5µ+ ]á͈ ;eQ'Y‘«Þ(Tªu¹Ï­ô:yN=9Þe V£^s‘ˆ­B[QZ§Œ´¥t\¿¬Ì°ÇepIMõfjs¿ýÖê( ô?T‘8 ƒ®Ôq4Rƒ')t«ÞÛÀI¤¢Ón9¡·¼' ÷¼ˆùnÍRC†ì#‚®øQ ™åºÎñüìJ·öÆÛQ&·w%Ûœ‡ª|H騇¦{=¼0¬jNnUd ºdY.D©Hù˜¸Ý¶§ømj‰Ö,[YØ´ڤ„ÚA<€ŽADÄ„êלÓéH€ˆ“2Y÷M*¸ùÆá&ЀÉnøCFhõLÞï²Â‘ÎIJÐu¹³×€j¿Ù$»WŸL5Ô ¯]Uïóòj¯i¶£fåÀ«‡k\Öl_ÅVi1phÃ$c¹„y<64Ò kûv¤NÄÆI™Ø<Í)“mlLƦkòs
-”)q÷Ü7’öö]bCî‚׸ÂCóа£+ÈÂðœƒ]©ã+ØH™ܾI]»ÏȃÔõ¤s-u=ônºzîÍð‰•Åö9•SpǼš¢K¦Ë’PÝi‘'¾²ñZbûSKd%¨™×jnöÜl@ýYì7:–ºé!­_Ró¦ ÔŠÁVCúáN{/[\Js‚R÷ÇÜ ~˜SJ¡ ê(VG¹ ï΂ ªÛ²ª²‡Üjj˜[
-ß­.™ã.KÃRî 3æ6·=´ÐÃÛ”V-¢ :ø-Æs„+¨ì=ÌÚG"ÎÜÃlkúâûüúãÝô“þ­õ6Mï™m´î‡¦Q´}ÆÃiOïÜXƒ]åP¯º¨WõÊó€´Mº&mŠ|LwVؼ påVL“æe«Ó›ìõãhmßZNêD;/ì/(ºÍ€tsš&ÝW3÷"‘æ}¾;€Ú£pWÜÂipí¡ã`wBëÏÃ9[aÐÿYÍ£­!‰yÄOzåd½òo.œÄ4–ž[³Ã‡²eú°_­Rg¼"Ç~Ë’è༢ÍOEÿúwþö¿‚öRtäy‹‡’À`åœÒócŒÆÙþGÀ¡ï;úendstream
-endobj
-1963 0 obj <<
+xÚ¥ZKsÛ8¾ûWèfºÖb€à£öäÄvâqüØس»S“9Pe±B‘‘²ãùõÛ(€¢è­Ýä
+¥ðe(„)ŽþÑmhͪ¥C‘"ñeÂã‰pnI„УI,S?\(‰¬³7¸¸H¼YNm“·Ø‰½v•oNXâéñ¬¡ö5/Kê}dð¼•Å<k‹º¢ÁEÖæ§Ð /›·ÅËðTÞÎa5ÁŠ ò®ó7½y»ÊôéE5/·‹Ü M·GF=›qЈbʘŸJÉÕ½`}½~†ÓgeNš}-ÚõêrWSÝ—|Ó
+ ÕË©‰î‘0çµj49¯«6+ª¢zê­ú‘¿Q§YÕÛRS¯²—Ü¡ã^óœÏ‹ïAÀs³#JBA6ñ®–4VÕš)E=UHœr4å¹€¤NIÛ$TÕ½º¥¶Ð¿·M¾8„(æ¾dà%F`SBG¥€°
+bì|
+ Ynêu™Íòr V§¨ȈhÍa EÒ‡ì)}GCÕˆ† •ÒÐõP†ÔO¦æÅ&Ÿ·5­ïƒ%‡Ô0ŠÆ™ë¨¸sÌN‚ãÄå\pÓÓ°C.O±¤Í@ƒUÌW=òÆŸ¡.MÎãø¿V›ëÌØЦhÛ¼:¬ br½£ ‹jD†JéâÇAk;rg-{GZ‹}¤ë×TôÁŽ}´Ð€ne²Wȉ´ÐMÐXvX‚„Y¿“LØT#4TJ‚ÏChf˜1{ÞÔm=¯Ë=4‡!àN†ãÌuTܹ)xêÇ"Š]öÎÂäzr=JÇ5Kjê%+·9u—#J“‹.ä`a˜$:!€ñþ6\Ŝɨ©¶ëY®w›åíkžW4h2ôvØáRZ›«BÀ]Ò vSˆE¾Ì¶%fH@ªKROÐOL$¨f5µÌÝzpþ¹nŠY8¡.ÜÐ Ý©ðÂ!ÛýÒ\g½8 µU‰L¨ ƾ]~¢.…Ô»T†¦mܪêóf;ŸCQTo£6 c?¥G­Muµ•Bm;˜CcbIûöœ¥ÀP²„ã|uTŒõSà@`ÎìJˆ¯Ê–
+4¢Bèn&°
+€eÇ${ç`ûöάõ‘<";ÃN‡zü¡Ò0híÃüÝö¤ö‰K¨öiFElÍ–Ù¬(‹öÍͶ0_µJøúä¬ÍyÁtfcêÐ0wÑo··çòj¾y{6¹*l{ñ"e¾"G¼Muñ•BüË°ŸPåhÍ—ùK¾ï¤<†Bm”³Žj€5·úg>—‘ËÚPʑ϶OO]1¤8;,3 ¾#3‹jDf†JÉl/K¶è# ÑÀ‘NvøI÷Ž<+ËúÝp ô$ö9%U8Ø%U8ŠøÂÁYNí“Î-4 R«h¢Xê+MÙíwuN3¯ô>‚CÐÊb‘ëqUÞà0=Êà•ÒÁ¨ÍBD@e¡a
+†öjÌTŠ©ô¶ªòó—º|ɨ7S8uYN¦<ôÓ
+"êI=áW˜j5~n1xýenFñÎ"o†öÁbça@‹ÅšMh¶j[ô=?•®aò,ÚS2â¡w¼®©+¼ã×®·èz+ÓSwÂÕë aØ¥côy±{ ¦E-¾½lIæ,&$Áè[žm4Sè9òYÕ€I’žOD’:<œ®êí†~,²·F‰´üTÕ2_˜(óì™zê0´*M·®«v¥7uOWCÝyÁ㬭 BøaŽ·8AzÓ×ITO뢩4§vIˆ§ma³«^ðqë_'®Ö–­û^c)ø´ÿDc+Ãz
+³”a½4PŒV#…(KŸ§é;)½Mu8XwT*Xß¿[ˆâG©õR]¥ŸæDÜ’÷øë¨tÒœ(ö£fuž“ÙBi´ d†ÔCcº{QÁ¢‹F(øaeV×ÔÎô&ú­Sišîù Ÿ³yê-[=Ô´rºš‰SŒäf>T¥ë2öc.¤kE¯…ú.síè¹ù„·0¿¨Õ~Ž+ô…¼XX{У­µÙ¶1©»@«_lqkõN žü¿µ´zª®2|,{|L?SÛ=íBE6Jßw¬k¦
+wó¹æt/S5å‰eßÁ'Võ+6‡ Ap?Nâw2}›jÄ •2„³wßÇì ô…dÉ8{Õ
+IÌ\ØÁ]‚;¶´î8D Â`ZQÕÔ¦‘\aZJÂ4N)Lã aZÈn#Êï#Lck0}…ig'B±áDm*Ìï>âÿgLÇ1TPùŒºÞ|¹ÖD
+Ð߆Œÿ7ˆ~lí8Œg¢ÙçÍEsâÇ1D›9 æD»ìh0'äÔ±5`¶©rI _òÈo#(gøÕ’ºnƒƒ6ˆNŒ7‚FCÆ÷¶gÑI°C4ž<.¢é æ“ çYc'»*+ð®ZS“(ÿm½â[1ÀJ:O©c€ýgíú­·“ÝÇ:4“ƒ#¤83 Û «zþï¿ÏÙý5RƒOH<D‹
+¥ËBÖg½ûKž}Þÿ¢Êòƒendstream
+endobj
+2434 0 obj <<
/Type /Page
-/Contents 1964 0 R
-/Resources 1962 0 R
+/Contents 2435 0 R
+/Resources 2433 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1961 0 R
+/Parent 2414 0 R
>> endobj
-1965 0 obj <<
-/D [1963 0 R /XYZ 56.6929 794.5015 null]
+2436 0 obj <<
+/D [2434 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1966 0 obj <<
-/D [1963 0 R /XYZ 56.6929 749.0289 null]
+2437 0 obj <<
+/D [2434 0 R /XYZ 85.0394 287.1527 null]
>> endobj
-1967 0 obj <<
-/D [1963 0 R /XYZ 56.6929 675.7286 null]
+2433 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F41 1208 0 R /F21 930 0 R /F55 1311 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-1968 0 obj <<
-/D [1963 0 R /XYZ 56.6929 599.4635 null]
+2440 0 obj <<
+/Length 2099
+/Filter /FlateDecode
+>>
+stream
+xÚµYKsÛ8¾ûWè°©f…àI
+?ÊÂz³âöñJþéœY©(ý«¿l[‹v³öYgEXŽèì9“h8üubõµŽ3«Ój©u¡±µ#ßB­AFøëáuZ‘øöÈÅ 5¹ c¥ÌC‚c—•,»(¥]{Zmê­…õ¥{¶©€E “›¦eÃ$°Ê™°”
+žl’©ŠØõY©ð–ó²x#ŽS°1 â>§ ÞÀ-ÁãoXàkÏ¡uúâWë4,<0àbì47e5eõ2Ú{Ò®ÊgóÁJ>Fà„8
+S¥mÝ9z…ÂHRybjèkµ½€ð@’ „%=[Ÿo˜È¡S öˆ¢¯; J‡N÷ò¨ ÿh-öÚdF2HÄ1ñðbY¤ks¨#¡4;TOë ‚ÖI ^sºjè4Tß)ð=†Fœvõy
+¶|j§òÖ¦½…ûäh‘„ÝJ×ÊÝšøF‡b­ZÀh£¤<Òª‘;»áÜFšr¾x[@œw°6+†¹ØlòÀrk¦wC‡ÄIìÉKŽE ›}²3Ða4„ ˜Êáøõ{ñø½SM Ý év{¿_™X”ÚöÉà (k¯ä2mG®¤ý”Ú‡´B÷¹*¬àX3/Ã9hß¹­5bÏ<+´—0
+Ñ$ M?4EB?º½ºp9f<b®\Ôž3žfÑK
+&!û£Q’„Šƒ²ü£“>ÿ Ùœ„dS•M9/ÿ$vÒíÿ8h7b‚`ûuZE|Q蟇õ\ ÊõÂ<Áâ÷–Nã®w}ÒŒ1Pø0¿íæ¤Í#]ÛÆöžNÚËÍ“ÉuP5´÷ÃK…Ÿ!b¿+€}û÷ È‘Œ»1à¿þ³Óî
+@’)Eã¿™S ÷= ²Ên†pzøg˜J V‡±ÿÑÉkendstream
+endobj
+2439 0 obj <<
+/Type /Page
+/Contents 2440 0 R
+/Resources 2438 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2414 0 R
>> endobj
-1962 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F41 939 0 R /F53 1029 0 R /F22 737 0 R /F55 1037 0 R >>
+2441 0 obj <<
+/D [2439 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+2442 0 obj <<
+/D [2439 0 R /XYZ 56.6929 632.7441 null]
+>> endobj
+2443 0 obj <<
+/D [2439 0 R /XYZ 56.6929 393.4246 null]
+>> endobj
+2444 0 obj <<
+/D [2439 0 R /XYZ 56.6929 322.7553 null]
+>> endobj
+854 0 obj <<
+/D [2439 0 R /XYZ 56.6929 278.4974 null]
+>> endobj
+1446 0 obj <<
+/D [2439 0 R /XYZ 56.6929 239.5941 null]
+>> endobj
+2445 0 obj <<
+/D [2439 0 R /XYZ 56.6929 205.2551 null]
+>> endobj
+2446 0 obj <<
+/D [2439 0 R /XYZ 56.6929 131.664 null]
+>> endobj
+2438 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F55 1311 0 R /F22 953 0 R /F41 1208 0 R /F14 956 0 R /F39 1151 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1971 0 obj <<
-/Length 2140
+2449 0 obj <<
+/Length 3022
/Filter /FlateDecode
>>
stream
-xÚ¥YKsã6¾ûWè] <<jlÍÄÉŒfÖÒÔnÊ™MA+©ˆ”§œ_¿EÊ•­9F?¾î†ÉÃ2‘a–%“4KÇ„OŠíž<ÁÚ‡+âhbO©Þ-¯~~ÏÒI†2AÅd¹ð’KI&ËÕC4ýòe6¿½ûÏuL9ŽÞ¡ë˜c}šÎ¿N?Ú¹/צf‹ë˜d’g@Ä5™ÀÑí|±˜ÝÄ¿Í~ÿ0›_[þz5[öb E'˜i™þºzø†'+¸Á¯W1à6ù‘,£“íUÂâ c~¦ºZ\ý«g8X5[CªàL".iÐ%BPÆ9)ƒgH0ÊŒ2à³û©¾ïrvkow³ƒ÷wApGàDZÅXF)IÃâßU;*2 ¢è
-Ò2îöÍvW©Nµ N*£öPªmׇªz¹&„D?Á¼äQÙÙõݾ¬;C›E¹ÛÒÁÜ“7kûÛm”¬›ýÖÊŒäfÉDP'Äo5üC?æyþc©ÿ¤Ž¹1Ľ¶ac×X-Úó`Ðvy½Ê÷×DF+;ӺݡÏbGËMÙÚiÿ›×î{¥ê®ücZä]ÙÔž»Œá*'‡¢í@o«”çÜÙßMî&žT­öy§Vè¬/cpA Qõv¨Œë‘dhVJ6à¥õó&éé¡'°)Iß>µ§z}ìÈ’Ã8ãcµ96¤%˜8›{¼ÖfoÕYU =H’ ªRWUOuQUožzTÕ«cƒª >ÒF  Ϩª>lÕ¾,ì‡qvµ³?-xñÀM<wæÕS³/»Íö¼‚…
-£ˆ¥R\ôÆ#0¨½vŽ=¬›¦3˜“:Ø
-ÈI(ø 9'%\ö´†$¦éqÜþ‘<îî4#`mAœµ¥5÷r£BRf(¥½2Ñ âÌYKC*Ãb þÊõOª+'ûmê =°^S4>%ê¹n“wŽ‰Nzð¨,`¨öÆô,xE3à/¢¿›Ú?EĪt'uP8V:DôªuÈ“îæ±UW"ƒ#O¹ùøõvÖgóNmÕ ºt]4¤°fÁ«0`€×ìyƒSJúŒÔ_)ÁCí&ÔÔŸ$jwª°¥‚]6àP­Z]¾J(éÌÍ®y|† +›Cëö©â
-ž~]þòùþ²fï
-¥kšêMO´â,^êf×BxœZ:ˆM%(‹ê
-\_€bcWÎq6*LDz?ÂÉkìâFXßÅ!nб>KÁámùw“IŠ=]\Ÿe%‰.º—]ˆôÈÐß{±â"ÀŒ2ȺØ7£E•·mœ3$¥?ñ›UÚC¬úÑ:ÀY@(ð¾LXWùSˆq‚’T’ž³Í0,''Pù?]”ß9*àK@Pq‘^bÓþìG»ÀAG"éÑe·oº¦ðQ° 8=gà ±+÷]ý
-£f»RÏaáî=¬gÚ^d
-x«ê'Hæ—\­çÙxÆL_ßÖHÆ$öÁèŒßmÒ3~¾(l¥žUõݯ>bÝ´ )Oq2Æ¢ÛÙâæþîËòîó<Pð¿•€*2ÄiFÇNgËvibÛŽÜダª4u×B×&ïõë}Ò•Q”®(j[âK¨ëì¯Kl2¢œq·£^¬é¤§ŸOî:;¥ËF^^ú‘)óªmÆ/}hOžR­[ó] Ž–‹»Ç>kyaíÍm^sÆjˆ¼s×n5†q]»ëâc§*ý\NBþ iÞu81B¡Î‰7£i»q= lúƒé3=–FFX0wn)šíÖ>ª²VÚ ³Õ¥fÑ{‚åoú?‘¸"ROnmçFyWlNø›{Ø£×+Ám3ðññ ›o{lé?²Þ÷MYlÎöÍΪA?„]¨=?›
-endobj
-1970 0 obj <<
+xÚ¥Évã6òî¯Ð-ô{ƒ[æäØN·ÓwOKyo²(
+¶ù"KŠIµã|ýÔŠ”hõaì
+@U(Ô
+JOüëIžÄÊn’.N”N&ÕÓ™š<ÀÜ»3-8Ó€4íc}??ûö›MŠ¸HM:™ß÷öÊc•çz2_þ]~útsw}ûßó©ITô}|>M”Š~º¼ûùòß<öé¼0Ñå»›ÙùTyR
+`‡ÆgEÁË},|½~`0hã2gèp΀ÃÈø:>’uÏŽœ•ŠU.1)l¬ŒÊÆý¬ MûXÁ·ûÙ éNKf.IúZ bP‚à#ÊÕÃæìåé9íÀG™ì+ÜuX#ìõµJ'.NøÏ3¿òU‹ÂÍ­ˆ=wQõüºm7Ïåî„ç:.AoœV¢7€ÛéMn;½È!{ÙèK¹Úɶ¬&aÈ-Kõ˜4Ž¤pR¬‡ô‘5M¥±MÕ[ /Ò@uM€%KÂϳ˟®Ñ]XS`göþ’ü«…È6»¼`ä;8”NÒЃ'M’Ê4÷ÁrǼ»û"º¹ºz÷q6?¯‰˜‰ q
+=å·äµÀ‡D<HbD4#Ž±!"´Éë÷ÜGßv]ߣe@£ïýj¶ÂH#?]^MYÂ>u‡\³åð¦ÈÏkÜáIÀi7bó€ÃJ’ã ø&š¡
+‹.²!ÍÈøt ã–þFø©ÊÆGÜøuS·õ?ê~oÑkfy´Þ`[ôÔŠ†ÉÀ0¹NàŒ¤µD¦óe¾f4¹Æ}©W+F±c ánÉs‹WYúûr·je£Ýz囆gÚÑx`Áx3¥sQé©Ñzíâ dÂÁV"ÖÁ)øþà¾]ììÞXuw>Œ!zŠÃE‹P_ïC,Çs#´ð]˜_rä‡kh}¹Ät"ç;fãÀ~œ%úä)“8-””ºRJ$! ¤%ÝRJЈ
+1e+¡¾§†øš)Öp[=úêÏtá
+ê¶lëE½ªÛ×°´•
+&&!Å‚¢ý#©0d Pr[Ø‘Bž41Q¿Î>|*p˜d_
+„©Í‹ÿn ,ႇ.ÌjÖ[;Ì ¬D2hýßÛU]Õ-Æì/ÖK`Õ9ŸIllUÑå|åÛr0F%/åÃR ¬Q²kUOul(¡‹T "”f±.²l¨4弑®B’–&¡
+a Ÿ8hý#W˦{ÀQÓ]mB­)LÐ
+ÕÄIMîc½­ÉiòÕ‘&'qâŠâ4É€4Br””Š«ÍæÕÁGuÈfé¿~ ’§cJš Ý¬–Ó¦}]ùîA8¼f¢SEG·Ùµa í
+e‡oËeÙ–x½ªˆ¾bÝ[Úñ'9ÐâX!rí‹ÄDÐï,7C%‘w-Ÿ“ªÕné¹#…bŠ¼ÓðXŪPŠyÁÈ’ UË·¨þºpnÚ /^r_¾Œí$Ñö¹þ"Û¥}‰Y«CúDŽ³ˆ²$±UG%¥z‰¡eû´Ù0aÌùë´/žlÏr¤Þî`ÝrHDBxsŒ¡j‘ɱ)ßVy¬Jñ+šl.oZ@½“/×M·GÉPŸñ‘úÖ‹.®üáK(œ—°é| ŠùR’„߶oï®ÿu*©5*Á<0ä6lj£Ym~ø {6»íV>[6¾éè<½é#ò"†lÜžv=¤·=D@"®«ñïL€ʧjyÇQvk’X'y~’­阯,ÖNéc·ë%ê‰ÆÙ .|lrô…Ó=<R»äÉj³nËšKÊÁ*N¦
+©ÝQâÔýÀâ˜÷ÿº ˜endstream
+endobj
+2448 0 obj <<
/Type /Page
-/Contents 1971 0 R
-/Resources 1969 0 R
+/Contents 2449 0 R
+/Resources 2447 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1961 0 R
+/Parent 2414 0 R
>> endobj
-1972 0 obj <<
-/D [1970 0 R /XYZ 85.0394 794.5015 null]
+2450 0 obj <<
+/D [2448 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1973 0 obj <<
-/D [1970 0 R /XYZ 85.0394 752.1618 null]
+2451 0 obj <<
+/D [2448 0 R /XYZ 85.0394 751.3869 null]
>> endobj
-1974 0 obj <<
-/D [1970 0 R /XYZ 85.0394 531.002 null]
+2452 0 obj <<
+/D [2448 0 R /XYZ 85.0394 624.8718 null]
>> endobj
-1975 0 obj <<
-/D [1970 0 R /XYZ 85.0394 468.4168 null]
+2447 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F55 1311 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-670 0 obj <<
-/D [1970 0 R /XYZ 85.0394 429.776 null]
+2455 0 obj <<
+/Length 3191
+/Filter /FlateDecode
+>>
+stream
+xڥ˒Û6ò>_¡ª=X³kÁxð…ÍiÖžØÎÄŽcM6»•äÀ‘ Ë©ˆ¤'“¯ßºA%¥jKÐhô?1‰–h©'©ŽXÌE<Yl®øäÆÞ^ ™y¤Yˆõ¯û«Wߪt¢™Nd2¹_keŒg™˜Ü/™þ‹ÅìVàÓ7çóÛ׳»Ûÿ¾½ýx=:‹õôæÓ§ÛoÞÿçz&cÈ€ÊùôÃÍÇŸn¾Gاk-§7ooç׿Ýwu{ß“’.¸²4ý~õËo|²„|wÅ™‚&OÐáLh-'›«(V,Ž”òòj~õc¿`0ꦎ±"Š3Ë(™ÌTÄ2Øœa‚¥B
+¿Ÿç7Þįà3w#fE@1}‰Ý®14?%Jå#AÍÛº2U{’‘I*YÄùN†X§YÙc9^®Ft,S é÷ªÌÉÒœÉ,ÉΓå‘FÈ
+9®c&°Ï²æ¦µº¡ÐÚF³5‹âWÎ¥ÕÅcPe®€27XTØûA‡(¯ÅÔ”4±^ ƒxþ
+›Û]aý°m®=6ò°“?ûÁ2V[OEYbë¦
+©šbOi-¿3÷H’rÎ 1 ÑÉÇ8{pï ­›‚eîO¯ŠÞ}2Zi¥¹}2.•…Nh`ÇœÇSš¥š§C'ã˜aæëv”RÎ:ÎyÀWÙƶXo±,ñ¬O¦÷VØóÎYzX :wÛ
+ k¡ÙåµÝ¥ÕRRá×ùQÛ
+—sÅétS/Í?A¢¤šÎ»-™€‹-0ÜU•±œq.QÅÉ´îÚm×Úà&³©Ø¢ì–ÓÁIâ£_—(ªe±ð%B’Ÿ¯ãX¿®;¢¢9h¡}éîJpK~P¹:̈gM‰ø«ŽU3•öᱶHA†—Áq± ¨Þ¢-¾+dÏÅJ‹ê{9Íù<¿± ‰i
+íMŒÄt»‹µ6KnLLçb¶h
+ÓVµ’SñýLÀÜîSr»Ð3øÒ -k¿+±ØaR÷¯Å’¦ç#FA´ ´ôØ+`Ö+\d,²ì@È{•>4A6îO}ª„±X™ß»bØ–/Æz#ÕK®ÞÇ'vÊ€=ö
+tì>¦l$qtFšèŒˆÎÈ.²¡Õ`chãˆ6‘ƒ“Øaûæh´}j´ÕöE¿˜ó±¬þ D$Y“þ1`STÝaÁ‡2•!%NÉÁ4‚‘yyTü ^MƒòŽâ4š?ŸÎýDbÿ}]¨î„X§µ¿ÇrÚߌi?D¶¶äåƒô©Ûõq #
+p–¸k„ºAÌ! ÷—I4$ï èàÞ=qK•ã¿£ÌA|)ƒsrv¨ ÷
+=¶J±ä·Ÿð1~_º€ïè±!b÷¯‚bFÆ„LôP¦ÝŽvlK
+818ž¹—Æž¸ò5°m·ÛÖþE×Ä°ÂqZ^ ÒË´¼ð댼x,'/÷cò"íÿ*¼çÜíœ;ú‹FÌøEÒz¬Úÿ¢¡ˆJ‹ì+YÚÿß ŒÄz¨zµ°Œì³›\ã—Þ|4ÈÂe¹ÂA<Y.p%JŽ¸rgŠÈónÓ5-.ý@[˜KW¶Ý?ø˜RƦ3} fû¢(˜må¿
+
+gÐq©|ý²RGô7 ír%X@<9…îÏÆm_”¾‹œÖy ­ë¯êË¥_=™{ó(+_ïíÿÌ°÷œ¿k«| |~2Øgô_ào¤f÷0‹@žöýcø»7¯g>Ú¾y· _Õ$8½{³õ&ýtIÚ—ßbfÿl5¢|â¯ñÿþO×þ¿kQÊT–P%™ÆV•O”埈¢cËbB"Ghÿîÿ“Îendstream
+endobj
+2454 0 obj <<
+/Type /Page
+/Contents 2455 0 R
+/Resources 2453 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2457 0 R
>> endobj
-1976 0 obj <<
-/D [1970 0 R /XYZ 85.0394 393.3396 null]
+2456 0 obj <<
+/D [2454 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1977 0 obj <<
-/D [1970 0 R /XYZ 85.0394 361.4675 null]
+2453 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F55 1311 0 R /F22 953 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-1978 0 obj <<
-/D [1970 0 R /XYZ 85.0394 295.9604 null]
+2460 0 obj <<
+/Length 2936
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Z_wÛ¶ϧð[”ÓZERΞ²%í²Þ¤½Kvv{Ö=ȶœèÔ–<KNš}ú  MÙ²“³µ¤I
+ØðdÁ»—‡ùy[ò⹡o–;{·Öq*wÕ²„ Ê, Þ[U¦MýXÖ8CiTŠƒjN3ífúp\nµ³}º÷æÍbÑ<ÝELÐëDÊñ
+L¼‚RÚaû5Šâïæ¬aò¢g`l«àtÙPW§O®7s½Û3{ÂÕËÊaø 1,/íïB°é¡6ËÕ†lT/{.‹5+õ5ÒѬD=k 8x:§,‰¦N¬ÆÍfM?fÅskL §|_7kr$˜X”ÅŠzFˆL·lêî™ö¥›!'/: ÎcõT–߬xO¤·}¾ v6µ¬j°Š¡ÇeH­ÊiWûÛKn,Eü~¦ak°ä ZPãðÛ˜Ò; ø]qÐñGkæT\gíÁ@ ™S¨âô…Ôħ:¨• ÔŸ‡u–k¨á)ß5s³•ÝpÄa’½¤Ÿ£P°®“4L’\÷5äx[Ûf¹Ñˆ†ššÚ§‡Êø4L4‚yŠù]ÙÕ µf²ÚLUû`N›vBþdžóWqœÏ!vÙitY 8tÙ5,Ô¤: ÓXêÝð¹X „cô‘êéb3#ÔÇãcçb£/0ÈK¥Ç£nº>³Mk™½@Û‚;2ë¡ ‘â¿·Nõ-;]mõ˜ïè1þ@m³êª†9>JÃi XNÊ’±z½Ý»qmšå¹ÆWˆ‰uó„ÍaGˆ4<W’ìGð¨Ž8‚¥2Žp>äðzÐùkü@…R‹ì¸zŽj@¿¾ä¡”Rô$?šïAì`OEjeý Ge<;•]ßP;a‚C°šF¸–îÄáne!ÜájßçL¨džä
+aÚâ:³aÜ
+„sU"Þc/,®³h‹kÈûã\öq €,îïí¥^´~Ja5ÀDâŠÑÁQ\ómdwxi‹—| ózvˆ_
+Ê®o¨¥úX ×Ì¢¤»ZFÂ¥¦†…IMY’y&f|ù”cÌܨ]4õ}¹v÷vPÜÍå^¤8Ðá›Î»eñìÇÃeaî1 åªi«®YÓSŒAû
+£≢Àoð•YhdÊ"èù…“’
+d04¥3a\ÃœI3.LÂïòû
+¤™ :3…ËiÙ¶ÆUaÒ½!n@Úz+ÎÆËÜ• }…¶ðÉ£Ã
+ê ;ù'UÑa íìï@]tïc <©óhû1† úáòæò×süRwwyAL>^~yÅ™ßñ4¬ïk%ÜíB'6«¬[Pi Nvï¨}ž ¦ÊN±Ô‹¹š)”åÖ{ç›Å6xÆYJNOÌլô µ-¦çôyÁ>‚q
+ Ý#Õpw¬«iï ²ýÒèÕ¸¢¿²XÜ7k…˃¦Mt‰úqËni–i^´ëy[³î´ª'ðPü1>K^ÄÞÖóm2…ÏDëìó¦éLÄgÝA;JâŸó ì+rwÿþ«¡í‘¨4”Yv ¨$ÁRB¤e¥p÷Bé]Õ5\O:‹ÓÝÿ×LDòendstream
+endobj
+2459 0 obj <<
+/Type /Page
+/Contents 2460 0 R
+/Resources 2458 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2457 0 R
>> endobj
-1979 0 obj <<
-/D [1970 0 R /XYZ 85.0394 212.4297 null]
+2461 0 obj <<
+/D [2459 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1980 0 obj <<
-/D [1970 0 R /XYZ 85.0394 107.4752 null]
+2462 0 obj <<
+/D [2459 0 R /XYZ 85.0394 658.0977 null]
>> endobj
-1969 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F14 740 0 R /F39 899 0 R /F53 1029 0 R /F55 1037 0 R >>
+2463 0 obj <<
+/D [2459 0 R /XYZ 85.0394 153.2806 null]
+>> endobj
+2458 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F55 1311 0 R /F22 953 0 R /F41 1208 0 R /F14 956 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1983 0 obj <<
-/Length 2949
+2466 0 obj <<
+/Length 1723
/Filter /FlateDecode
>>
stream
-xÚ¥ZKsã6¾ûWè(Wh
-dzéãç›pâšs>þ@ƒí‹¢Îk^îMw³oZêÍõˆß=Ðó™dwÅꚧÐeÂàTYnò
-&9®Çã‡/·'_î¤û8}¸¥é„ž‘³p¼ çA&¥Ð´FˆP"äÝ[BÆz„u#aj1x6!;H.à6C&ƳÕ(šÔGk¨Ÿïx3±È-¤¨U5E[¼ª #, @¨RMØSÝ"2ÉÆü'<CŒË[Yi" C²†”¥lümz‹'¦™¢¡6§˜µÌÛz÷Nж6¨Í¶TU™uór]ïŠöe£WLÆð’Ùgzë, Йõ戩¤ °âR-‘-œ‘4 „£4| ®½-zÒ‹B{ Åeˆ+
-­| ±œ4:Õ~3W;ê×+jçEk`E…-·×|Lop<†¹ÜI”1TÂ.^êb¡ü•«;úືT[-³~m×·‹tâ«%g†AÊCîëû¾!Ádê ªt¨yK=²C"ŒÆs Z™®jß”ªêN’4è¥Ô㛵}“…“ÆdÛ‘,µÎv\¤Dn×£iËbÔLÞmžDV[¹Ý&vÄ)ÛÚmàN8£ñ|Ì™ˆ SÏL"ŠÔ_ùÂ,»Ù—mÆ„žð
-b„$…ZKiHÓÔcˆ … …se[K!<ð#ý&Š%3ç>£±2‹ƒDr>¬±.ê¼Æv(­±ÕE­òjß·=*K³aâ:TužÊ
-^œ Ÿ<OeEœSú­BèO8\y¨lü¥¿ÓÔ0–¤©8e¼¶yM3!rÙ%xð.õ” G¤K0JYhÙeî–U ÂDcJ²
-~TaRw»+6Šº+MO½¡—¿}úHÃB†õÞŠ²¤Þܼ‚vàÅʬW7M1/Õ?P ýÃ(ñ­h U©'ÚXR€áû qV|CcøAñuQçÅ·Ciñ}9qqÀ²ä–Ô³¥+’ X’mùuWT6²2\øÎð¢Ùo6ùÎè|½:ªˆÔ[ ¯š£¤Ë¸‹=VŒ!Eö^e R"1z¹¬šF-& ã M=‰
-£PÚZpvÐ |ÅcOM…9sØCãEÓ©÷¼Îmv¬gªížò¢ãÃÂ¥Œ¥}âqt¬Íš
-endobj
-1982 0 obj <<
+xÚ¥XM{ÚF¾ó+8ô
+F š{lÁ™Ï*&ZpQÛ"ÍËÒ̃ofwkr«lâM!ðŽb 'YêùfÈ¢I*S!ä z(ì@ ¾PÊW¦| 3¥YµD‚<Y#­Ü$¥IqµÈq©²ÁÒàøn“åUCPV0»%(ìjÁµ !åÌIt–üI’äMf4ñ¨L‰cöÆH¬G}Š¼J²¼D·VV;¸ÛÞ¬²9Ž-?ÆØà-N“<õŸ$ñ³"f÷`2XL*†‡yŸÇí?§¶M?àà H‡€S"y¨kF³¥ñI“‡ÍaÏXŠkÒØ¡[Á'Tw¤³³Ä>B›A8?ÿ ‘yQ?S\«–Iå˜$9n 2
+ŽÏ?žŒÑºe†^›¼‚š˜þˆi‚†L4¦}ÞãÀ•3=6¯d]óJˆ³Õm±=ÖAygæ™%œ#šUZZ\Šøà]­5¬7÷Y±uÛ!§·°}‡¯\Ö–E^'¨à¬Ü³kDH ãöçE… AÞH³Cƒ-“{
+n²ÊN (OG¸ŠÂÂJmk»‚šÂJZ¬!WœÛ£·3›‰Ò¹Óü•¬ïV†Ì‹µG`­H¨DCkmlKÚÒɶ(V«âÊ ,ÖhTx÷PlW)®ß8rˆõ­IñÈp­IÄaÍe@è)½†&#HðY› ^¸Á'È-8Ê?/'c½¬¢½j—ïµI£ FK^¹i qƒ6€q±xqà™µOåGÇžu„$o(o¸fš¾$/Úè´®ªÁ+*u߶ÚéU$‘T4eøµÎFÃ0ޗރΦ>Ñà "<…ÀFÊâ«žÑñc„…ÎêE ƒ‚Ó¶· VˆʹTìqGspø ­‡
+è¢ K‘Å»ü
+ñº¸¯¤¯ÖÊé./îʬ||O„´
+#°"“1"’¾{M~ˆ;û/}$dÌ6²õOúî|-U×<Î4¶ˆ|–›¯Íðƒ³»7ÐJ7-×
+‘•¯éŠI5ÙÛò;óðwZ5Ø ½<ôñÅfçá©$Ѽ ã–éøU¦&¿Ír_³~HÖr\¸xv‘­Œ?_`¯
+­Ý;^>O¯O¯f§—OUò£á>Ä—¥Õ¶£MKmÓJcj¶CÝtt0À:e›èïKS¹-áºáÀ#\»ï’9~¬nOíBj,çÜö½vš¹ ˆ>@§(cõ©¼©bý Qâ°4uKl'«róàz$Ûöm»Ú¶åØ»Ô7¥¶+i“8/:IŸz.̾5àRû…Å“e´õýÿþ³ÿ`%Á6QÄ÷ßho6Êv%ºÊÚIýDôæ“ÏSÙÿ2®Çìendstream
+endobj
+2465 0 obj <<
/Type /Page
-/Contents 1983 0 R
-/Resources 1981 0 R
+/Contents 2466 0 R
+/Resources 2464 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1961 0 R
+/Parent 2457 0 R
>> endobj
-1984 0 obj <<
-/D [1982 0 R /XYZ 56.6929 794.5015 null]
+2467 0 obj <<
+/D [2465 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-1981 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F55 1037 0 R /F41 939 0 R >>
+2468 0 obj <<
+/D [2465 0 R /XYZ 56.6929 598.7685 null]
+>> endobj
+2469 0 obj <<
+/D [2465 0 R /XYZ 56.6929 432.9509 null]
+>> endobj
+2470 0 obj <<
+/D [2465 0 R /XYZ 56.6929 360.8886 null]
+>> endobj
+858 0 obj <<
+/D [2465 0 R /XYZ 56.6929 315.6627 null]
+>> endobj
+2471 0 obj <<
+/D [2465 0 R /XYZ 56.6929 279.8921 null]
+>> endobj
+2472 0 obj <<
+/D [2465 0 R /XYZ 56.6929 241.5703 null]
+>> endobj
+2473 0 obj <<
+/D [2465 0 R /XYZ 56.6929 166.5861 null]
+>> endobj
+2474 0 obj <<
+/D [2465 0 R /XYZ 56.6929 97.4887 null]
+>> endobj
+2464 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F48 1228 0 R /F39 1151 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1987 0 obj <<
-/Length 2192
+2477 0 obj <<
+/Length 2079
/Filter /FlateDecode
>>
stream
-xÚ¥YM{›H¾ûWè°ùÉÐÛMÓìMv”Ä“XñFʳ³›ä€¶˜A ÈϯßjúCHj„g×>Ð4EUõ[߈Œ0ü“‘dÓ8‰8B 6Z®/ðèž½¿ †&°DA—êjqñ÷wTŒbó^a)Éh‘~Oî·7¿\!Ãã+t0ŒÇ·“Ù×É'½ww‡ãÉûéü2 RD\‘q<~;›Ï§×Áüæýì?ŸgÓË‹Ÿ/¦ §XWy‚©Òê÷‹o?ð(…3ü|%=à F$ŽÃÑú"b±ˆR»S\Ì/þévž¶¯úÀ`T"&CáA#$#BPÌXx
-`™¬³^¨¸äQtª.U?TŽjª³R÷PˆõBu œÞ‡w { *wël›/õMëßÙF_jp܎˶Ù}3)«mÞ¬Öý
-ÙVÑ.¼Q'5õ&[êê¯éÚà/ÒZ5¤2¿kO ûÕýS^íÌëÏ;xýE?2[Weœœ‚AòzÏΪV™y¿¬ ˜
-pû}ÑèŒ `9ÊÚ6]i3ýer{÷i:<,ÔL¡zcJ4x—D$7°Èô~¢/‚Ëà¾mU)ŒXó‰ÞÕÊRÛßÂŽ>)ì¤ÕbŘ]˜¨H´ÍJöG¢F
-“…oø€S1×Ø(Œm=Rª¢¨žu“ "ÅZƒ
-Ïž«]‘êý{C¾¾ËÒxt
-BΑ aïLÙ 8 ¡A¢¯-íƽ¾@fÃP¶Ãg»:DOöjM¾? ÜØÓ03S94N:85RùŽ|$öcGIôcú&ä„ãa}oÚjÁl¾Â‘=îOžîFDÐÑSòúÉÆmáíjZ‰™h3ÂiŠÜˆIlsUÏ{Rá ,tUgsì»Zìè\Ac5:3rÜÑ?ÓzPÈ{˜ÛJä üÀ™ {>5Õròiþy8CÔùc©ª¹ªÝR•WcBw?ØH$cf•ºº™™/±˜®ó2LÛó~É2m»riœò6)wP“| Ã`Î9wª
-endobj
-1986 0 obj <<
+xÚµYÛrÛ8}×W¨j_äÊÁ… ‰Ý'ÅV²ÊÅöXJíVeò@KÄ
+/‘²ÇóõÓ
+»RïY4H„4.Ö]1ÂqL†‹Õ·Ñäþ~z{3ûïÕ˜r<z‡®ÆãÑ—Éí×Ég=w%èhòa:¿
+B‘ ñèæv>Ÿ^çÓÅböezõ}ñq0]´~u}'˜)§~|ûŽ‡+x…Œ˜ˆùð0"BÐa>8C<`ÌÎdƒùà×VaçÛf© ÎbÄcyÀ dHœS .PÈ(kи»_Ìînç'o‚æ
+(æi­|¨’ÔÃ\VLJ¤Xéü#­Ñ9LBA ‚ð2&]©ó˜´R &Ÿ”É·ï9ïHÈ
+!LF@4{ÅUòŸð‡£ëäP59êøO0(‰CjKXQUr9Þ˧ò‡4â]Ûaˆ"N#Ýà ÖKz¨‡©áD˜Ñu»$Ýë‘l²OÒµ–Nô£æ<=N2ædeÖCÙ¯šˆÃ8OêåVmú&…HH µ‚Ô19DÜJ² Ðl½Í{}D[ñf7†Œ×=rÑ(,:K!#ÔBÙiáÆ4@«Û‘Nåùtª×N>Ïï<bXÇÕˆº
+ÀÉ×Å¿ï^GnV@™.lùœ¿TµÌ A\—EÜ”ò£Ý
+ZHž
+:(7ÑáˆQUxUÕÁãËÔÙUÑðXà£ÎVÊUaø6^·#Û„³nª G
+ëvá=“<@!m“°UzïQ
+QŽC(KFiRË·åz­º³Sµ!VdA_íäç¨}ð¨…Ȇ( 1sËèÿ¥ösܾù9j·íèÉc@/âý¶µ§öjG¢¯zê: Ôù<tkͱ¹ë©vßШ† º†~ÊË°ý"8»x3_?ÌšË
+ˆð6GË]B¹TWj4-š‚öN¸ài™j@UX
+=õh¡Ñ\éï_| §ˆéìy“¬é¦ø³,¼ÙAS…í¾WeOY)Áð^›QkÛVAWGaì&DU®ëgïUÆJBÓ«½k.FdáÔÕ¶§•»ðѬس´ÚÊÕ/­íZ÷`RmËC¶rjœœZnߤë€BŨ–õÙ&„ĈDßýÌ m…îŽ=ê5˜jÿÍ xRÙ)V=ŸšÏ没ù¶hè 8òåzWÃl–6>0Ât¼O£
+'u8¥³°Õ³Â›Ušï²m Ȧ¨+í„ñÆD¡™Ñ¢C­nbN\&vÛ$÷¡ ®õAÉbooĜޫíðûHë#1¥ÂäíÒ˜šn˜+S\ªžŽËmRltš06z,Õ!Z)8ÞPsQ+{VÌÙ©±À±o›Cý0±øTÀz“$É›Tý¡cOèì|uË°]åghöHÀ]Í:‰PE½ÍÖ±j+‡Ç2œ;¹m¨3DXt0Sz ! §¹NŠx4úr¤"Ñ…œ‰Ø]Þ ¶zVÁVŸ:¯`p¬lFQ&‰žÛ`ŒÍ)Óºìä›Í¯ä1ko¤ªå>m¶Û™c¥›£–Y’¬2ܲ˒e?AÕ†”E{ãQ\¾½Eç~ü€~DýbáiÛq[Uþö#Ç_€‚±8¦þ‹ †á ƱN)8¡åé»Þþ„rêû_·Ïj¤endstream
+endobj
+2476 0 obj <<
/Type /Page
-/Contents 1987 0 R
-/Resources 1985 0 R
+/Contents 2477 0 R
+/Resources 2475 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1961 0 R
+/Parent 2457 0 R
>> endobj
-1988 0 obj <<
-/D [1986 0 R /XYZ 85.0394 794.5015 null]
+2478 0 obj <<
+/D [2476 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-1989 0 obj <<
-/D [1986 0 R /XYZ 85.0394 752.3199 null]
+2479 0 obj <<
+/D [2476 0 R /XYZ 85.0394 752.123 null]
>> endobj
-1990 0 obj <<
-/D [1986 0 R /XYZ 85.0394 504.8188 null]
+2480 0 obj <<
+/D [2476 0 R /XYZ 85.0394 500.7908 null]
>> endobj
-1991 0 obj <<
-/D [1986 0 R /XYZ 85.0394 359.3246 null]
+2481 0 obj <<
+/D [2476 0 R /XYZ 85.0394 437.8079 null]
>> endobj
-1992 0 obj <<
-/D [1986 0 R /XYZ 85.0394 298.3625 null]
+862 0 obj <<
+/D [2476 0 R /XYZ 85.0394 398.8908 null]
>> endobj
-674 0 obj <<
-/D [1986 0 R /XYZ 85.0394 260.8495 null]
+1447 0 obj <<
+/D [2476 0 R /XYZ 85.0394 365.8909 null]
>> endobj
-1993 0 obj <<
-/D [1986 0 R /XYZ 85.0394 224.9084 null]
+2482 0 obj <<
+/D [2476 0 R /XYZ 85.0394 330.3396 null]
>> endobj
-1994 0 obj <<
-/D [1986 0 R /XYZ 85.0394 193.5316 null]
+2483 0 obj <<
+/D [2476 0 R /XYZ 85.0394 264.4348 null]
>> endobj
-1995 0 obj <<
-/D [1986 0 R /XYZ 85.0394 129.6476 null]
+2484 0 obj <<
+/D [2476 0 R /XYZ 85.0394 180.5065 null]
>> endobj
-1985 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F14 740 0 R /F48 953 0 R /F39 899 0 R /F53 1029 0 R >>
+2475 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F55 1311 0 R /F39 1151 0 R /F41 1208 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1998 0 obj <<
-/Length 2985
+2487 0 obj <<
+/Length 2923
/Filter /FlateDecode
>>
stream
-xÚ¥Z[wÛ6~÷¯Ð£|qq%‰î“[{Ótc'»Ýí¶} EÚæ‰Dº"×ýõ;ƒ ‚¢¤œ³öÁÁÌåà >cðÏg:MR#Ì,3*ÑŒëÙr}ÆfÐ÷öŒ;ž…gZ ¹¾»;ûÛ?d63‰IE:»{Œ•',Ïùì®üuþ]’&ç0›_ÞÜÞ^}¿¸}÷öæ¿n®Î<Ïx6¿øøñêæòÝÎB3`fÆæ×7?]¼'ÚÇs#æo¯nÏ¿ûñìê.6ž3‰RýqöëïlVÂ~<c‰4¹ž½À K¸1b¶>SZ&ZIé)«³Û³…½öÓIep–™Š m>ã<1Z‹HÚ$©ÒªãòêöûOï>Þ½ûpƒ«±ßì4Èf ‘&J
-Ë[6]W-]ýØüÕ6•ãþ,K¤P|‡üÈØÊR5/ð!çø(Tj>×é±jªMÑWŽñLBESéÓ'0Ñ6ç<ŸWËÖ>K?61Êù³%·åvYÅÓ¢ •íKµé궡Žöšsr/‚º@üþ©.¤VÒÔ@*V]K­¡üØAZQC-r‘3áÔò¹zíª~1¡>¥’,å^}¿1&VN„eÛôEÝÔÍ#½Ù`0kЃ£SëÔ3ãBÞ€ú™×.ÐêzúA¬>x&ÀsãB¡ƒÚ̹…Z/Oõò‰šNÀŽÞÊjU==è¹{ƒ3¯{ÇW ês1oŸ±»X­^©Ãë‘Þ.oé¹op Ò A ÃQŸêU¹“Îó‘?¬iB`®7Öa±ÕZGJ[§KBÔ "máY2‡ˆT¹ý⃲}ÐàIÆy:KK”‚øœrbZ ¹|Œï#^àÂyÅxÊT%Æðüø”žibÊ¡VRhf’ÇSþ|Î9ŸW›úá• ìL oæ’^ÑëŠ~Kf&eNéFçp‰ãºrÖM಺Y’ý´Æ+*À(z¹*ºn,˜I“œ u\0Ï4!˜ˆ¦ƒð–H²ÛçjY£“YoU‘³k»oQƒ$³ÍöaÄD˜uH:‡ KO¨sÀuDžËªóó”:y’-wè7+O c•ÊñL5T¥án°³EBÝ怤
-cÁÐãÓ\ñã’® ÑâøÙR­bÙÞîöŸèùå{LÝ~&À<QëÆ1•eÝ»Ü@Ïû–¨RаVŞߘf„ÿ¼úZ<JB4í\4zgS´{E}N¶¿îˆV<?WMéM-tÂRmF‰H;
-î¦XWâ~´aô ;¼'
-bûKE\:ã󋆘‡Ÿ*²ËŽ—ZV>;~YŸc1JkÊý«›ŸÍv}ïE«Ýø¿Àßõõå"öV
-ÈË~¸¾¾?—<›7moQèïtÒ!ü¾q¥4cȪ¬€ ù¹úVéo}×Ow Ù÷Ô¶9"p\Û’õOXÁKe‡ÅÄ’‹ùqÅZBvR„¼^%¹SInUô‘;}äóonš„ µþà“ztàMéhì€7ò0h,·’®é]·Ÿ$ RÓNnŸ°…03lãJ6•§ŽÕ 9Ȧß/Ê,K´†â rÆ°ÑÆ¢ºäšZëºÙº}™Óã©Ýn¨…I¡OÔ Úm_v©†+ÖÚ¥K?ºÏÕ‹Ë1kp#n»cÇòDåPfG¸×„ó\áªi„Ë esš„ôtßÀ4`?~\¸À5!]œ²¬æJÅâ|ãÆåBØ |ÖÅ7Ûg„-·ˆ€oøêð¶oH¬þ|vÉ–66¿p/
-‘æÒGd»íŸ·ýâ¡^탘 =cŽ‹¸&ä‹“´,ᜋX@[ÿKžºº# ¤%`E$¢?øGúðàß{?–¿ÓÀö_-ø´½£Ð,ÛMç,BZ«âŒ-½Ó¹Ãš¥°•y/KDAáj3Êàœ‡ªd_öî`Ô],훸XÔÌAÏáyŠ'`'6¿!×aÏ \ÖsžöªÚ4a&;1¥gš˜2ªjyÂ`§ü¸©›Þíø…KžÚSF·]¯‹Íë³:5ô7îjÙÇíº
-÷íÄ]žPÐC„“¹Ó—y
-TÅøÀ&­£ubÌ©3‡!×ëx.kúÔé"¨²Ú@²Ÿ™À†,<.[àš.
-jž')T\±tÿiFAº}¬¾Ôí¶[Ñ¥œO8èä[µË$ž‹®ó½…£Ù À‘‰é¼Äžcã¾f/4“KU0ø'blo„Rz-ªPðV:v;`gÔÝ8Ë]®|Y᧰o…ã,ÜàÚ ùÀŽªãœUÔž,¨…wÝD5fÕ¶ª¡ª(h_Ó%ÖíÔÙÃ.t7‰ÅC_íÝ9ºÅæ<,ÖÞuæ᮳˜ãÖL
-jžXù¾Ô]uàXMW—îÌÊÝlZÍÝ© <­”tÈo]Û6hÊɌŌ;ÿÑltÆò¼*–®±Ÿæà™Úí`Ò£°¥p#¼¾3·}ëˆÁ¹½œÿ±…<5ˆ/ˆkØÛ‡Akr·Üféè÷UÿRQ” ¸£+C"UT_„Ô›»»‘±Bn[ú€½‡´©qûñƒŸsõ^‚†ÓÃÉcf”Àä_[Ñú9‹p|‰¿gÕ´#4MAˆLñ¯züõƒô~ôƒŒ‘º;%Rô®–¶Ø(ÒX±;aeF'DØL]1 4LP‘€ *:­b¾:
-endobj
-1997 0 obj <<
+xÚµZÝsÛ6÷_¡™{°<±@ðcú”Önê¶N|'wînÚ>Ð$qB‘ªHÙqþúÛÅ. R¢ä¤7—<\,‹Ý÷´…ð_ŒtÄ™ÌFI:z4[_„£%̽»Ì3qL“.×wßü ’Qd±ŒG‹Ž¬4ÓTŒæ¿¿ ’à
+$„ãë÷ÓéÍ÷“éÍÃÃíÝÍÕDd©ã·÷÷7ï¯oÿ}5‘:nà ÃñÝÛ÷¿¾ý…h÷W°½»™^ýñðÓÅ̓׫«»*õçÅo„£9᧋0PYªGÏð"Ëäh}ièH)G)/¦ÿð;³vé -DHËcH1"È´–=kè,ˆ•TÖîn?¼?>‰!âQ"E #-NìLL“.—ÛxÀ Ž ÷,·ŒU¦:=¿¥cØRv¶ŒÓ Ñßò‡z{%ÒñÌ€³tœWø›Œw›yÞ2­^æ๜Oõv·ôüѼÃsÑ®ˆTÕDY›6A9QCiÊyèŽÿu¥õ–Ô;Ô®Š†ÖÕ›¶¨«7h»©$
+"&prT^5™MÓ¶ÅÚ0÷Ð °tªFïuX÷\”åÕD©h¼È ;Òãç•©ˆ–·­Yƒ
+Õ’fÚšèÎ*HˉTše>{!B1¶o’=_4.®Ä­bÅØóá*w¾‰Ò1Í~½vÚéñ£!Šu’™Ñè0§é¢Â#ƒ-øpäS+P&ñ¸2Ï8Ðcrì'S9~´ö†iöW¢÷+êm±,ª¼$2yÈìC ‘m^TfçTi2~p‹ý²!6¯)Ó‹04G§CÚ#SÀ}D@CÛߕ錼¶!©©Z
+:èôàÔkk€J’œK;L§_RÇdßÑŸ eZwD$9L[3këíË¡bBFA¨CyV3Ït¬Z×BfA¨ ¬uu›š¶aÃXŸÀ
+ö(æþç蓼ÈÍn³©·-=-qÌÍ"ß•è4»MÔÍÇY#Ä·60C”RvëÅgï^ÌžHª|mzÃÁ½O. TüëŽã’§Z›@pÌÂ8´žBUQ؃Bõöý;ZÜ)ݬ ¹DÆ`gRõÒ‘ËU¶°I"ŸŽÌ'—h´NÙ˜¹O”.£ÒäàßÝÝõ5Í@AÕ£þøãÝÝtÐäí‚&½
+­ËÝšrZ‚)Žß ¥¿}¾æd|ù÷K—¶™0¹´I^qa¦àCUk¶|¬–Nbx2çÓA¥ó ŸŽ–¿^œ½Ÿ†qƦaðIlëI²j]Z SÍ ×Å‚³ýn¶:¿o1xüE]–õ³Õ]@í€øP*V†¶L©)ÚV,f²OÖ×0yùr *$£ñ庶æ’j|ùìGs?Z¹‘=®^ŽÔÚ× ·áý’þ)›^Ð{¸#›WÁË^L¾e¥~‡|?7¨'UCù)«XÓ@F(›·ô0Ï_kbðò²‚
+ÎFU˜(M¾¡‘Ý ¶Ì·®«vÅBû»[’ß/<±]GÔ³1ÝöMßÁ|î\XÅòìƒÃ
+ˆr¥/¤•Ì´ôÓuð›ƒÓs:gtJ!è!êÊ6&¸ß¶²Œv•Á»b!ûÆU¼Ûe0¼<™À¢0„VÙùÖå:À<—M`÷¯&0T÷›za-q˜ÅTÕHÎëç¹ìe1•Ø@÷äÔŸ9Ϥ™k€d[ƒl_ˆÂdN*Cá¹p«kú}d!›ÝcY4+ëÇδßäsmb$³ñÛD>7mC6+íWèÖð¦6·é$H¤Š†:Ftö£qà™•»ù!”<?Sd·{UÝö…í'È¥Ã^f—(O"KAï/³ø•Ò¨ËuYžË"ëí«mÎ9`A¡Ϫç¹ôë+
+ƒ,…¤ßS%÷ÏZ3²p„ÈRÐ}3²z\ÔecDqëkú}d†CöØ
+rmEÍ ¸¶Â–-'¥¯­º\T]Á pëkúµ®€EsSÊ*¾€²"lÅ;ÙV(Ë^†QŒ˺Zš­Ï…Þvô0õqŠcö-.Þ­ó—nH\çná‘
+endobj
+2486 0 obj <<
/Type /Page
-/Contents 1998 0 R
-/Resources 1996 0 R
+/Contents 2487 0 R
+/Resources 2485 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 1961 0 R
+/Parent 2457 0 R
>> endobj
-1999 0 obj <<
-/D [1997 0 R /XYZ 56.6929 794.5015 null]
+2488 0 obj <<
+/D [2486 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2000 0 obj <<
-/D [1997 0 R /XYZ 56.6929 751.9327 null]
+2489 0 obj <<
+/D [2486 0 R /XYZ 56.6929 751.9327 null]
>> endobj
-2001 0 obj <<
-/D [1997 0 R /XYZ 56.6929 651.1304 null]
+2490 0 obj <<
+/D [2486 0 R /XYZ 56.6929 503.6095 null]
>> endobj
-1996 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F55 1037 0 R >>
+2485 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F55 1311 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2004 0 obj <<
-/Length 3048
+2493 0 obj <<
+/Length 2264
/Filter /FlateDecode
>>
stream
-xÚ¥ZKsã6¾ûWè¶tUÄÁ“ã¼k’]3öÔnm’%R63©ˆ”=ίßn4@IÕÔ–€F£Ñ/˜/üñE¢C&SµˆSjÆõb½»b‹èûxÅ-fé@Ë!êÍýÕ«2^¤a‰hq¿Ì•„,Iøâ>ÿ-x}{ûþæݧÿ\/…fÁ›ðz© þõúæëëíö:Áëïï®—<‰y  a ÞÝÜݽ»¼ûôñæ¿ŸoÞ_ÿqÿóÕûûŽ±!óœIä꯫ßþ`‹öðó ešèÅ3|°§©Xì®”–¡VR:Êöêîê×nÂA¯:& ¥“P -–Z…RK5.22 "XÆ
-VRÐr"|Ld…"[~¾ú õ
-˜ìãȲ‘­êŽ#â¦Ïv£;Ã3ñ(0bhÌÍPÃ;N#29»'ú,“0¹³ú΀H.‚f_¬KÔO³+8ÞŒèv*Ó~.«¼~¦6™W>—FZ@3Û†_²ÜUæ
- *†B†ãÙYv˜så Ú*²ÓŒÉÓ[„ÔŽæVuÓU=»¢â‰(,û®v™Mg–órsj–2RRDÊh†2B`8#&°di‡tARØŒ°jRCüZ¨­Œ.°`A#ø•&<V> Ÿ†ñÓHÌ´M‡}ùð–<M„u’ÈŽv)­›á‚¥Ñb¢n7î
-LÚ&Èx ߆•.jíæp|Mì/RâBÄ8DÍœŸC™óû|)®€üb¦bCHcgùs þ¼3L8Þ#é3HõÚ˜õõÚ˜S˜»ÜÄ$µÝ! Ðï®y`Ì’º1.ÈÀ¶ 2"èv»U:dÄdCÀpdÌ×wÙty×èÎhT S¸ú?ZÞÓ/‘ª²Ï CÔ´~u(£_ûÓ%¡W)uaIYr¸»²u¡O–üŠuO`$Ø7Å1¯—TŸ@D÷Y›Q糩óI[k&íH•Õ[uÆ°SI[÷–¶Ö¨MÖ´]Q œj°2ÊJC†Ú–,†òPì²Îñ6I¡Ô–£ÿ8Tû"†}´]qìŠñ±ìKÅ
-êDÄ#¼ÿ.áŠQendstream
-endobj
-2003 0 obj <<
+xÚ¥ÛrÛ¸õÝ_¡7Ó3! € ¶OŽíõj»+»–2í4ñ-A7©);Ê×÷à*R‚"§ϘàÁá¹á\!2ÀðGœ!eñ ÍbÄ0aƒéò ^`ïÐ"…]¬“³Ë_¢t¡,¡É`2ïÐâsN“Ùçàêáávt3ü÷EH>¢‹aüq5útõ»†=\d4¸º»_„„§$$.ÑÜŒÆãÛëp<¼ýç~t{ñ4ùíìvâë
+Op$¥úëìóÌ@‡ßÎ0Š2Îoð‚É2:XžÅ,B,Ž" )ÏÆgÿt;»êSŸ1XÄã4õXƒÒŽ5†uœ R–¡$¢‘²Æp~F4 Ú…‹4ø*¶R4ð,ŠêEƒÑìÚîé÷¼ÒïâÛª,.H0-Z h6Ó©hšzÝÿ.¯j`h€’#!$ø
+ÏÐÓºš5Š?Ä 8kÎ!Q†“dÆq–eJª‡Çáh2Ýéïï&ÃûÑØ}¾ aP†¦(N}2³ª^!øX[,…Áï†|’¡˜f2SHôinÌ˦֫g£â¦±J´fgµ.ªvÏÀEå­~›ƒ·óåãÓœßPÑѱ¯ rt21 Rs‚!erz$ߤ°‹¥3ñä{‡%µ7û,!KÆq|‚¥Eò°ìZ8“f{,:¶ƒƒiúîñid‹XÕSc¦y½^æíQë°”"–2þcët±Ž[Ça)무Û0Ö­ñŒEÆm®/.¯./‡—7—yYî‹Hx‚˜¬M?”Ñay„ì©ŒÀnÆûRZƒÊÒ!<±^ÈhjpÇa‚u#ô†J²‰VïÉäyä Ù0Â4˜,L0Å]ûQˆ&ãÔ˜ÅZ®/~Œ(ÅÜ Ô+Už4»|«9=+Úƒ0JJ¤•{ùi—ù!nUæ—O•ùi†µ6
+z¸…1‰XFúÇ¥ùöËgOGÕ~I®ºýZû¸e’`ËýÆ«kœpÚÓµËs&Àç{üdhLdoXâd^ÓòÌ÷(Ù4ñÁJ_jˆ¨8Þ¥(šê¡èC<|«qý]B ežÇ„Ø6A§Áñí­–âê÷ñ½‡²¿=€Òû"ª/˜aÿˆQÄöÅKõÒKg[Ѳîy¤Ñ,³iíãpt£‰dFœôEÓ®ó֞ģ˜ëÎYTScÉ?òj“û BŽh’ØxõI
+QÝ}t'1sñßì&
+K/îçöâÑw…#ºË3àÑòZÈ3¢q±Äæ=yÍT
+wOgîîr{ugÍbZjtìG!H\ò—OË‹],ýß?í~ƒúqNý×l†™$‚ÙÝ%Õ„6x_t÷ÓÒ¡ìÿ§ìÕÅendstream
+endobj
+2492 0 obj <<
/Type /Page
-/Contents 2004 0 R
-/Resources 2002 0 R
+/Contents 2493 0 R
+/Resources 2491 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2006 0 R
+/Parent 2457 0 R
>> endobj
-2005 0 obj <<
-/D [2003 0 R /XYZ 85.0394 794.5015 null]
+2494 0 obj <<
+/D [2492 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2002 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F55 1037 0 R /F22 737 0 R /F41 939 0 R >>
+2495 0 obj <<
+/D [2492 0 R /XYZ 85.0394 655.2256 null]
+>> endobj
+2496 0 obj <<
+/D [2492 0 R /XYZ 85.0394 487.8207 null]
+>> endobj
+2497 0 obj <<
+/D [2492 0 R /XYZ 85.0394 419.4946 null]
+>> endobj
+866 0 obj <<
+/D [2492 0 R /XYZ 85.0394 376.8649 null]
+>> endobj
+2498 0 obj <<
+/D [2492 0 R /XYZ 85.0394 338.6766 null]
+>> endobj
+2499 0 obj <<
+/D [2492 0 R /XYZ 85.0394 305.0527 null]
+>> endobj
+2500 0 obj <<
+/D [2492 0 R /XYZ 85.0394 233.8048 null]
+>> endobj
+2501 0 obj <<
+/D [2492 0 R /XYZ 85.0394 108.6677 null]
+>> endobj
+2491 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F55 1311 0 R /F41 1208 0 R /F39 1151 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2009 0 obj <<
-/Length 2546
+2504 0 obj <<
+/Length 3157
/Filter /FlateDecode
>>
stream
-xÚ­YÝsÛ6÷_¡—Nåi„â‹ùè6n.uëäFδwMh²8‘Hפì¸ýíbˆ¤h%sw£‚‹%v±Ÿ?@bÆá'fIÊÒ\æ3“k–p‘ÌV»3>»ƒ¹7gÂó,Ó¢ÏõÃÍÙ÷?)3ËYžÊtv³î­•1žebvSþ1ÿ¥ìVàó××Ëåå‹åÛ7×ÿ~w}y¾™f~ñþýåõë·¿Ÿ/d˜9Ÿÿzqýá⢽?ÏåüâÍåòüÏ›ŸÏ.o¢b}åW¨Õ_güÉg%ìáç3ÎTž%³'xáL乜íÎt¢X¢•
-”íÙòìŸqÁÞ¬ûtÊ:ÉX"u
-fÑL›4Ÿ6™`F`2š3ŽìÁdRL™,p¡É7šj–ç"›õ;˜&DʞȆF‰¡È·wuóp.²¹%“_-¯hð‘sUÜѸ©éùÉ>Óàic=©´}ØUuUß…©¢£Q×г­îjväAo&Ã3¦SPþ´-{\'l¸œ-Šüþ§$éq
-ÎL–'°:²´Å¶ë• 
-Áò$‘nÁ.†MÂõp£ªÔ­U’4ŒÇ;2o Gg9xãЙøňL1´úBDö¹^ŽÈÈå"òS‰Ìx«VÓ½©Û±rBq–˜$;­]äšP¯ïK¡–$F õûíE#Ó&Œ^¦ŽÚµ/U·Q©Ÿß‡”v]ìÇ.œ¿ì¥˜‚ærÚ/¦nñLÎ+G5×0“
-uR^à9–×·³‘Ìh™ä‘••ÌVÆ÷‚ÞÊ8ôVÆak;¸€ÆÁ»÷7X·ß}¸¡÷P°qÜø¯ŠíöhQªö+ªúeëë’eCϺéZRòf,KÌ0q{Aq´2×ðêC¡µ«}¿×”vkïBp¼àô$ËY–ªÓNï1½ìôÀ„JÿÝÔì%·ö¨þK–¦&?)7ðËTÃR @£/7¿N¹ÔÔ]Ñë ±d¡–Ó•[ª-_6 ¾`µ× ³.ÔÀH¦Q8ý™iBæ _2&31’¹¼·«jõ$…–¸©V‚.-ÚM³ß–4v‚§ï )u!Ç6ó”gBcYJ²ùÛ5‘êf¼zCAeÐy¶|ã¼å–5Ãe½º& × ì Ì(ƒìç
-o÷Õc(|¸-´à«ú£È†:@kÖ¾þ—•ßb×<<Ÿ !æ¯â'‡C§ñf„±Þ ¿AOæ± ôРÜz¶Ð÷x
-dyî%”u åzKÀÇú,¢ÆLçC§#ļêí„}]é;a¤6!&ÈÉ~°€ÛÇ·Ø‚2Úž‹ù³ÙíÛŽXn=«k„™Ï2$슰C9E†ÊÕýý)e y[Þ²ÓöÎK³TöànÔ½j Èj)ą̀E°
-ÎC‡G×â‹ôûY„.„q@÷4óX5ûvûLSÞÖnv(CoZï¬ °¨½t¤ÓÕŠˆ›GP(ø
-§ýjeéŸò^vû[Cþ•RS@ãˆh¡Cf¨ìyC/tq¹7»ë‘Ja<tÁÌßw†o ”Їp„“ힺqo¶£Bá‡5º©ºÊtt]4F‹TŸ”Ñz’°=<û‡öêð=ÜICHòÝ!¼D
-™„ùåýOñmëÒ«D7#>ãjApOq 1%'Ú ~”õ`T„_»€Bâ[Çt{ú@‚Z?´½6žV„ë‹€‘ó¬ÿÃ…>çê{éÿO•0üÓrâÊG@ð?ÿ7zøXþ̲.ï¤I|œ¥Ð”B¤Çw”œI'ëcÝÿ&,±&endstream
-endobj
-2008 0 obj <<
+xÚ­Z[wÛ6~÷¯Ð9û"ŸV(n$öÉMÜ4Mâd+·ÝnÛZ¤mžH¤*RqÝ_¿3€"$JÊž]û 0ƒ™o.˜pø“$e©•v’YÍ.’ÉbuÁ'0öêBxšY š ©¾½½øê;•M,³©L'·÷ƒ¹ ãƈÉmñÛô[fØ%ÌÀ§/oæóë³ùëW7ÿ~s}9&ÙôêÇ뛗¯ÿu9“ r æ|úîê槫·Ô÷áÒÊéÕ«ëùå·?\\ßöŒ ™\!W^üöŸ°‡.8SÖ$“'xáLX+'« (–h¥BÏòb~ñÏ~ÂÁ¨ûtT‚3©R9" )&B0›$2GbYª¤râxÿáöõû›Ã– ‘N2)X*„9²2͆Taá‘cT¸î,ß_2ÕÌZ=¹d YR–L¡™)/ùó¥bZnªûg:Ç|¹¤ÆCY—›¼+ zm«‡:ﶛKa¦eËŽÉ&µdk²Ó²R—MOåd³À%¿ú.I”î”ál¹#Y,ó¶Ýg̦Ì©O3ˆF“Ñr° æq6_—‹êwÎeÙ’¨ºÇ’`LÔ Î\³¹ß#ú»©ËãâLAÉyrNœªâ TNœ/T-c’+}zÉ@4²äPP™dÂh/ù¢Y­ó®º«–UʦR1]5Eù5`‰ÓW^Ýh §ÃÖÃ} m•„ÓþX>·e7óZ¡„Z0£•ðt(ß:_•D± Ô" „x„K¿~U{>Š¢êªÆ½Á™5#lÉŒµÖOR´G˜R 3iÏüg3õôXÖH4™i®@ç,Ⱦ‡/G³¬êo»;ú’š÷͆ÛÖ«Û·ófY”~ìS¹ia;%¦"Ù[Á„«¢†m.f¸8.6²‹LƒÒ³D\¿EtYrF¿T'ô;P9ý.ÆàéøMT›rÑ5›ç}æ„”LÁa殧a/ ™1•f&æïmÓ|ÜÑ¡Vip}Ù˜REs+ÃT^ŽÈF'Â=§‰3šh*­™R
+CªãªÐS9U¸>«
+eýP‘GzÀ5ƒ`Ãœf­§á-v–i†1÷Së¤ NWØébó¼œq]¹s·Å=K¢ø'üýº¬çó·DFÜC· w2z $=»Ií´Y#Îz{‡±ª£g»]¯›M×"rÈd7IU·]^/JB!PfƒìAHÄ ¤¸˜>UÝ#µÖ›ê!:¼ æQëÞm¦YÑ[N€“mؤ'÷ U®bNªé/ˆndþ¤Zb|/ûáÍ‹ù?„ÀvE#•¥³
+"I+ÎÃdÂ2ž%L‚ffRO¯ÿªÚŽÌ
+„“ÒX
+Êï=EN`—ñ캜mr
+Ø—¯!>+ÂQË„ñ4±ñYØþ.8(ìù£:¡R ‘%„Ú'ubHu\'z*§íÙâ ‰›n†:{è Rð™\f¯§á/R L<Ìp³} †à>.4
+R®üIâXµòƒ.³Ò«¨äý?þ8ýŠš^;ï cå?ý”/«Â9‡ÄCR,ò:’*$œqƒ7T…BW—‹KT9ÿ¼k›åÖ±ÁxãG‰%„ïŸJêÁý0Šj¯j"~ªé\v´ÔrüI4’¢º„HÚïz\y@’mÁ£Þ®îk•ŸÿWø{÷îå^Míå÷ß¿{7ÇÐ< 8G—h|ƒ#¦’ÊBë„s$Q–@ä"= úk|†~ºÎ^PÛÁ*P¼s°
+Šwàg•ÒnZÄb!§WDK ÉI#!‰ñ"1N$½<Œ—‡™~qãò" jS¹ aðÉ = …iêÂ÷í’|# ƒFìàq$œŸ¢˜ºêf4݆PœÛQcÛ¯ó:»H=i`2
+Pœ.ª,ƒX.K÷$r4ñ²‚Öªª·>Éôxl¶¾˜„8°-_.›§½BÔbÙ,|å£ýX>y°Åt©í+Uǃ]i þÌô™zÑê8ÂõTáÊq„Ë Êé‹Å8¾ÁÑÀù‰ÓÌõT#ÜÅÁ.ÀªÑ:f¯Ç7a½_Àᶾ¹1wHØ"|‹èø†¯ß„å‡ø†å_ëªÏ½%t\ù—k訂t ´ÏPÒR²¬O$¼FjH !ÎP±F:HüàZ"{m^qDd¹@PùÏ<\õÈ„}™ÐòD‚¸½»)÷p—k<Í£' ¸XCǘÕcVùJ¨`—롺nèu*Ð7
+«™6É^EÞç}lÌ@RHš„üŒ r¦„ÙÕjÛz¾ó
+Ú7`‹X„ø0Û-ç5‰>tÚˆ+6ôN)ƨ’Át_¢bZ¥„4ÊŠÃÛ£²8z±Êa¹JU»Í’¿ÇÍ¢dŽjŽ€ˆD[y¦21¤:®9=•ÓœÇƒ¢fʸÍÎ,ˆF–ŒÊš‚qpÿñ’6U
+¼þº­}l6^ívµÊ7ÏGÒ8*„k±N…§‡íª¬ÅçÃ+8©- Þ®Øùÿº‚ÄÊ({&¤R8@åN§:WH
+aã®F]´’±ÐøGl¯¾¥Ö#rÛÛìL™”Y½»¡!Cµ©8h÷³“çÅ2¤Ca ÷–{ÊÜOª÷LTlÙËvðÚ à¬¤öhÂC-̪:Ê0`tq²¡œæ ¹¸Ü¯¨^»Àù6à¸ïÉ_šÀA#lÖˆ~³xxÆ߈Xš "Œ»cÒ«½ÇŒý©jË#ŸÀnÚ
+/Øñ˯ÜÐóί긤»{xk›¦þ’j×y]ŒFZdèò`ø
+ø2_øÔÉ}jð¶Ùî<˜€°®w)ÂÊ ìß·{k‰À«½šþ¹…ø%ˆ/ˆk8Úõ“V¤~»xWèúïÊî©$+PG?$¢®’²Ò˜>¤Åæ® º/¹+æ»÷T}«}!åÐ~’„Y#ôg^ZksæBÝZó¹™xXswƒ ïçâ{hš™þ/~k‘1%Upø!ÉkýZÑï¶Bõ3ïŽýLO% [7¸¼ÿÝÜÿü¾Ý5ðnŽÕúd熞×3…Û ?ôdþÇ~‡¼ÿŸD
+endobj
+2503 0 obj <<
/Type /Page
-/Contents 2009 0 R
-/Resources 2007 0 R
+/Contents 2504 0 R
+/Resources 2502 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2006 0 R
+/Parent 2507 0 R
>> endobj
-2010 0 obj <<
-/D [2008 0 R /XYZ 56.6929 794.5015 null]
+2505 0 obj <<
+/D [2503 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2011 0 obj <<
-/D [2008 0 R /XYZ 56.6929 485.757 null]
+2506 0 obj <<
+/D [2503 0 R /XYZ 56.6929 752.0497 null]
>> endobj
-2012 0 obj <<
-/D [2008 0 R /XYZ 56.6929 207.615 null]
+2502 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F55 1311 0 R /F41 1208 0 R /F53 1303 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-2007 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F55 1037 0 R /F53 1029 0 R /F48 953 0 R /F41 939 0 R >>
+2510 0 obj <<
+/Length 3243
+/Filter /FlateDecode
+>>
+stream
+xÚ¥ÙrÛHîÝ_¡·¥«FLŸ<ö-wef×ÉÆNíÖÎÌ-R6'©©8š¯_ æ!‘r¥¶üàÝ@h\M¹ð'‰ …NÍ"NMh…´‹ÕöJ,`îý•dœ¥GZ±^Ý]½x§ãE¦‘ŠwëÁ^I(’D.îò_ƒ—Ÿ>½½yóá?×KeEð*¼^Z!‚¾¼ùòòûtªàåû··×K™Ä2¤Ñ"¼¹¹½}ûzyûáýÍ?Þ¼½þýîç«·wcCæ¥ÐÈÕŸW¿þ.9œáç+ê4±‹'ø!B™¦j±½2V‡Öhí!›«Û«ufÝÒ)aX„6Qñ„4”HC
+›hÛ4Œ´ÒNÙþZ&A×qð-Û”9£`]ï ¦òìØüC#‚§²}$`F8«ãjS¤¬ÚbûÐD½&hZà. J-¢àî±`ÚÒQÃ!(yYViYñ½lÚ²z ðçÏ š e+Zž7ôg倄–R†©µÊ7?¤ã¶¦ÿÅ÷]Ù‰
+ãH(–ÅoJ™¶øÞâÆ@àR+=²°"/ÖÙaÓÂP2©*Ÿ Ip=Ú ¨ì³§9"q(eâ9r³X…ÒDrlÈw%Úgjƒz×–uEcÛíËm¶/7GÃ¥¬ò"§_ÎôÓˆ¬~?C—ù±Ê¶åŠ~4åCå1PL£©y»GÔxÇü°ÝÑŠˆT6º‰’Eˆ
+ÄûÓ¥3äNàgUWKTýò¶ãU]µYY‘'€‡]žµŽ!œt÷÷¼mÇ8`æ|ËW-EJ8/”’ "2HÎgÁŠ–$Œ/açµ'WÕ픇Ùf_ùöo«G5EÕ0D <d/f
+²ZÑfÛîÉÆ]
+Ðú[±ïé…bÀ %”)ÜžleÒîÓ//>eЪ\lhËÿ›ÚãAXi|l &Ú†~»ô7kë}ÃûT9/‡”¶Ø3Öý‘'R
+¸–­:ÍW=û*VŽ}ôZqì;ò±îûÅ€°ÍŽ4p®&¡jZÀð7ô“Nƒ¾ 5
+XÌÐc9;ü4k‡—Hö†xFrÒ‡$ß”MvïCÁ®nÚ¾SÅmHÐS­í©¶hZJ˜Ñ÷¦È¦ UÚa§û! ÷£QQ5ƒ',änLQ=Œ8T§Ø×z¨]G¸%owh˜þ Mƒ?KÞÓï¸)2O—Js˜«êjÊ$¸%\¥f·„»³Áð©þQ ¿ÜþBÀ¯øˆKÝj ÐQ÷*HÜ\W~SÀôû*¿ƒ„Ž úé]9hbG–;s‘œ'3jÜKzaŠ¨!:ѹêS…lØ­ìΊ©ÁiÝÒiƒ³¾ÿ˜4ìzÛi¾–»î!¹ð¯@½EM]8iL¨°×qñ ±æ/\‡å.Üþ¹aòm9hé¬^Ä[$Õeæ:¬ îF9~Ö ”³7îK Ÿˆ±#à —hßî߈0ŒëÑJÀܹN³óî¸ÑâÄ–¦è)G.ÑÄijéÖßÊœ—gO
+È{òÞ5ÖªèBsîŽ Ò§qo!ðoõ˜í³=‡
+endobj
+2509 0 obj <<
+/Type /Page
+/Contents 2510 0 R
+/Resources 2508 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2507 0 R
+>> endobj
+2511 0 obj <<
+/D [2509 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+2508 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F55 1311 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2015 0 obj <<
-/Length 1499
+2514 0 obj <<
+/Length 2925
/Filter /FlateDecode
>>
stream
-xÚ½X[sÚ8~çWøfŠª»íÇ”Ð6Ý–dÙÝ™6.ˆÄ-Ø]Û$¥¿~,ÉØ `ÛÙÉLÆ–?sô+"†?Daó Œ9˜ˆ`¾îá྽é‹:аz5ë½|Í F±¤2˜-[²"„£ˆ³ÅÇþÅÍÍxryõ×`Hî¿Bƒ¡À¸ÿábrwñÞ¬Ý bÚ¿x3ž†$”Œ(Ô0‰û“‹ãËáèíxôÛèzòzp?{×ÏÃÚÆÌ´U÷>Þã`gx×Èőžá#Ç4X÷¸`HpÆÜʪ7íýÞl}­·úÈ,B"¢¡‡ JBP,íÐ!b$e5ÓñØœúâýôZŸvч8€¯H
-Êkø"+K5~UÛ•}ÂGð¼0YÜ&Ÿ ê@€Þ÷êjriôÄVÝbfiYI•féV-U1 Q_ese–>$Ù&YyÌ"2BTJiÅû à(Ž³€Û×##lbyœ ʱhdú†4(Še ™D!COw³·×·ç™»Ê*Udª2fL·e¥Ö¥yåY™UºYïôrĸ¤VXE46L¢âCÌfÉZ-†óG5ÿ:ϳ¥Þ«ÁL &Cž
-Ö’NqŒ(©m¬Ó)-Ô`k CG’6!i¥.Ó•ÒÆ8?îý¡*Š8]n/ÇÓÑíÕÍìêzÒìòÄ«ÿȇQQ-šZk¤ èê±/ÌËç þ,¯öqjdU:/-4·A˜üLú³ÖYÙaâº&azP¿mˆ0 ™®œŒ£6Ê•ÛÃ8jPZïðq_%”lÎù•äQÙvH#®ã¿£ò¦H³}º7eòà˜ß¬× ÄŸ¡;³,«ïi…Ž²†GŒa§…:ÁŽCÕ츌íC!BEèË—¶m„‡°äœ4®Ay¬ëtAQ̹ìš7z¬»S®£—á*š'k¹€f,C~w”‰¢°9Y™[¡‰ŸfóÕf¡Ì ª;ã¼JŸTiÒÏÜ.‹;H½è
-´~NŒóòÍh® ©/êþÁ‰¥æÊå—ؼNmZƒ¨¿±¹÷yÛIÕ2]§«¤Xm]pœ¹®sùhlј!"ä™Ìk£ŽÇVƒªcëé ó˜îægT:Ge'ó"ðe¸§Ò—yOª(›²åªœþzXa€„¬ÇnÄùÙzl}ûP$ëŸIn*AJÄÏ9 …:á
-ñ®Û¦Y%Õ¦ì#Ò qU˜z^Xسr\¿-T£k±M¥ÇV$„Añœ–ÿnBå^ &¥u°kõ†)“Ý'® ×…žðÿç¾
-endobj
-2014 0 obj <<
+xÚ­ZÝsã¶÷_¡·Ð3?Ú''q®—Kík¬›k›ä–h‹=‰tEÊ>ç¯ï.vA")·¹ŽgLp±Ø]ì.?€’3rfâ0ÎT6K²(4BšÙr{&fÐ÷öL2ÏÜ1Í}®ogo~ÐÉ, ³XųŽ'+ EšÊÙbõKðm˜†ç Aß_ßÞ^}7¿}÷öúŸ7×Wçs™&2 .?|¸ºþþÝßÏçÊ`f!‚¿^^¼ü‰hÎ3\¾½º=ÿmñãÙÕ¢3Ì7^
+Výûì—ßÄlsøñL„:KÍì^D(³LͶg‘Ñ¡‰´v”ÍÙíÙß:^¯:ê )B¥c5â ¥<o¤24Yff‰ÉÂX+m½ñi]T0)9>tð¹x¡÷²¡ç}½¯VØ΂²mˆ«-·eõ@ Û¢ÍWyËãÝ°âK,ÅŠÞÚšzWE[ìNäuýÌÊZêoÖõ~Ãcî˜ißN¾\Ö»s™«9ºæ?—2ÌŒQv2dȪÃ纠Æ}½ÙÔÏ]ÿî< ö›¢Øj)‚«|¹¦Žf¿\MS>=F––.j>îÊzW¶/ôV?»#…–{«¢ùÓq¦$)2U³DÆáD`#èùÑ »`Î=#!C“Š¬Ó‚Nzwf%2¨jzv¡„¶Jx[ç 5î
+›$Ðj
+ T‚Ýñp;ch`âH) U÷é¶Q²´ÇýݦlÖ65\ ú½®¸•W̃)À\luS>T6pf:6ýD耲Â)ßÇIj$Üù¾„)ï§=ûýLÿ|ã²
+=³ÌÛ²®ˆ
+’ªâ™(
+q]²Çr¦/ëí£Ý`«iˆ8Œ²W¶é„?˜Éºc?pGŠ,9­Ïñ õùÎH$î*}} Ej×·Wß½Áß“`¹Î-V€.®@Ðâåp(DÀ˜S/•§²Þ7›¢!Ÿ-ÀF°l«,øtn`¯h×ÄÔR9„•C,F©&±4Œ ‡q¿zt
+Ra "µpÔZæ5ìf+³yF<YO£èìÆhÄA’a.cêâ-,'ÔéQ}õÙ%ƪFª ð˪EVÓÓÉ…&+ƒÖ
+êøùž‹¦2’ó]¾Å #¼§1‘ì|Œ[I%7£v3í
+~NjØ9²à+m «ªiŠ¥¶ ÃqR%0H=⧊ƒ*ȸ3ÈÖ~ª0“i4Q½òŠË2ŠaQù…ÏeÞäºÔŒ‹dtzaú\Ó+³ã²Kói ïÉPGIÄÓßOÅ
+8„ô,»-ÚæU¯Š»ýÃCçPkØ´ËDª(Ó¯¸Ìã:á2Çe]öePÍ ½ N«tL#*{Åš‰–}•7•-=ÒðYCKEÔahÿü3 Ÿ×–´PÔ+mH€ZQ¼4íè äz[¶-y»§älHž‡%áß#¡ ‘p!¤Læè4…×#„{wYå¶Üä»á•ípgÎJõ×0<pvŸ›Ïµu)š?AC•|T†ÀŠC«ŒV†šc!‘®zTPV#ò5^zhW3B{ƒ3‘š
+¶68⼂;|®éÔì¸ljþ>•š'Uv©9T9–š=•ï: Jàøýí{lDp¡ó>0Ò§8tÀ¿ûÀ
+zó¹NDÆqÙÈ\¶ÈpÔ§U:¦•½ƒƒ
+¡êÆ}•ììL÷m¯¯‰îœ $wJ
+endobj
+2513 0 obj <<
/Type /Page
-/Contents 2015 0 R
-/Resources 2013 0 R
+/Contents 2514 0 R
+/Resources 2512 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2006 0 R
+/Parent 2507 0 R
>> endobj
-2016 0 obj <<
-/D [2014 0 R /XYZ 85.0394 794.5015 null]
+2515 0 obj <<
+/D [2513 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2017 0 obj <<
-/D [2014 0 R /XYZ 85.0394 752.1815 null]
+2512 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F55 1311 0 R /F41 1208 0 R /F53 1303 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-2018 0 obj <<
-/D [2014 0 R /XYZ 85.0394 689.7995 null]
+2518 0 obj <<
+/Length 1899
+/Filter /FlateDecode
+>>
+stream
+xÚ¥X[—Ó6~Ï¯È §Î ]më1ìX.Ë–¤ç´xð:ήKb§±³~}g,ɱAK{òYÍM3ߌÄÆ~lœ(B…–ãXK¢(Sãl3¢ã;X{1b–&tDaŸêÙbôô¹ˆÇšèˆGãŪÇ+!4IØx±üLonf×—W¿OB®hðŒLBEiðvzýÛô™»™hL_Ìæ“Å‘@¤‘,¢Áõôíì2¼x9»x}ñîúùäÓâÕh¶èë+Ϩ@­þ}øDÇK°áÕˆ¡5þ”0­ùx3’J%…p3ëÑ|ôkÇ°·Únõ9Cª„(.£qÄ’j¿Ç(¡
+<Æ’ªùÑcœù<æ¨ÐcŸóé¡Œ2ÉxÜçv&ÓydòžLF#ñD …ηyV¬p"Q|¹/²{3ej3ªï«ýziÆ·¹ùß×¹i*KUÜ•væÞ}«ÊÎS¨$¸Z™©²:åžî&, 쎕ùH)Ï—O`&¦È¬eÙZu‹õºÓ <7D°ÁÑJñÖÀükº)ÊV]AƒUµƒ×Áåõüõì3iTȪöY‚´1‹F. ¬\\Úæ_Ñ0*a0Tµ¥;Zó«j_ZÑ©
+²j³1N„5”_›!ÚÝ2•I?Ü!K9M$pwa°]ç˜x4ˆ"’HYZa\ÑÜáSêr>5L×vp——ùŽii(oOzÚDà’Dk+aYÖuž…À6{ô A¢©‡±ü‘*úºg yL©xÌb.cXbž<
+žåYºÇÃœ3TGN1«L8÷hÀ8‰-IµmŠªDŽ<(jó_VÜæí¡4 -!m4â2zó»Çä=Ž6ûºÛnù–!&(èÀéI>oÒºÉ15 *Ö¹+jào©â$Vw~¿%?„D(éÈ­S¥`”h7
+*ʇ*K?ð{]UŸífǹ
+ŒC½H˜ó厾ñˆ )´N4š†).¨MqíR\³“×ßIqÜZWnkÚX¿jD…ÊåÜ$ö9"¢¤åŠÍ¶Ú5*´ÄàP%vt<“aôʼn¹Š\üÝù‚$*ŠçpîÙA!U GS 8CénÉMÂ,·I†Ha2'A˜ù¯Ì?Ì®aˆ´s™C6±ø\ôáõ-A¥À{žü
+ë>‹ö¢+}—ëŽÊë!LÓáý'7zèFv#Û¦)ÑãΩ&œ©®†;‹MžÞSBÿÚ¤åº*Ö9*ãdl;iß>ùC6$‘T ½|9›_¼¿ºY\½»öÔù“Àõ„Ùyß«så«¥ÄF]0ÛÇ ØUb¥Ý7fÖÜt9ÜÒš"«-iµ2©GOèî Ã7•^ÙôµÆ’ð¤ëBN#™·Œ-Þ -Œ6¬ mÔÌÄ$øï§òØ
+&Ð «MüÌMͪv­É<ÒuÕÞˆ˜«°H•â­§lko>Š2[ï—NÜÍlƒ×µï ¸NŽ{-‘e1x59B ×Huû4o²§ÆÝÊ àýDïâú1ÛZˆ¹=ØÒmZ
+ò½×;@9|ród:íà¿ìß0%´VIÂýc‚Z ÍœRhSâTu%¼oÄÝÿ$_Éendstream
+endobj
+2517 0 obj <<
+/Type /Page
+/Contents 2518 0 R
+/Resources 2516 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2507 0 R
>> endobj
-678 0 obj <<
-/D [2014 0 R /XYZ 85.0394 651.2999 null]
+2519 0 obj <<
+/D [2517 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2019 0 obj <<
-/D [2014 0 R /XYZ 85.0394 618.4832 null]
+2520 0 obj <<
+/D [2517 0 R /XYZ 85.0394 672.6222 null]
>> endobj
-2020 0 obj <<
-/D [2014 0 R /XYZ 85.0394 583.1153 null]
+2521 0 obj <<
+/D [2517 0 R /XYZ 85.0394 403.8925 null]
>> endobj
-2021 0 obj <<
-/D [2014 0 R /XYZ 85.0394 517.8114 null]
+2522 0 obj <<
+/D [2517 0 R /XYZ 85.0394 340.9183 null]
>> endobj
-2022 0 obj <<
-/D [2014 0 R /XYZ 85.0394 458.3941 null]
+870 0 obj <<
+/D [2517 0 R /XYZ 85.0394 302.0073 null]
>> endobj
-2023 0 obj <<
-/D [2014 0 R /XYZ 85.0394 396.012 null]
+2523 0 obj <<
+/D [2517 0 R /XYZ 85.0394 269.01 null]
>> endobj
-2024 0 obj <<
-/D [2014 0 R /XYZ 85.0394 145.9047 null]
+2524 0 obj <<
+/D [2517 0 R /XYZ 85.0394 233.4614 null]
>> endobj
-2025 0 obj <<
-/D [2014 0 R /XYZ 85.0394 83.5226 null]
+2525 0 obj <<
+/D [2517 0 R /XYZ 85.0394 167.5653 null]
>> endobj
-2013 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F39 899 0 R /F41 939 0 R /F53 1029 0 R /F55 1037 0 R >>
+2526 0 obj <<
+/D [2517 0 R /XYZ 85.0394 107.556 null]
+>> endobj
+2516 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F48 1228 0 R /F41 1208 0 R /F39 1151 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2028 0 obj <<
-/Length 2089
+2529 0 obj <<
+/Length 2010
/Filter /FlateDecode
>>
stream
-xÚÕY[sÛ¶~÷¯Ð#=¢¸À£ë¸­{N·v§¦y %ÚfB‘ŽHÙU}7Š¤H)N|δã –{ùv±ØÉ Ã™‰%šê™Ô LÄl¾<³;Xûþˆxš8Å]ªo¯¾ùŽÉ™F:¡Éìú¶ÃK!¬™]/ÞEß"…ŽŽ.NÞœ½ŽO8;ýÏïo/ÎŽc"J¢“Ë˳‹×ç¿ÇT` bŒ£7'¿œü×Í]k|vuüþúÇ£³ëV±®ò3£Õ§£wïñl6üx„ÓJÌžà#¢5-¸`HpÆÂLqtuôSË°³j_ƒ`DYBGРdFÒBÐB£„Qfá8ùåú‡·?C€œvÀó˜&ˆ
-Gv^6ÙªÌÀÕ¦n²eíN«²®VM¾^z. ”#ÆêÙpl0èÎ
-²“H&Ní]ëµ@”$a+;pAL¾Ì‹ÔZO ÷)@Q®?e0Ó\L«Tt³nœ¼¼q¢Òâ)Ýxë僺Єõ
-Îg Tc†EÛ3œ
-d
-q @6Öš…óÓ^=ÑèW›
-»„c¤ÙF¬ëô.„èz¹LWþÂÏ×8ÊþÌ›iD°¹ŽÕô
-#{¥Œâ„¨ÝMí¿^ïêþ7Ü°Mendstream
+xÚµYÛrÛ6}×WèQš‰\yé›ã¨­ÛÄvc¥í4ÍMBŠtI*Žûõ]
+)£‹ÍØžç!úÇíY™}{t&?Ú».Ó¼Ö ëÁ®ŠîÌ°Úm·Qù¨'Š?šüšÖè .´S_œ
+›´B“ƒpªƒ`C“¿mdÞAŸæwƒÀ(œíV£w Ûù(ðS±+s[6÷Ӻ妪®ƒ  sŸÈí¾Ô0­”Z™ö[Å{l:Ψü¸i+ä0MGÐóü¡íUƒ ó›tS£@ç3<Ñ Áƒ½}]½mÁæè
+6¦ÿendstream
endobj
-2027 0 obj <<
+2528 0 obj <<
/Type /Page
-/Contents 2028 0 R
-/Resources 2026 0 R
+/Contents 2529 0 R
+/Resources 2527 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2006 0 R
+/Parent 2507 0 R
>> endobj
-2029 0 obj <<
-/D [2027 0 R /XYZ 56.6929 794.5015 null]
+2530 0 obj <<
+/D [2528 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2030 0 obj <<
-/D [2027 0 R /XYZ 56.6929 751.9898 null]
+2531 0 obj <<
+/D [2528 0 R /XYZ 56.6929 681.0754 null]
>> endobj
-682 0 obj <<
-/D [2027 0 R /XYZ 56.6929 712.1227 null]
+2532 0 obj <<
+/D [2528 0 R /XYZ 56.6929 404.8182 null]
>> endobj
-2031 0 obj <<
-/D [2027 0 R /XYZ 56.6929 678.7055 null]
+2533 0 obj <<
+/D [2528 0 R /XYZ 56.6929 344.3155 null]
>> endobj
-2032 0 obj <<
-/D [2027 0 R /XYZ 56.6929 642.737 null]
+2534 0 obj <<
+/D [2528 0 R /XYZ 56.6929 283.8129 null]
>> endobj
-2033 0 obj <<
-/D [2027 0 R /XYZ 56.6929 575.4649 null]
+874 0 obj <<
+/D [2528 0 R /XYZ 56.6929 246.6193 null]
>> endobj
-2034 0 obj <<
-/D [2027 0 R /XYZ 56.6929 435.4781 null]
+2535 0 obj <<
+/D [2528 0 R /XYZ 56.6929 214.3762 null]
>> endobj
-2035 0 obj <<
-/D [2027 0 R /XYZ 56.6929 292.5265 null]
+2536 0 obj <<
+/D [2528 0 R /XYZ 56.6929 179.5818 null]
>> endobj
-2026 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F53 1029 0 R /F55 1037 0 R >>
+2537 0 obj <<
+/D [2528 0 R /XYZ 56.6929 116.1573 null]
+>> endobj
+2527 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R /F55 1311 0 R /F39 1151 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2038 0 obj <<
-/Length 3060
+2540 0 obj <<
+/Length 2741
/Filter /FlateDecode
>>
stream
-xÚÝZKwã¶ÞûWhÑ…|ÎÅ“
- Eå€4(mHƒ`hód&…F £ÌJã¶Xef@K´T#"$…¢”òõq»5¿ž˜¶‰µæÄ/7Ùò×òrÁ¸˜W›´2->¿ýÉ.‰šgËÂþ®Êæà:;8ÚªpÃW®[|þ†&qT±ÀEµqù~ñßbŸ¹Nº÷4űZk÷–¢3Ë$l¶ i!¨]À¦(«}ºËJ˜’À¾3‚ÇĤ8l U 1m‹e:&'Æ4µØo¿8¼‰™ö­ÇeONfðy“/7ÍçVd¦kDf~ãºM'.¹Õ¢§qÅÉ$
-TK@E2_eÛìSZåÅÞ=¹»w¿ íÕ%~uÖ2˜ŸÂ;Tô'qc5*L¯!˜Ä¡ÂΨðpˆI,Úp€6¸fó÷•{–n˵¢@Ûë´>m~–tµrÌ–ž¨¯0˜ïà ö5:¯ÙØ¥•Á€{Z”qÚÏÙ¡ÊËle—ƒÃ:Ü?z´Ùéìòíê¾’\’á›LâÛíø+CÛu‹@ëá†çe±Ëê5’\lkkÝG~;æ®±ro¹}2­ì÷¼¬Ê7ÝióÈn¶ïÈÔ²“>¾iî Ó†è]Ó,Åý:K'1Dz£“‹2ÜæûO#;“pDçþ%ƒüþÄðm¢xo¯OͬÁDˆÀÎ*/ÓÇ­‘csÿ¢éÐ TŽh€ÑÇcåS·nô5;<ç¥Á ×LÂui9°€Q6™ëö&Ÿ6[`#Ô)Ñ0!ù2ó^ÑŸ²e•Î@%hª·ÅŠ"Î1?Û“& {
-˜À4XÇè°ƒ÷]Áúí ¯ÇËôXfAI¼Âgk#Ö5XjO}Üomˆf=¸quÜ=•£6`Yì«l_M˜UÌP¢‰:¡( ª E TVQ~V¥EP”÷,-5¡).¦ù
-D|µ”„
-H§’c²ƒïÀ.sX.¡MŸf÷xáìaIp™¤WnPdþœÛÜOÑ k¤©Sn`æÛcˆ4Ì€‘ˆQ7Ì[êæ”nº s-9RR‰f,_á|ÁA*€ÿ®ÎÔZ}Åͽ†¨¢­Åî)ßf#:¡AR´ÎMA£ß EøˆjÕÌðžÓÃ~<¬HtÒ·/æû¤&‹×Sž
-êDx2ÍX¤ଭ¥ðh¡Û¬Õ® “ؘÜt¨«Þá¡ËMq4™Œi?f™´µC˜ù§ùÚ?Ødþk1ö·:56% XKK5a§š.«S(áºïë+HÃßyê
-Ðâ‚×.eÀ|"ìëTç¼P¼ àü$ÀIb´ì„jRM
-¶‚7„ތٗ՗í€ç5›Mr©Xk°
-„¶S.´ô#å1¯Üq‰§u'+¢b ^ØŸ˜±ôX0S¾L·æTÍ =úßÔO–=¥‡´ò“•ËCþdPŠù{7XíKûŒÐ}ƒÐÞ
-Ñ\ÂØ$g‘¨ÏZ ŸRh.©ÉÛõƹ£½ ëá(• $T2Èl7¦4ñl\–½ìb&u\ •ï—Ûã*s•¿Ta½KO
-endobj
-2037 0 obj <<
+xÚÍZmsÛ6þî_¡ôLˆâ• >º‰Ósï⸵ïÚ¹\>Ð"e3¥HG¤â¸¿þo)‚’fæ®™©@`¹X<û`± š,0ü#‹T Ì_HÅ‘ÀD,–뼸ƒ±ŸNˆ“‰½P<”úñæ䇷L.R M7«®á4%‹›üCtvuu~ùæâ÷Ó˜
+ýˆNcqôîìòŸgÿ°}W§ŠFg?_ŸÆDJ@ˆ`-—àèòìÝù›øõßÎ_ÿýßï/ÏO?Þü|r~Ó[6´ž`¦Íú|òá#^ä°ˆŸO0b*‹GxÀˆ(Eë.œ1ßS\ŸüÒ+ŒšWChp™".1ã(M@C@†
+Щ½`˜7…Vžòèñ¾¨m«j²¼¬ïôƒ]Fj—¦sB£›û²µcëì"d‘@:BÒ¡IÇ —TyVmÛbµ­ì¼
+a"“c(1ÄSÞ.–l7™&œÕïczèÌb˜êJJùC‹5ïÍyu=)s\Á 0ƒÂŠŠÃUÅPÊT4TUôRzÞ8ߟ
+*Ñðð”^(0å(„)8;ÅÞ”çuv[9åÅíöî-š[9—‘DòÃ+Jͯ¼—2+¿Ÿ[ùÁ)û•O§ ­|4å)ÝŽ¦±m³;O×ízmžkÇÙâkÙͣà ll[G@g u
+˜6Ÿ@B8&cÛ®õQ¾zڃњ3¡ï]U]¸±ºé&‰Á+ç3(•..õÿ/ZŸU@T.òyg‰„:aB\á„Œ'Ê€'Ôs@ÊqÅ>òTX
+~Ш^hjÕÈ Pûc‘È‘YW¶*P9”¨MÛÅz+ØG—™òQá«l¥ª“ÉTEWMÛ–æô×’z­•Ê\}ÈÊdY©ò Ô.‚2°2®š†-
+M¹Æ»„šäU@=ç™(¶§=ÖVŸ™%|.‘¤/™¦j¡®N€ÆÉ^Ò«õUÍ2›3J"Á‰8 ˜#•>0ר;f/Ä1æ+Bº„BLÈ¡â<:g&…
+PIʦI0*¡ ø„•¶¬—
+˜6.e‰’cÛÂ¥¬³g¾–ß,›€º«¦v|Ý:_OAÅÃñhswÅ×î sU¸žÚ]¾BA,Tb˜ào²Ç¹I$‚Œ ˉ[¤DP ¹÷ÍsÅ ª¼ ÝzÄxÿÑwŽ+T_^ÒƒvõBSÃÆLQäZÖ…¥ÜÐ)뉢;5QtŸä»oL)Û}!JGk€;¢Ã Vxž; ƈzw`—°”ÌrÇLäN ÂxW7‘g“ˆî>^éò¶Ù„¶
+endobj
+2539 0 obj <<
/Type /Page
-/Contents 2038 0 R
-/Resources 2036 0 R
+/Contents 2540 0 R
+/Resources 2538 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2006 0 R
+/Parent 2507 0 R
>> endobj
-2039 0 obj <<
-/D [2037 0 R /XYZ 85.0394 794.5015 null]
+2541 0 obj <<
+/D [2539 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2036 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F21 714 0 R /F55 1037 0 R /F41 939 0 R >>
+2542 0 obj <<
+/D [2539 0 R /XYZ 85.0394 677.5149 null]
+>> endobj
+2543 0 obj <<
+/D [2539 0 R /XYZ 85.0394 533.7824 null]
+>> endobj
+2538 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F53 1303 0 R /F21 930 0 R /F22 953 0 R /F55 1311 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2042 0 obj <<
-/Length 1827
+2546 0 obj <<
+/Length 2753
/Filter /FlateDecode
>>
stream
-xÚÝXKoÛF¾ëWÈEÌ;¹{tb'u‘(®%§Ò‰’‰ðáòaÇýõå.)RZÉŠ^
-8¤†3³ß¼I¦~d*$’šêi¨9˜ˆé*›àéþ{?!Ž'蘂!×›åäõ;N5Ò’Êér3¥VŠL—ë/³7H£3€gó‹W—gåœÉÙÅÍÍÕüòú¸˜€ãÙÇ‹ùÝÅûìæLÓÙÅû«ÅÙ×寓«eoÎÐd‚™±å¯É—¯xºË`Ä´Ó'¸ÁˆhM§Ù„ †g¬{’N“ßzƒÛW}p¡ \NÆ‘ý~ 
- ¦Ph$e=P”ø€ê¸ PÁïæ ¯ß 1à$…!V Ý°dÅ:ÞGCKÄBN¦CvuL»èP&ˆ Ádž-âU²y> ˜–³§û¸¾K{SöººWß Î6…û//ò ŽË,É£Ô½š¤ëUTž5[Wàð«Ùü4—}dïb« J³¢ª
-Ó€h
-¡€ H A[s£ô)z®LœÑ˜j +¡jÒÚÞ{ìe%iÓii_,ìµÉ×qYÕQ¾Þ84Ó>É¢zuŸä['8ÝeRßgööO,ðí»·ö‚–Ã0¬f7EU%ßÒÖ³à®ÑaŒÇ+›
-mŒÂ‰‡HÌ]üI)ŠÊÜ\óÐÇL@ìÉŽÌZÇ›p19EpØC%¡d $ÙæES£Ã@–ä°K”C61Á^Ȧ׉l긌ƿ‹<Σì ]
-µ/¿~Ù‰I ¥»(Ÿ}B!©8€·yQhSu·ï.*0}üj'h&M½R¤sÝÙ¾Ÿ{ÎÅ°/ÁŽG»H Ü t‹ÑN¿¯hSÇ¥áòjñööúfyýiþ“ Ú7†B°rÜådb
-.ÍÔo.—®vº-ˆ-eË®¥Mûºœ/ìll¸Ârè? ñì!‚Ðkÿ2MÜ\ÛAŶJÛËÚ4Ÿä[S'…Óº± Þi»^¼E–z×nQ@dÅnêoWÏö4£lJrع`ùh…¶­?ß›˜àç]]v ×V}³eç=ÉÏ÷Æ Ó‹Q¿™(Cƒí ¿ßÇ­ <ßmŸP°Õ÷ESÛìʲm²8¯«s‰Sa×SzöówA«Wjå[l"§ÚWÏÜFco ›9qÛ”=DÊMŽžp%!Fœõ5ãu\¯^·V!SÏ}s,Ê’©áPb>„ÝsÔÐZƒð³›öò¤N¢ÔµÓ¨Žö]BØÄΧ›nrù«‰Ë$®ÐOôØOm-Ž-Z"ŠÁ'›è€éøÑ1µ_3ø¾> Ó™&ꤾŽçPßs dÈÈHß]å"ûúæ‘wy:ˆ¡[æãѺÏ{ó1¡¥²È¬ïîqâ²c=Df5é B"_©f÷ »ÚøöbbR¸ïýª=BØEØͱ<*¦Ëˆh¸dM lô«´©’Çøø")wž^#{žK¤åÙ™ìsþ e½ï÷•ù\?P6ô¼üï=Ïÿžïf^ÌWO3p_NþõÇÕÝÇcnj½¢~ÇÒÔ@;£ÌáŇA‹e°ôÚþàEqendstream
+xÚÝZKw£FÞûWh1 tNT©'Uµtlw¦3ÝNOÛäL’¸Åi 8ž_?·^$@î´É-(.—ª[·¾ûDdáG"F±¦z!5G±XoÏðâ#<ûöŒxžU`Zõ¹¾¹=ûú“ tLãÅí}o.…°Rdq›þ}ƒFK˜G×ço¯.Wÿ¼ºø×¾¿¾Z®ˆ$”DçïÞ]]_¾þi¹¢?0c½=¿þpþÆÑÞ-5ο½ºYþzûÝÙÕm'Y_z‚™ë·³ŸÅ‹6ñÝFL+±x„ŒˆÖt±=ã‚!Á ”âìæìßÝ„½§öÕ1mp¡ <½ĤœÐA’`’L#By§2JÆT晌ÆVŸÌ6¿~%D‘¤´
+õ.«ï«zë$lc„ ^²_(åëM¶þ´*“mÖ˜[ÿN râ_±ìÍrʼnóvcF4j7™#5Ù:ÿcš¥ŽpŸäÅ®^y£ @Ä<zW5M~Wô4nºÄ¿p,?•)©ú0+LH¾â˜!¢([¬àH´Ô½…N³ûdW´² ¬‘µE 3ê—2JWëjûÙ«2YÏœ¥*‡ùjd^…¨Vª·ƒÇ¤.'vÀ@.ÞOø§å6Ç6!µÕà=&@j7{R¦c' ‰Eÿ
++Rô¦‡æ4m­$~ž¦88rÏ<f3iEØ—ÙÌ)d ¤äóÍO"[Àé«Xž@vkÙË"ûí²’«9dÇ9™—+0È5D6AL
+½áû|pMÜåæýRˆèwsÔp à± æþý®á" ÑU¦–w¦á›/ /Øp¡‚ñg7\$éæqÃÅ>Ýpa„‹ãzú%ê:(³ ¸<U×õ¹fи,:ÛÑÄ—P”æ5ø“ñÕu “XÏ ×qH7¬ë8ZÑ¡xOŒ CR<^Âq„Šã1y .Sì‰Pf4•ŸÔ&Ïf”—ëb—fî&rØ7Á£ñ àçËð–çÏgrˆ;ˆ`y基¬Â{MsÝYêcØ
+ݬ
endobj
-2041 0 obj <<
+2545 0 obj <<
/Type /Page
-/Contents 2042 0 R
-/Resources 2040 0 R
+/Contents 2546 0 R
+/Resources 2544 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2006 0 R
+/Parent 2549 0 R
>> endobj
-2043 0 obj <<
-/D [2041 0 R /XYZ 56.6929 794.5015 null]
+2547 0 obj <<
+/D [2545 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2044 0 obj <<
-/D [2041 0 R /XYZ 56.6929 627.8052 null]
+2548 0 obj <<
+/D [2545 0 R /XYZ 56.6929 85.6141 null]
>> endobj
-2045 0 obj <<
-/D [2041 0 R /XYZ 56.6929 562.9454 null]
+2544 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F55 1311 0 R /F22 953 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-2046 0 obj <<
-/D [2041 0 R /XYZ 56.6929 498.0856 null]
+2552 0 obj <<
+/Length 2176
+/Filter /FlateDecode
+>>
+stream
+xÚÝY[oÛ¸~ϯ0Їã
+“«+»ÙóO“[½øŠvL‡G¡Rö"]g³oX` ÿÈ™ýÔ FÓe6}š–ż3mä1Õ‘G8AŒ€4läݼ°2À\"°<pS.ˆã äHIÂÇë›K+O¹]ÍÖy‘Wõ6­Ë­ºÏæÙö”ÈqVL3;ô9-štXžÄÑ8ŽxäXzf˜H¢€J€à±…×—‡_oï[ôº¨³m‘ÕV“ÉkUgëʾ\”EUnë¼Y¿­Ëã1ur8©‰´[lžFcwúÍÃ@9ιṉ=)$ãX¾±Õॉ¥újÎÊušo§o©*Û>ƒi6Â}ÛL^‹rSåÕÐbpHæ*FŠ%<„wzSÁŒ°
+é :I„ʯ%ßfSu¯!¡ÅT¼YÕœ"üJ
+ß»S$î›ÀRv×þìšÊûúðìh¼céç–ú£¥~–Pż çÓ’Ê>g²6RÝíì„fJ!7bFúáçòjrq}÷p}{Ó~u8ã‚&ŒrìýbYyœÚÇ¥‹š6A×P6¸[Z'ÉË›‰N“vÀÏ„C–mñx“ôÌT9·ÏzéÙ4§)e3âòǦÎK·êܤ¸Ò­v=¹@–ú¨Ó &Ö¥M‚ΙÝnz¾œór»N­PàýÓ(¢ ØÁ™ýn2zÕ¦tvÖ’Ü‘i1{ËøÈg)"Q‰ߟË̬£@çòÉæ"9~ÉëeÙÔv&5Ê/šuVÔÕYà‰H“‰ÏÜ{Oê«{½ä«••om“º¥Ý~ÄáyÚ¬œë¿aLͶ5‘ë‘ \I‚gmÌxŸÕÓ÷F+¤sF@5 UZÌd·ôwTW[máWK@åSçéÊ¥ì´N‡G°ØdîLç¾>ú»É¶yV¡ŸÈã·Æ‡&;e°KÂTa$ã‡3u—ËW­»™ºåÒëF|¸¤bˆ1I/é™Kv M#Jô—üR9|_ß=sï +ghÈËΊù|à!˲r5Ó‚d[Çç|dšnÒÇ•,çí1
+…V(4•L|·VV¬Ú‘ÛÌ¡O:
+-ù†‚%ƒ(è.ÙEAü¿Gÿ?B”`„C¤=Œ‚×x.£¸¯ÊEWqŒ(#"\”wÕ#1ÄSÊÙaýZ®€‚ýv1F‹¤¯¡M ˜ÂZ·½}COn ©@Bvç k %\9 øn"Ò³.:/ Îëô ¹M5ÑýÜ%µ³ÖHŒ¸PÉnÒò=
+cP±Ô•%´t£«~ªÜlÀVæv¨É,¡Õé>SûØ”U•?+ Ê0RÇá’¿gr(‚HÒ6åÆÁC+êž,PÍèAkƳ
+÷´Jíu%ˆ-ŒéÞxö»‘ã1N4ßé(‡”Z̳ì,ÖëD ‹»‹Ý7Ã_GØp2˜œ;X,,šß—k'É‘F #ú²ÝÛÐß¾›0ŸÿÇx Ú÷#HÿrØn[úüÕÛ/p\ß·H6Ú.H0N)m+"’¡êíOY»ºÿ%Ǧendstream
+endobj
+2551 0 obj <<
+/Type /Page
+/Contents 2552 0 R
+/Resources 2550 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2549 0 R
>> endobj
-686 0 obj <<
-/D [2041 0 R /XYZ 56.6929 457.8644 null]
+2553 0 obj <<
+/D [2551 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2047 0 obj <<
-/D [2041 0 R /XYZ 56.6929 424.2917 null]
+2554 0 obj <<
+/D [2551 0 R /XYZ 85.0394 752.0294 null]
>> endobj
-2048 0 obj <<
-/D [2041 0 R /XYZ 56.6929 388.1677 null]
+2555 0 obj <<
+/D [2551 0 R /XYZ 85.0394 688.0859 null]
>> endobj
-2049 0 obj <<
-/D [2041 0 R /XYZ 56.6929 320.386 null]
+878 0 obj <<
+/D [2551 0 R /XYZ 85.0394 648.5014 null]
>> endobj
-2050 0 obj <<
-/D [2041 0 R /XYZ 56.6929 234.5807 null]
+2556 0 obj <<
+/D [2551 0 R /XYZ 85.0394 615.2083 null]
>> endobj
-2051 0 obj <<
-/D [2041 0 R /XYZ 56.6929 126.8791 null]
+2557 0 obj <<
+/D [2551 0 R /XYZ 85.0394 579.3639 null]
>> endobj
-2040 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F55 1037 0 R /F22 737 0 R /F39 899 0 R /F41 939 0 R /F53 1029 0 R >>
+2558 0 obj <<
+/D [2551 0 R /XYZ 85.0394 512.4986 null]
+>> endobj
+2559 0 obj <<
+/D [2551 0 R /XYZ 85.0394 427.6096 null]
+>> endobj
+2560 0 obj <<
+/D [2551 0 R /XYZ 85.0394 321.0146 null]
+>> endobj
+2550 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F39 1151 0 R /F41 1208 0 R /F53 1303 0 R /F55 1311 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2054 0 obj <<
-/Length 2977
-/Filter /FlateDecode
->>
-stream
-xÚÅZmÛ8þ>¿"À}8¨]½ÛLÛÙbÛÙÞvŠ[`w?xeâ«_ÒØî´÷ëÔ‹c;N2@ \ Œe‰¢(Š|HÊ¡ ÿé"‘á©XÄ©ˆ$¡r±*¯ÈâÆÞ^QGz¢pHõêþêåO<^¤Qª˜ZÜo¼’ˆ$ ]ܯÿ®ß¿¿¹{sûû2d’¯¢e( Þ]ß}¼þÅö½_¦,¸~{ó^…à
-ˆR$S$¸»~wófù×ýÏW7÷½8C‘)á(Ëç«?þ"‹5Hþó‰xšÈżˆ¦)[”WBòH
-Î}Oqõáê_=ÃÁ¨™:§!“H2¡!'°ßY=‘ˆHØw ©XôÄ蜞<ê)\á>_þ¯JJ"ÆAÝĬêj“?†›¼ÐSPE#Â_ W>’¯§š —U*"DÆc ?6ډȴ )’x^Ä _•F*‘ÌÑfÍ2ä© Ú­Æ†ÀÉ»}ÖæueG±§Ð¶WM«³µ¥®7“ék½Éº¢}aC3ª"!S/åKÝ®^VY©×/B®X”$`!¥Q*AD¿™™]0¥hw–Xj¢DpF\/CÁe «¦Û/ihûÞn³["°½E­óêÑ:ª£Ýc§ß=N‚6¯:ݸ‰nµ§zÿÉd›Vï'\½ÿâ;· q³]¿·[먫mV=jT.Oƒ¼ml¹YñeÛ ¬ÚzÿÍuuÚ6Pœá3³]Ý4ùƒ·†ñ¡p¥„(§H`î«\ÆE3´”õΙ
-êžÖ
- qlDÐiÕøbÆ|C–
-³è2¤:.=•A—õºP Þ×ú¡{ ýEÇèÂÀq/É×SÍ8F—8R*•c ?h𖺓ÄÆ:Óe]ý½qo(žmZCq¬íøL©
-@@á1`SdG'I!F+
-ùæYÁzªÉFË {Me: rt{Œ‘‚&V
-”`Ó&ºC_×dÚ6×LD*ˆ¨<{l0O&ï}”7¤n̾d¶f2GE¢ãZ-صfÒ­R3ÀEK5ÃUDEÏÆ€õ)6És¹@*Rï×Íé"ŸÀád
-)†\ 0œzÈDì!¡«Ì„¸4â2ö ÊUûõ9‰*‚ØýVû¸[´‡Óìjïm=qáÛ¯§¶É!ÁÐ!/c©žQ±(5꟫¿Âža8àxlÅ,²„ Ö¯‹Ûzwón*ýI•ü8ùz†çåãàÖ@0–ïÍÍ«o‡>¢8ß°qºYíó½îáóçÀ˜P4oPÿÈ›ÕKpÑhûÏgd3§À, r ìTgÀÎS°«.¦™[íºæíÕ@~V²žjF´ÚA"‰h¯]îÓÎALˆ©ˆ§"gn„Ÿßae„SÞⸯõ¨°UdŸ´íÉÖ_²ªµp
-¦z…g k¾+Ñë÷wCrëL²cÍN¯r,dôúÅLö‰6J¹”}B¥ Ù·à“zç)7‘ðºEì7ÚÜÇ€‘BUYæ•vÝ[רºòÁ~awƒ´(¿íÙ9dÑUk;lȇÆêpfN}àì•èXxîÀ5²´·Û“;¦¹[­«2}Æf  †Ñ‡»Â[¿ h›]ÀwñÂ%$.ɸW¸þÜ-›È8–ûÆ‚‡Ý®Oº£ˆ^hœœwÇ!Õiwì©Œ;î.ºã®Þ·ÇÞH¢DÈóry¢¹Æ™‡Ä벉`¿äM««C
-hŸ;½ÏµƒÆÚzù¦ñ –|ñ@u9
-⮃É49À$´û¯ Ð6Ï®ªôJ7M†åˆÅ7èÝ Öä‚w«žX”Ë ”Â[™ý)
-ªð>
-{'„¾cæ<vTæþ‡Óà¡sr>èÍá,¼û{änÌ›
-¼B&bí]ûäg î2<&:õ'.#Ág „ôiÒwÿøéðã.8W0ÝSwÛ³Ô”z¡ps”Ñ©è*w™°xFöÿs ÿendstream
-endobj
-2053 0 obj <<
+2563 0 obj <<
+/Length 2873
+/Filter /FlateDecode
+>>
+stream
+xÚÅZëÛ6ÿ¾…ûpZ VøÒƒ¸Ã›d/Ø¢ÙË5[\¶´2½V#K®Ùäþú›á²dËv‹äЈ)r4Îã73Ôòƒÿù"ŠÃX ½H´
+#Æ£E¾½b‹'X{sÅÍÒ-ÇT/®^üS& êXÄ‹‡õˆW²4勇ÕOÁËóðX°àþæííëë¥ZÆÁÍ»w·÷¯ï~„çˆ0¼½¹ÿáæ;š{w­Epóæöýõ/ß^Ý> òŒeæL¢0¿]ýô [¬@ôo¯X(u-žá…\k±Ø^©H†‘’ÒÏ”Wï¯þ=0­ÚWçt ¢4Œ„ŠA ƒ4ç5ÅÄs J$è…ƒ^S‚ÏiÊS¡¦–O‡#KÇ‹1³£-=ÑÌ–b´eÂÂH²ƒ-¿ï+Òu·14hMóÑ44.×usÍÓÀ<ÙŸº¯V4Ÿù#È}V–4(맧¢zrìj<狪±FhŽÅQgBÁÚneš†è&ÇQ˜îÉÂ#×púOX
+™ª FQ1’§²FÚ’P ž’«0Ž•vB­ËìÈ’:
+E qV.O4#×Xœ±P(­¦‚=\kô ˜L*ÔöW[³­›Ï4×·Ù“¡áÊ<öÎ"Hõ3c2{j1É»ºm‹ÇÒ‘º5zÈÈþNrl¿X‡—±Óíul>¡Ã4M¼¦¾™a‡\ lº&ËO²I/—Æäu³ºèLù´Åg…‘PL¹
+2lâ"+¶YQ•ŸÝúÚ­U€Û¦íè‰
+Ô$xywÿšÞÑ4±2×’¯E˜²†Ìá¶qf¼‘à3½Dàœ@¿­¯yäÞ[Íå ‹N t¨›¬z²u<Ø>~3úY÷]ß7¦4ÔØÀõÈW„—Huº{×9˜ω5”ùËýMÄ—¹ÿÒw\ !`}¡DT
+’C zÁ*‹`ï/—ˆÛìÓ²­óG`Ç@ÆÂxã#ñªù&.
+T‘š
+xS–õóL…ŠIö­è© XªTù“øŽª÷mW¿›Âã$­A'$åÐ^NµpˆÔZÿx¸ý
+:r Y"êxïðÊ)|q « ø(µÈŠ¸ËK3ø á ù‹ŒßÛï-VÞ c¼9…˜‹ó$qˆÉ
+†²­q„¡’u4猋y×ã‘p à\li[šË€Ïdk˜¯7g%7–ý”Eו³AdÍjPÎgäjÛM«€¬ò#Cƒ‰*¨ÂÇ
+³ýp7ÚŠÝÖÉQoDÞ…p<v!
+½¥€T”b*šºõ/[L p……V×úŠ«£ž;°>…Sý¥*kœS¾0OýÙe–PP¥ìÂÇ¡Ê–YÝL™¥Cu¯³äªhLÞa/wXdq åi<b8[dyªé¦YMA’‡ä=ïݜԶ ñ|=„7ŸRè9y60•zÊlMÞ|éªÆ´Hß“„ÃOäõvK<”t9„ÑcßyêªìEäÁcï}4þ£=û änœ+¼LfjŠ=â3ß13'Ë7®ã0âè«”oÚ¨úD…ãTñ†®2á—š[žâ½¬Hÿ¿Å—”òšýâmÌùLñÆcª8M'ÅÛ¨áÕñ¨xK\ñ– œ¹™ÂQ§üÚW¹- ž‹nC#ô¦™O¢iB ÿ¥`ÙÏ`9W î/H¨oÎ9TƒÄ<ß4–ƒ? ÀD±wg÷aŠ.§w,z  ‡"”>ÂLæWjºÄÁª6mõ׎¦Mù,wâ­ÉûQ jïÈ+wG^·î *°Ú¿aIǼÓü3¦WúÍ(‰…Œ%þn‰Îú3‹˜€øŒÂ
+hMfdÿþ½¿Ïendstream
+endobj
+2562 0 obj <<
/Type /Page
-/Contents 2054 0 R
-/Resources 2052 0 R
+/Contents 2563 0 R
+/Resources 2561 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2056 0 R
+/Parent 2549 0 R
>> endobj
-2055 0 obj <<
-/D [2053 0 R /XYZ 85.0394 794.5015 null]
+2564 0 obj <<
+/D [2562 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2052 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F55 1037 0 R /F22 737 0 R /F53 1029 0 R /F41 939 0 R /F62 1062 0 R /F63 1065 0 R >>
-/XObject << /Im2 1051 0 R /Im3 1185 0 R >>
+2561 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F55 1311 0 R /F53 1303 0 R /F62 1352 0 R /F63 1355 0 R >>
+/XObject << /Im2 1341 0 R /Im3 1500 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2059 0 obj <<
-/Length 2424
+2567 0 obj <<
+/Length 2383
/Filter /FlateDecode
>>
stream
-xÚµYÝsÛ6÷_¡·R3Šâkúä\œœ;‰“Kœ»›iû@KpÌF"]‘²ãÿ¾»XP"%J¹^’ñŒ‰Åb±ØÝßb%&þÄDf¼ôës¦¹Ð“ùêŒO>ÂÜË3‘hfѬOõìúì§ÊN<óFšÉõm—cÜ91¹^üš=cžMÏ®Î__<ŸÎdž+“¿}{qõüò¿Ð׈€„óìõùÕ‡óW4övêevþòâýô÷ë_Î.®·âôE\¡,žýú;Ÿ,@ò_Î8SÞéÉ#t8ÞËÉê,׊é\©ndyöþì_[†½Ù¸tL¹tÌ(c' S\‹ÿe[å¢"Üø¶|2óŠå.÷ÇyÑ:¼R³[1d5s‚iïõdf¬fVônHʉÌk-ñŠœeÒ:9±ȼ´ñŠþƒŽ”ži“ $„5ÚÂ<çÓ™‘Ù»øÿ
-þ‹ìrÛ–ÙËýr†y¸‰å–9í£®&‚¼€ËDýv<ýN+qà§Ë•š<¯áŒ“þ1ãYŸs<¦‘=CRÁew«$sÜÑ1¯ïÊLËÛ¬¾o˺¶ɚ»z³\ÐøM ï¦ i¤LTóºúcSÍ»e6{,Û;jµwôŠÛ‰ eΤ‡6)p¶!š¡˜9(A䉄„úq:S\dE’t~·®ë¶¬>âr°=å™äpþí•Â–•Ý¯ëyh꬧3¡³MUáÒ8Rt3À[2[Ô¡©~hi8TwE5ÔiÂ|CÊö‰†ðÜø]ÕMZÑ<5mX5?COñN hÔ$yÿã˜S xSgœ[™@gýk.áŸQx¾Î¹Hôñ6­Îá7Îe¯ ºÅrYã®qÚ zpx«ì¤Ûƒ©ƒèÄå2| iq[ÓdhæÅ=pfQ
-«.+Úå’í»Fnàw“¾£~ï+pjã!Îvñëë"˜sÎúì„´~À@ÌÑÀÅé3J1‚
-[ª¾?hÝ÷Áœ×*]/8áz_{^²Ü;3éïx WG4"Wߘ¼e¹õ{r½í¦Œ¾/ñîIFÕ[•KfûžŒ{¬¥aNø.x·-PE–ózu¿ ÑŸcÿ~Ì-mY߇ua ‰q@fÍf~GST6_O…ËBÑNE–ø€/ÖóOÚDÔÞ--[–à¥Uâ^‘;ÍòN>0à(
-ïÒLkkw¶ßkŒý±ñi*ym]gUXþ0;J4>‹›rIxýU˜à”Í
-»6ÆY^¬ë{jA§F ¨d· ®t€0aΑDœÏópßRŸ$4>ÛÉ€£õ& ¦¡ò”nÊjq
-’rÐÉÃã1€sAŸ¡l k:Ë1iµ FÚnU=£ ‡ÑF›¡§Œa½M½Y#jçÊ‚«¯J
-P4/ª.àè³Ë«çÔòôYÎOÕÃ…ÍXq…¢ˆuÙ*UXb'±à»«ùÄ%Qb’AuŠ¢úØ Æ"—u] ãvÓnÖ[&ËP4’ÊcHÝ7¨¯2Ñï€Ó=«çÌA0ìÊžÕw‘RB`•NP2óþòåÕù«÷#Ánù–Þ—¨? éx SxÞØ>ç1ì+©ÜǪÀ$ '·…G™Œ
-oÒÊT”©%c²¥ –´†bÌ`âÛ„5ÀÑÏIÒ>(ÆVº.K^W‹ùXÅÀ¢c"Ú‰v(ÚpÓ†bq¶Ö©ðÕr·úTÇkK•®ãŸÞÔ„,ã^ˆÓÛvD#Û¢—Œ[xîö}QGÅÏ$T¢:Ìr‹W˜Aw2µyv\U
-+š§UÕ£:¡ªŽ*©êòêA*e0p}ñîõžÃûÕ;›Ÿ–dK5"Ê@}b¶_Êr·IÀ¹¨«ÓJ‚›Ê~4§
-7øbSŽ,ã[.'D‚±¶®©A•ÈÏ4Û¦ÁEhæëò¦[Su£ð\Rõ‰7À°~Àô‘2•5CŸËýNÚ<ÇW'ƯTÜÀw 0CD{(]ý±ìYJ<>ÀEÏè5Ë1™§ã~"µ§ÏùbUVeÓ‚:êt­ïÂm’½êùuQmŠåˆr…q˜+šcoÔÎåH¡Ô˜Ëð­¥|õ¯“»__s ¯['Ç}œ†yüÁ) …‚ )#‡¤ÛÈÙÿŸäendstream
-endobj
-2058 0 obj <<
+xÚµY[sÛ¸~÷¯à[©™ˆÁý2}r'õN⤉Òvfwh²Ù•H­HÚοï9
+e'¿'4#ÂZ¨Fcoí³üÄëë KÞÖ`R2¶ªç<³öf)6Ê=*ÁBCL¢Ñ ŒË t5›s¡Òe5£$íž^;-*3\™hg•o\©Æ¸Ì¤Ô:RukëöÞ…Áo3FR·ÃœN+·þÓ R;Ò,óm~[®Ëö{x߸å}^•Í_uÚÖaºØÕÛ0Ê×ë0ØÕu‹ÊÀdB¢Gb(A-ˆ£2-ʵ»ó)“º'éÓÒmÛð4T6}Ögë`$ÄzäE®3Æ‹VÞ–Uñ ‘„Á?:á>¡´ÏopÎÃc_·"¨°­aV4ª–WE4®íWÕó`0‹µjßâ¥kÀLUb皺Û-¾ét]nʶ™@¨†Úô[µB?ôòº*oÝú;dI_Á”–à—² ‹7.¯"×ö>oû‘›ðS°+ˆQÑæy7áÜ „ÑHRoÛ²®Ϻ¼uLCÖQ¢{ëB±|Ä,­ƒã~Ãp2›>Þ»j"k¥Êµâå¬å†õ¹]F–A@‡›ƒ™´®ÂìA‡,c5
+“” ó ,0à™µóíÎñ`¹¥™!PhöÂêYºÏšè´)+Œ0¸2Ã'öCYwM >g‹² ªº 3°›jÌŒÇðz¼i`Ò'/,ºuá}çÚ¼¬|Ú"‡ªuœ dß
+Èâ®<»c Ñ@wä1ÙaVc“áɸ†ÿ`_àxZh“óçîöc}kŽÊÁÇ94@ ŸÆ š –m"°0‹çnD' Ã@å7Õá_,o(šŒ™Iì‰&DŽC
+»S 
+'oãJL«0òµ
+žËºjƒ€uX
+|Aܸ4¦?G]Ç­€3i6 ¯]U,',bp쀉žU;Ö³¸i]^œl`œßxf=ÝÀÆT§Ø@ò×oŸÊ „Î3ê¼ÜjBð^iàŽ€ö$¿«½ë—±%Äæäç`‡ömë¨u„¨Ì´HO; 2TùB·SqVOu}³À^ÑL,®¾|<r Æž×d šPeÏ}Ú‚Mµ¯Ë}ûgQ?Vç ê‰Æ"NM&ѱ8»±Ó›¡#÷No\U”Õ]´¾Ç¯ &â³ç͇Òëi-ü¸ŒD]U¸_a• É~X5  pAŸ
+ù/ŸnÞ]¿ÿö徸þts®rÈÁªã-K-ÔA;q7³Ç
+Ê.¡ª¿µ€ò€ªÞu¡àà Ž§8³ög;º̵uËz³]»§ðµ“…k–»ò¶_Sõ³p.\‡1ú#á}ÁÞ”YëÆ\¶ÏŠáO¡XÁâež éÁUÇCY¸¸ÊQ¦xó!ýF‡JØÏŠöe-ôP¤¶áqYlʪlZpGÃúÅ­¢îU¿‘?æU—¯'œK•AȨÆgÖƒ(A-ý™¶û‰z2\<“Dòƒ‚ñîÔ`'n]$ƒJ$zºMÞü6ůÈ
+2€S•^¯Â— ¶9‚ÉÒÛïS½ N]zîK™hÐòé¿
+É#
+àŠ8ïŸÑiÿôDÞ?ùîõ®«‚¢§¶eq¨cgÕˆŽô؇Ÿ>™`3™vÔ(ÑæeqÞO=.Bè7yaG†ýáŸÓž/:ƒcɉ”
+endstream
+endobj
+2566 0 obj <<
/Type /Page
-/Contents 2059 0 R
-/Resources 2057 0 R
+/Contents 2567 0 R
+/Resources 2565 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2056 0 R
+/Parent 2549 0 R
>> endobj
-2060 0 obj <<
-/D [2058 0 R /XYZ 56.6929 794.5015 null]
+2568 0 obj <<
+/D [2566 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2061 0 obj <<
-/D [2058 0 R /XYZ 56.6929 243.4864 null]
+2569 0 obj <<
+/D [2566 0 R /XYZ 85.0394 388.8031 null]
>> endobj
-2062 0 obj <<
-/D [2058 0 R /XYZ 56.6929 96.2114 null]
+2570 0 obj <<
+/D [2566 0 R /XYZ 85.0394 246.2919 null]
>> endobj
-2057 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F62 1062 0 R /F41 939 0 R /F21 714 0 R /F55 1037 0 R /F53 1029 0 R /F63 1065 0 R /F39 899 0 R >>
-/XObject << /Im3 1185 0 R /Im2 1051 0 R >>
+2571 0 obj <<
+/D [2566 0 R /XYZ 85.0394 128.907 null]
+>> endobj
+2565 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F62 1352 0 R /F63 1355 0 R /F41 1208 0 R /F21 930 0 R /F55 1311 0 R /F53 1303 0 R /F39 1151 0 R /F48 1228 0 R >>
+/XObject << /Im2 1341 0 R /Im3 1500 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2065 0 obj <<
-/Length 2296
+2574 0 obj <<
+/Length 1411
/Filter /FlateDecode
>>
stream
-xÚ­YKsܸ¾ëWÌ-£ª/‚äÞdKöjË–\•Š×Š¤4ŒfÈY>¤(•ŸºÁ!)JV*©9àÕh4úñuƒ#~bŒ«X/ÂX³€‹`‘îŽøâÖ> ¢Yy¢ÕêýõÑ»*\Ä,6Ò,®o¼"Æ£H,®³ïË“Ë˳‹Óó¿¯dÀ—ïÙñ*à|ùåäâÛÉgœ»<ŽåòäÓÙ†R+D‚[:×ëo—§'Ç¡^^Ÿÿ¸þýèìºk(ºàÊÊôçÑ÷|‘Á ~?âLÅQ°x„g"Žåbw¤Å­”ŸÙ­þÚ3¬º­sªTÄ‚H†3ºbNAÌŒ’Êé¢Lvyf¯Är@¬à\H8ÁRå&¯‹¶±Ú‘Ëv“ã=dH¦…iG·Kšû9¾.DõøœËmŽœÓúXDË<i‹ªÄ™]•ÑšeôG·Ž²Ú$‚ŽZîäP‹eKSH™æMTÂ,ÏoqžÜLŽu¸‰›'xIÅ UlHþµÇY+Oõ‹¥X¬t ¨Ô,VB°8
-–ÿ¨ººL¶8I2þ£X-ËÜIóm…Ä›ä!Ç™´kZ§èïózW4 hÑ™4’ÅÜÄ?7Z(¹7m³©º-‰q“£MÞâDþÏý¶H‹vû„ã¢D´L4i]ì[ÔˆŒfd8ÑH×  8^Ú¦Mê–¦ü=Ff ~fÅt¤Qü³ì帙¸a&ŒâÅJ(’îãùg€…iÜs°, ‹1‚£_€,"Z ©\˜êh&L{*{껼Mß¹{±´*o§ç‹P³«ŸÐS=—`¤'@D°:ácŒ/³ü6é¶dƺè]W÷AËÉiÙ‹ZR‚©
-"edqR¿.IOõ\”‘º¤ó+Àß‘,óê8ݪȞië¹êˆi‹ÿ#\ŸáÖ“Ï미Oʼn8°À $W?¯DÌ—‘ÔLXhÎŒ6Ѭ&ülVQ‚†ìôÿ—]ðv+É%Fø*Ýäé½ ›F"›ž/ÿ«*óér]fétnûˆøßd³Ì˜?&À•ç—Z úÚLÀìýùÅ)Ú*&“e»¢,š⥪qê*¿Í)m¥ä4_’²ƒð\ÂDLãSË ^ã‰F^sòíú·¯W3<Çîr^¶y]æä°ë§¦Íw >@>©ê¶èv‡c5SÚHb£/¢HãÍ¡Ër(­Ê¦ÛgYê™
-˜Œ$Âʨ÷™b¦8õ 0`¤ ±wúÖ)R\¬±3¤íÚb[´Osjâ“ z*«}S4S°0P˜)ˆn% ‹„Œç°B€à2ÐÐÒ†,Òæ곞j|sŠü¾Ê~øÞiß»Ãο±YUã!Ý=PC/ŠCpîSá÷Í.IýqŸ[uæ¿6yZçíL¹
-|0œž­?\_^Ÿ½˜)ÄÆP2Œû)¬ÃIkíß`÷¥Ÿ ÒÚ¦»Ù-öÑ.|´Cç›vè#ŠþÙåMKj³Ü¦ÙÒ³we)´}¤Pf|f‚Õ ‘×€Ððäc¶š!¹#N
-§>Ë ñ†Ä'`ÿPEJƶ.G•ï0;ã5i;œê=Bž¨“6»Á ­l«¦5–«±UϘû0;2;IV…ÞÁª0 Y1<”á>øìšS}Ï‚ÏN¸«Î}$€
-72úM&62ö¨oy'd…í mÈ ð4ÑPÕdk)Τ0jŒ@6ŒmèòªË>Ä´<\Zj®S¶8íT®ý‡X² þB{v Ô€5öGPhÙ;(tKØŠe‘Û‡)í>¥¸â.—_.N¾œa×Ñ9_‚êv$†ôbÌ€ÏúëÉ‚Úô~2SÍØnÿ‘f5÷Å@Ø>ÕV{|â*”Üû<>²½QÌÄaô&Ó+XçµÃOË» 3²ü¦»£ãªÌÚ3Ð1)ÜNÒcòN3ðªH¦#›ÛªÞѳ\Ipø—
-á†Ü’—½â$½€æM·ëɆwI–O»݌˜ì·…G
-ª\þº“ioF[Þû, 'z Oq¨)›$%lj'Š»2i;BYœs9ÝvFA‹µ›í9ô‚6éÀŠ
-L»SŒ»€2€3Pí[Ü m’ÅX´tÑ'Ø4
-kbgŸƒnÜâvÊ Ž’Ê Ç3'–¯¶½/«G⌞;÷O <fìç­™g3ïÝöþåðo‘™Š"9ÿ!ÏæmÎå…²ŠRMEïÿoy.û
+xÚÅW[oÛ6~÷¯Ð£ T/º>º‰Û%H,v€m‰¶ÕÉT&Éͼ_¿Ã›,ÅJ[l
+yÎáá¹~$‰‡áG¼0BQJS/NbzÙ~‚½-ðÞOˆ•ñß—z»žüòŽÅ^ŠÒˆFÞzÓÓ• œ$Ä[ç§o¡h*ðt9ÿ°¸ô¯oî—ó›»û«åzæ“0ŽÂéüîn±¼¼ú}æÓÃÇxúa¾|˜ßÚÝ,¥ÓùûÅjöy}=Y¬;ãúÌ”eN>~Æ^~\O0bizÏ0Áˆ¤)õö“ d( s”r²šüÖ)ìqõÒÑ€Œ(‹èHD(ñAiÒAHÂEŒ2’Õbaœšß¬n•?Ç´Gìù4BZ§Äïß]@œR<÷˜§´'`QË”ô›…ÊDF¬@_]ðÿª @O1J¾¹ŸíDöGVÉÍ'âþÈ9ûïJŠ—ìZæÙKZù\ÏH2M>ª ¹mBÃ9wÊ' £4ˆ"¹ü©ò½Z^šd¥6gù¾EÓÖ¼­jCºav—™0¤\x9%ˆF°‹‰²"ƒ¢ñ;!Ÿ%=iÙùÃú×Ûû/êåJ¶¢–¢5–¬ŽM+ö™\T²©ê¶8ìOûˆµz†â4Š»Î…ÔbèD“/Õ¡–¼|ª Ùªõj‹ÅI ,AjÜ<¦ÚóFtiÛ>Q›Q¨ÒoFv™Ò|w‡=—¾‰=Ïùci…7U½‹,v M#eõÔÍKLaÅIļ âC6†¤À¯
+±ièâmñUcPºÜ¨‰ËÃÞUoÅH½%dÄŒL‹8¼´VB²Ð ¬Š°,¤p­°-¤òdú\´–‡x
+)íendstream
endobj
-2064 0 obj <<
+2573 0 obj <<
/Type /Page
-/Contents 2065 0 R
-/Resources 2063 0 R
+/Contents 2574 0 R
+/Resources 2572 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2056 0 R
+/Parent 2549 0 R
>> endobj
-2066 0 obj <<
-/D [2064 0 R /XYZ 85.0394 794.5015 null]
+2575 0 obj <<
+/D [2573 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2067 0 obj <<
-/D [2064 0 R /XYZ 85.0394 691.7632 null]
+2576 0 obj <<
+/D [2573 0 R /XYZ 56.6929 751.9132 null]
>> endobj
-2068 0 obj <<
-/D [2064 0 R /XYZ 85.0394 587.392 null]
+2577 0 obj <<
+/D [2573 0 R /XYZ 56.6929 674.8216 null]
>> endobj
-2069 0 obj <<
-/D [2064 0 R /XYZ 85.0394 513.3346 null]
+882 0 obj <<
+/D [2573 0 R /XYZ 56.6929 634.4081 null]
>> endobj
-690 0 obj <<
-/D [2064 0 R /XYZ 85.0394 475.0295 null]
+2578 0 obj <<
+/D [2573 0 R /XYZ 56.6929 597.1931 null]
>> endobj
-2070 0 obj <<
-/D [2064 0 R /XYZ 85.0394 438.8551 null]
+2579 0 obj <<
+/D [2573 0 R /XYZ 56.6929 564.5425 null]
>> endobj
-2071 0 obj <<
-/D [2064 0 R /XYZ 85.0394 407.0157 null]
+2580 0 obj <<
+/D [2573 0 R /XYZ 56.6929 496.4842 null]
>> endobj
-2072 0 obj <<
-/D [2064 0 R /XYZ 85.0394 341.9916 null]
+2581 0 obj <<
+/D [2573 0 R /XYZ 56.6929 434.3126 null]
>> endobj
-2073 0 obj <<
-/D [2064 0 R /XYZ 85.0394 270.8991 null]
+2582 0 obj <<
+/D [2573 0 R /XYZ 56.6929 259.4673 null]
>> endobj
-2063 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F48 953 0 R /F39 899 0 R /F53 1029 0 R >>
+2583 0 obj <<
+/D [2573 0 R /XYZ 56.6929 194.3308 null]
+>> endobj
+886 0 obj <<
+/D [2573 0 R /XYZ 56.6929 153.9173 null]
+>> endobj
+2584 0 obj <<
+/D [2573 0 R /XYZ 56.6929 116.8171 null]
+>> endobj
+2585 0 obj <<
+/D [2573 0 R /XYZ 56.6929 84.0518 null]
+>> endobj
+2572 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F39 1151 0 R /F22 953 0 R /F41 1208 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2076 0 obj <<
-/Length 3928
+2588 0 obj <<
+/Length 3959
/Filter /FlateDecode
>>
stream
-xÚ¥ÙrÜ6ò]_¡·¥*š
-OðzÇaœF)l‚€E³ÃÇ&èo*4ÅžF:èªã‡êˆ\f™( ~8* ª¦ßÝ^(¥‚o2^nXà—O‡C{ì+A_5åñöÐ×mÃÏÅîº=ÖýÍž·í‘_»º|þ#OÕÿþýÅãVxŽó•#}¥T˜[«é/žX¢" >ÞÔå sy9 6ÕoQ¤¦" ê†_?ûZE1.~iÊŠ'[8Α‡žLÁWðù‘Ë2:÷LGq8ìêòB½ãÉõnÇM/ãÑ¢é™úÖ³¸ÖüŽY†|¾å•®ÚUeÏcæ~†»ÁNz¡=k”?Ϙÿ~¬ˆÀëf<¦÷¼ò´jä­¬6}]ÂQšk¡¯ †gŽg¬*±NƒgÀŒÉÁØFë¦ë `4°Ç
-ïøY¸Ýv¡rÆÑ@ߘsScu˜©4^"Ñe6ÌL<Kwò1-øRµ£å e2°Ý¥/‡+œ9H
-åL Ü™
-N¨†ÁHÈÖ[^¥8Ï(;òFÙ}š–e¡ÖÚ<L‹|Ý4|Ëk¾!¸ǵֿ¨K)^Úm/a,…Ü-2z*|N4!Ôiê(ŠDàTìu‹rû•KÒ㥜‹A©¯Ê)!5“"q¿yò
-)L@±á¯î0;V÷)<ë0LHÔ#Ü!!$ÍŽZz˳CÊŽÓm˳;q¯~žÑ„½¹ S¨L§Üe¯'¦ɉôÄDyºæ¢acäÉ«ä5iéiçr"§u&2÷™$©܇e~ÃÌ‚n³/ÞWÝ‚l&¹1_%[c’‘l'üðƒŠ½©JnÔ°£²I˜gY:ûWÞS±¶3~%ÍÜBÇq 椫h)žpÑw­¤?Xñ;M‚ñL“F.n_lª©¨bŠÎ\ò³êï‰)Q2Ï3@X ¡´¹qê ƒ}ñ©ÞŸö2[ïeº7ߟÌ &JÕƒ(y´®¶­Wrx®”klP¬©£.¡ãÊQ1TÂ6 8 YÀñÜÉÓÚfÓI«å?ÒOq±¦™JP‚Ÿ•è ¿j Âô 
-wjd{oŠ~7gŠ°(â‚¥uå&Óóˆ|××<ÄA•ù&Ð륚 j1¨£\φêúMµlB—ÏYmõ(ùëx¢ù–ëiºÔ‚gV -»4_ÉøSæ¡ÕNá
-¯ã>Ôt³˜«ˆ²‘þÀ+¦` ´e )RÉ/dÈë¶ð}zM7ˆ*8ˆ“›wuÆžÌ/‰seò<Lc«f^y"Kãê:ãó$“1É0SðO ÕlQödYÆñ€—ˆOfTÄ!xK5 ׸ƒóˆ å'•\&óÕOJ÷wØüç ¶*=¯Ã¥zP|ṅ,Ä=‚üNK¶“‚r$>#1l–Ò˜<̬ï¢AºLYÇ[q¥€ûÌ kuÃ…2zzÉæqz-TJúÆÑÂE†!úÄ’çxOª0ßÿV*ŸõïöÀ ú°9÷Ñ……Ü"û°cA⊯=ùêÍ¿óì—×/ã-×ÕBþ¯i nÙ¦_‘
-;åNß±ñ{Oï „”ç±Û/^þö |ƒLÜ®”ÝDÁS¾ZFcu½‡î >‘Pð
-ˆ¤70ZO°ý
-;² \HËÝaq µVî>Î/.+®Œ¸± ¨Û¢^n>…Ú»(éP4™4ž}Ç2ÄeRUøý\]HV×Ê‘÷¾œÂ——¨LܢÏÕ]<Éëq e'Y.áìvجY,vSí>w¡ƒšIqÃ
-endobj
-2075 0 obj <<
+xÚ¥ÙrÛFò]_¡·@Æ8&oŠå$ÞÄŽ×R*»ëø$ e`P
+“Í¿o÷t. eUm©J˜³§§ïî¡8àOœgq)£ÏS£Ã8ñùj{ßÁÜ÷g‚×,Ü¢ÅxÕ·7g/¿Sé¹ M"“ó›Û¬,Œ²LœßƒË÷ï_¿»z󯋅Œ£àÛðbGQðöòÝ/—?ÑØû #ƒËï__CWj•À"¡p]ï®yuy‘êàæõŧ›œ½¾éÑ£."…8ý~öñSt^À þq…Êdñùt¢P#Ï·g:Va¬•r#›³ë³ö
+"5‡ºT ð¾*Û“P³9Ô_„ºÏë¢Ù彨“(–s ÷Ls¥Sâ,ÓœÌÅGäŠÄ'‚8Uª…Ô¡‰’v' Á´åêõõ«oÞß¼ùù]¿gÀ"‚MÀ\·›È:­”c†Å¡:a|AI ’Á¡- leA×ÐH{Xn«ŽÆ®P|«M\½»¦Ñ_Xpp!² üýP¶]K³9C.ÊߢHÖ> ªš¦?|÷Š¤PÉô䜺HF¥Üß—{4! 2ßa"Ç7k{‘ùfÓ<p›k›ƒm¬Êñ誱߂—Úóá»´‹â /
+‹5 ÁÂѾmsï&níH³åƒéógSó9U·F ·m^
+j× c¿dÄ‘á%O.ôÊ1|U'é”ïo­Ìù@ëiÏaž‚p¨jÅÌF‘£VOžA@x;œê$ŸWç]>ƒ%Ïlš¶ó2ëÆJml|JÖŽ• ™«Ð¸
+Æ•Õ#‰zåƒ9KúžS>°W}ÌbAÈ’%úY,N¤qnfß36ÖÀwÉ}k´,ò<Тm"ûGb¨)ÛPQY£4ø0¨˜–Ã¥¥ :uGÖäø]óøŠ÷ló¶C ÃöØZðdõpŠ¾"¨
+
+¹Ù°g
+í¸LÚœSAìÚDD³ `C
+ˆÜðr&ø¹¶I 6™höh2¼Q0õ8ß!³wxAxä;ð€« Pk¼zKƒÕfC+ë²,|rjƒ³Ì
+žk“{»‹°Ö `#oÛfE\®Î…fÊCœì[bY(H,Û¸Œ]rÂÀoÞóÊ¢`“ßÒ
+^&šPƒ•w¨ýå¡Ód¨Øy2)ÆIê4Ê=°<ÅdÄj1NüŒíÌ$À´ÅÁQ€ ób¸9‚we튰‚ë‹l aàQ4³·ìÏB¦a¬Ò™{3¤+¶ƒé
+6úBƒ1“BƒÄT·ùaÓÑ<eزA Dz]Ä™Ërp†¨ÕRgÏ ³=tTüö8­òÕœÓ}éÍç~¥ ‡ËR!ÖÐ4âIÁСJú¼OŽû¢™´Ú÷bdôå4cœ.vãòÚ¨r½¾Ç40IŸœÛ7A–“—½O¾G©P‰4žþFoŠ\ äA Tš4Ó£wŸIA{>ÖiæB.-Ud´RW„ÆÈYËÔØÀç1Æà‚’Ø©Òøõs‚›}lŽ&¨Á‰„Ïk>}™·e¢é`H^«D81V8œ)’fÁ/-ãKP'„HF@ü4ý‚%éðà„(•=ÆEÕ® mÏï8X¨8 ÓLÅS¢.KWvÏ\M6“Ó›dbb:pÞ‚ãŒ
+щ˜£Þÿúú1îÿ´qãendstream
+endobj
+2587 0 obj <<
/Type /Page
-/Contents 2076 0 R
-/Resources 2074 0 R
+/Contents 2588 0 R
+/Resources 2586 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2056 0 R
+/Parent 2549 0 R
>> endobj
-2077 0 obj <<
-/D [2075 0 R /XYZ 56.6929 794.5015 null]
+2589 0 obj <<
+/D [2587 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2078 0 obj <<
-/D [2075 0 R /XYZ 56.6929 258.0612 null]
+2590 0 obj <<
+/D [2587 0 R /XYZ 85.0394 749.2922 null]
>> endobj
-2074 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F53 1029 0 R >>
+2591 0 obj <<
+/D [2587 0 R /XYZ 85.0394 666.7399 null]
+>> endobj
+2586 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F41 1208 0 R /F53 1303 0 R /F22 953 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2081 0 obj <<
-/Length 3216
+2594 0 obj <<
+/Length 3279
/Filter /FlateDecode
>>
stream
-xÚ½]oÜ6òÝ¿Âo]Y–Ÿùè"iâšËÅ.z@šÙ+ÛBvWîJ¶ãþú›á׊ZJë4‡Â€E gÉá|ÏPì”Â;ÕŠPaäii$Q”©ÓëÍ =½…¹·'Ìã,ÒrˆõÓåÉ?‹òÔSðâôòf°–&Tkvz¹ú´8ÿðáÍû×ïþ{¶äŠ.~"gKEéâ×ó÷¿ÿËÁ>œ¾8ûæ^¹ 1Šx]¼¿øíÃëó³R..ßœ}¾üåäÍe$kH:£iúóäÓgzº‚ürB‰0Z>Á %Ì~º9‘J%…õÉÅÉ₃YûÓ+”ÐDi^fxÁù€ŒÂX§¥2¤\X^üÕnk8˜”Åâò®†ãšbñëûó_ßàP-þ ”×땃·7ØßU½ƒà¯èôâßç¸;czQ_·ö¹r“OÍzíf›U½í››ç°”ßsSu}½sÀ®Þ=ºq±¸iw¹M rþÇŸ•œž.#F)nOvßîz‡•pDJÈˆÓ í*û#ÉÅöase‰
-ͽօÓj§dDKÁ<j,ÿû]½uY}ŠûXP×K§\B€r+ôÄCåÚ€^ÂBLZÙ &÷ö4í#Ø?è–£"'’»ÜvžjaeLɺÜ aå6r¿ìØ3 ‡ÕÖÍ##,c».L¬ÜÀ)3â\ßµ]½uЫg³ ·[=ƒ«Úä<Ð’ñ’(S^°#ŽÈïqm‰£–¸¦oÚ-(dzƒ\ÕãF}랛ꋟKEP¹¸n7~îÆñ}ã×whç×îIÄ(PëF´m÷Sâ-ÇMç¤ï‘ˆ~Ƈ8ι±h—]×Ün½çð®=ç
-Q% €Ízˆ!Ö´‹ˆX!ºíq|xâ”"“rž†ˆ•!"ñ -Q:¥â"ò ½ˆ¯ÞU
-!çÍgˆ5m>Ë:¯u¢ªN*¥˜§"beÈ80 ¥Š”k@6±œÌ[,}¨°Œú|‰æ– AŒ ¶àNx¨-úJ­’dòåIÔ€oM—¥¡ %Ó/ÿî}†‚` Á§d/ $«\‘ý
-dÈYês`Õëu]í&NåS/àÂA^"™Ö
-JÇ|À
-ÙDR­m”ñÀÁ…¬mäç’õÖMH¯›Ê‘"Yb% B{¬¤—Yr%8x
-&z¸ ðE*„îå—¿ï-%è-]ûfÚJ†XÓV±pÇÛôæöÀ&XA(‡‚rv㈕Ù99$‡Ü€J–ný[çeðöâb‰Jí%Öz‘Æ <ÊÐÙÈÊGËË»¦K‹y¨7p|¶ÐK–rî­$#k£@JE¬ËÛ㲞Ð-Ôªi
-JÀbŽø¹!ÖŒ–¥f½š¢ÀTN6»wÄÊlžF:
-àÙ“Í ¥ô¼jñû™Rö­Ú§ÎÍpJ©›#îË<
-…¿Œµ!øˆÔaMê$~Z„}ÙNª…ùµ2*#ŽökZ-"R³««µ¯k?¹ñX;$d8…)Žµ†91’lcxW<B/“kR)Á’2Ý/ a”«y>E¬ÌÆiÿË¢:ÝØõ•„Ø·fÄP-ÝD.¬2ΉÆÞ6p|t
- ¼ÂØùiÍdŸz&ÚÈãPõ`¿uY/NM·Šè>+K~ÄŽX3v°lÒµ«wõŸþŒ_Wí¦j¼Ÿqãe®¶…˜ ²¶Î’±2t¥|Æsð› aÑáú¦ÀÙ’™Õâ…O?Ý>ØÁu=„îoc†á
-ü˜ ¯r$’BÈHFh¶½j¬'3i!B•â<<i™U%JYþ­ö_»iú>¶þÞ½wO4»fÛ×»mÝ£î§AÖØÌ<Î%áZ¹bÍDÀ:tŠßmŒ‚Hg‰XjÇA¡žOÉu…ˆ¤4^yíÍCÒ`8_ цֱ‡î­ŠsÖ"ppÄ"$pݨY„|EŒZùÿ˜IhHEeè9m:/~ë+æ,c‘Q/2â0ƒ¢ÐG dˆ5m ë{ ÄáU}EÈáÜ@Y&ÔÊ#V†ô„єɊí—ùþ$T:Ì߆äåK¡x@Ü!Ëröë;á×'½¡ñ ÀÝÃÕÑ8»ÆÝÄPzk¹iwŸ7È%&Ý]µs%"^vâÃÞko²_ãèKõ½æì¦úص7DëØ_=˜BemïÇiü\áˆ-‚ÝêØàˆ]i<=ûª±-hd‚ý
-endobj
-2080 0 obj <<
+xÚ¥Z_sÛ6÷§ÐÛÉ35C
+ÏÓ©êŠýd‘Lœó¼€c¿ ÑfNŸBé+rÉèE2C Ö
+Uk —<åS½®Ð”ó;KuþŸL”ïV)À4*…è5??VÏ«Žê­’8¡:˃ÜÑ”„LêżdÎeL”%
+ã–ìp¾Ñ&nW[ÝÄË»ÂÖǬ]ÓP¦CεÛÖS­Qð
+ªq-µl ¦úaó·;ìw]oó.hÝéD˾§‚Õ䲪q†Æ.[‘X°ð5!Ñ“Ø’^£Jwópù­îk»Txë§jý±'.T>mØÚI
+Š„S$èqOU_Ñt¸"¤{¿RYs­Ok³B…+øíNûñóÄ *A±kN ;M˜º¦zÙº-°þëøí[X‚HN­vü¥¦û|ß1­æO‹UO™æ‚J f¸„QNJÇNH ÏŒïÍ¡çeVÌÑTﵡ‰ê…c3Âþµ/ÿk£ŽjÃrÃÓb5<ûÃz]YÌJ”Y¾³Ÿ2 —70ZMVû/ÜËl͸Ã ž0¤»\89ïh8hcæ„›¢ÞÎÖ wpóƒ°UÙxiRY6=5NÂò=Ù§­«ÂókuÍU]Ç{z6þ:…ÏIÍ+Y|Až¯Õé:éd×òÁÈNsÃéÁ.²ÝvŸû9W.J©C=À½É<î
+×áSX­v4C‰œ)m/Â÷´“PÅéD$>
+·ãNÑ$H*ÉðÜ˹.¼Hò(ÁÞþ·[µ:R2v’Rú"!,LÃèàò¾ ,#)MÑ^Ø@pªôÌÈÐÇÈ­s½s)Õ4®t%®éfÒåëûÛ×wtA°@k/@·U‹Ñîîüúo=Q~½%âziÒåét *„Ä°yvKñžî\Hô
+êp
+˜&å‰#„*Xþ7úmFÖ«ü>–d±òÆ5ÁÅõñs ¤"! ê›@šË(æ»`TdÙEaFQ¡‰S‹–æQTÿõn¢¤¹4ò¬Ÿà–ÛuõL4¾:&Ü;œÃ!ÛÑ&†Ûy8Ë7+\l…³ pŽg¢¬*zR»
+G”R•ýñF§iwMU3Ì…«]Ÿ>Ú×ôŽ"b.H$µÝ8ÅŽs×®d´‡8Óï;A’±ëêÛÓ¶îêë­/%Ï„Èt”ƒo^†‰ë<Lx.— i{9$Ÿ@ƒÄÖ]~YÇ4# `$Vî&]ÒÔg=¸XP¤zôl|KWdîÂ˹¶MýpÆå`±‡A % <ñ?„Š8À,Êeœp¡9¥6ͬm"øÀKχƒNüïµ¾#ŒÉ5Nši\ÙÜwÕo! Ø\HºÜ<4Ê—ì °A1€0»^Ê
+ª•†¯sÆݭ̤ê²ö*äéèé±Æ«‚ÚϹ¡>_¸Ã¯cS*OSR$”üø?!\ÿ~6tdi°ÀåÈ™.3YÔÚ.£ÚáÙÈ‘™¹(‚g:•á$rb#'BØÀÙ<_ªY¬pü«ð+.PfU(¼
+endobj
+2593 0 obj <<
/Type /Page
-/Contents 2081 0 R
-/Resources 2079 0 R
+/Contents 2594 0 R
+/Resources 2592 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2056 0 R
+/Parent 2597 0 R
>> endobj
-2082 0 obj <<
-/D [2080 0 R /XYZ 85.0394 794.5015 null]
+2595 0 obj <<
+/D [2593 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2079 0 obj <<
-/Font << /F37 802 0 R /F22 737 0 R /F53 1029 0 R /F21 714 0 R /F41 939 0 R >>
+2596 0 obj <<
+/D [2593 0 R /XYZ 56.6929 507.1706 null]
+>> endobj
+2592 0 obj <<
+/Font << /F37 1018 0 R /F22 953 0 R /F21 930 0 R /F41 1208 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2085 0 obj <<
-/Length 2191
+2600 0 obj <<
+/Length 2967
/Filter /FlateDecode
>>
stream
-xÚíY_oã8ï§p/ ¶ÑXÿlùå€ì43×ݶÛf=Ì΃+‰1‰Ý‰vzŸþ(QreÇMwïîñP –(š¤ÈŸHÊ¡£þèHÆ$NY:JRAdDåh¹;‹FkXûxFÏÔ3MC®gï>ðd”’4fñh±
-d))EG‹üóøGB#2Ñøæî·Û‹Ù$ãÅ|2eLðx<»½ß\\þs3pFÑøzvóÛì
-i·“”gçw“/‹ŸÎæ‹Ö¬ÐtqcÓ·³Ï_¢Q;øé,"<Urô“ˆÐ4e£Ý™œHÁ¹§lÏîÎ~m«öÕ!W©ˆd"M¹
-ô;Œ’„R`JdJbÎxë0F‡湌ÃyÖhÜ{–ç8È«]V”Ó2Û¹•¦Ùâàór›ÕõG}~pë ##„ô}ÆbE¸€Ð„†™ßr ØÏûY g©èn`–çõdÊ!Ì>Jýdr¼ŸP5Öuu°ƒ¥Æe¤.+ûÌ‘öT45ÇV?èeñG1›]½û yh
-‰P\ÀŒ Æ=–©c/MHÊ™r<çb¦‚Å„šðRJR)™å´.Çá
-yç´'®žð\6ƒéûÃúÈ€ŽD¤§µz¦­GDDȘuµ.&i4>ìKÜåžÖ–5€…à åœ$1Ôï)U„&˜k®
-ûšž€“ÁîSŠua)PÏv[»Å`?[ÈÜvÁæpKtɼJ**”¸
-SÖ®Ë8V-L[“ø¹¬ÛUÜkTp¨µ£Ø# ”¢¬õ¾Az¹Þêƽr\÷ G·î»=­ì¬Ú9 >÷R•!˜ìf_ç²´üÐ`ü«*mÆQñø¦j
-LáÄd9RQ>\•)J$él¹q#”‹WvjœeNÎ>+¶m%òé LzÂQ]õ•gȽÆ-ìÖ¢î–l-sxËÚ4ÛYÝæ̬öçÁw}ÏÐ!Kœ„¤/…ºî¥Û6§ì ’AN±ã—6ûè©«Ê ·;œ Ú/‡þšÅx
-ÔnŸ§v)Äæ‹‘†¶ñÐv©™ú[Í3 w;ü#’‘ âŽk^•þO¡ù°×{ýͱÇÛ˜›˯æ¼tÜøWa9$£Ë÷7³ë¹ƒ]µÓG¡ûÏQÊ‚"óJ÷ܦ¼h
-[ M"ÓM¿…w™Ã¤?Ÿ9Ìråü^~õo)¹Ín¦A'¥{q €´×É°€—Ì:«É܉œãÒ™ô¾-ãK›ÓŽð†³ÑÜKâ6…ª áª~ÂUãŒÚŠ•N¬‚7ñ¤¨6ãÂ>*íi•{U/êÆ)ËÐ Ã
-Î`ãž5>ýYõݸ2Ýv}pÎE‚‹ Œž6ÚÄYQ·AÕBðH¬½ ©Vå2+Ñv3®J¸Wñbé¥bÓ¥¼Û@<4\ëiÝ@µ3u`Oû øÖ”cš*[­išŒ?}x7fD´Ú3$ ? aw¨G«õ'ÒLš±¯´BeCmiý¼dÙ,fµX9{B¡uO*N­ÛŽM¾²' 53)o
-™¾á¬€ë„·<—±ögŒ"!#I“$vƒ•«®¡$AREýG,»…c!ø¥Ë[¿%…ü`œùÀ A‰œþYsö€^,’=9€KKù–AÞbòU?}TàºÉ$=Ž–ë8Ýo”Å¢û¬ÖÓXøo$Ë*oï±þÊðëÙûéõ…Ä™±oxH]ê0×`¸²†vi
-Œk]Ú>ªm›±Æb"é[ß°B®Xó\ÿÇÚ)¬=ì‹G×—vðƉ¸§CÒrǤ÷í9!U7(-ÞhâÍ̪>_ðffofÐÁ›!Ü»…xë× È¯ጧÝ/&wó9Bwvu÷ËÛŸML¤<>Çw`Æ£(y™1ÀF0SB¾ÌLk¬A1 f)§ç/y:o·rþ×Ε; °Aó›Ó@£Ö%ÿõO[/?á ¨MJ±×~Ðo§0vF/,ŽSBD‡{ñíÿT#æôendstream
-endobj
-2084 0 obj <<
+xÚÅZ[oÛ8~ϯÈÛ:@ÍáU¢3h§è St›3@'Š­$Bm)•ä¤Ù_¿çðfI¦ä´ì"@DQÇäá¹~‡$;¥ðÇNµ"Tdò4Í$Q”©ÓÕö„žÞ··'ÌÑ,=ѲOõëåÉ/¿‰ô4#Y“ÓË›ÞXšP­ÙéåúËâüãÇ7^¿ûëlÉ]üJΖŠÒÅç>Ÿ¿·}Ï2¾8ûæ^¹ 1t ]|¸øüñõùY*—oή.?ysØê³Î¨@ž¾|¹¢§kXÁï'”ˆL«ÓGx¡„e?ÝžH%ˆ’BøžÍÉÅɿÀ½¯æ§1QH¥‰â29]
+ItcDF U €eª2’.‚À8‹ ÌS¡À¾OV.U¾-l«-VMÑ×ÏTJ( ?Ç'ž( ïqÂNÓ#V.î‹Uù7¥¼hMÝ]ÞÙV¾ÙØÆî~wþ{Þœ1½(qmŸ×îýòâÝÛe[ÞVÅÚý´-«[?pËûå7%z\q¥ש†¥8É8™À/àe/–ñj(#œSæ~wŸ— šARP!ÍÀ<Á`–Œ‘L)nˆ.= ±Œ°$Íö Äfƒá2-ͪÞnójmW?MS®xà5¯œjƒŽÛ aÿ‹Ê>Q ¦1oSV®û¡Ì-+²Ï.× ,˜y^–Qv%‘`ÅŽ¤n"À\t¢¤åkl':KB|Ó9@ÊR" 5ï%=ª/ñT8ãmÛv`K>ÁB9×óªÈ̃ErF(•l8õçÖéàíÅÅÚi¬v* éÐúÈbš`àw¥³ÿ,¾íʇ|STÝh(´Ž›'ô’ˆ®3ZJ¯¥Û㺞°-´ªI &:%\=¯Á>Õ´•áf³žR¢ ðSXÙìÜ*2ù@B‘LêáäV‡R:YHµøóL©EY­ëÇÖ~á”Rû œ¸-ð »¾±=åã0µíuÊïÜS>Õ^ù@`Ÿj¨üþP¨ü¥ Yì•òaÀš´ E”†ˆïÌ¢ž4‹ìEf!A§*ÉŽ˜EjÆ,<rÓùfkùøbÛcë‚È$K,KüœdZëxÚ_†ðËdQ
+°mtbÆs?è‡ìˆ£‹ J´ÔWN^³)ãUdœ¥PÈp#bPÔ‘ñ ÷ŠTûZëÉ,ȈP©ø$RZdT ‰Rú:ÏŸ÷GŸÀêmÙt~eßÞ}°Ot»²êŠ¦*:´ýaÒƒñwÛ™„I›
+ Í:DŸjÚ!ÕaP|±C0
+*e6PE¸;…z~È®-D$õi­ï’z÷ÀïyŸ¬ïûÞ½wàOÑ#ð›ñlñ RÏÔ³<B>Ã#ØÿÉ%4@Qé÷œ¶»Ö©ßÄŠ9Á\”©g9Hò¿p¨rOTv}ªñT/uK—w9!Œó Ê2¡Žp¨"¬M‘,ñ~ߟ„J‡e>¶!{ñE(î‰nŒ£ÔXuÈ0ûê[Pí£0° ;î­gçlK³ËÚ'éŒ cÏMÝln€%&í]ÞØ1QèÏ"‘¦Ê¯«ÈªtŠ¥z©;‚¸i0Ø)³æ
+v,BE}œ;£iú<_¿Õaƒ#ìJãêaÙ×¥Ù‚F!àf öšžÜvX}@Ãú?}jÁ‰%mä´Â–|>ÉÚ˜u–Y`
+Ú}éE
+ ç-?fáöHËä*ɇ®EB1;åê áLˆcȈ%GSŸHöA ÔGÖòë‡rm‘‹€ [a0Ä&Úðö̊̌ʥ9‘„Ïײmýà6ߥ æ“GGö-Ä*cé
+Ê•¡“ƒSP.£RÿT±SÕµ»ûûMÙ;.ŠE¯ŒNiHÒÝ&&~¨ùPüÈømU»]ÁW~7a=„ˆNÊóÖ~É$ÃÁ=­ërSvOg "øt\a7p¯j>®ô¨f⊧Ç•|½ž*(˜Ÿ„”I&Õ<û*ÂÿR&©ÒÃœ¯ÑtEj!<ªâ*bõøy\iaŸÝVÄ–Ýä†Æ‘Z‹,ÓbÞnXJ2ës6Ø?]iMÄ“蜴9ž2’¦É‘¿O5msÊÂèúñइ"ÖD3;k ŠL;<V—Dà­’Á¼¯Ëö~“?¡w¦‰ÃÐXíkæè:¶EÛæ·ºµxÑ7Ø`
+_í•ÔÖƒ&j ó# ±¿ç/ÃS ì(«U±Õ&%Œ>£CËMîËb
+–†]
+¡ÞÞÞoì-5ËPc?˜ˆn:]h?8òç}.¬Z;§–x0 ëU½Û¬íöúdzx×c/Æq@¡mÑt¶Ï
+¡F‚Xñ'"ðH÷ûJfƒ™N¡$䣒Љƒ¬ = Ü5À°£“Ňº+m(Wþˆ$U>Uà9ùýÎeSôB—ÝÄ2-;®}q駵o¹§É4úŒäc|p7Û ÕÖãÉsK}k—¸»7K£CìáOÆÜÝ•6bemœyÀ¹âÅÂrÕ¿­Õ?Yÿ¶+ÚQÌ ae ­hol6¾7ÀæžØÉÔeVæ½ÊIƒG¼ø¢ëþB¯L–LEW(™ˆóL¡œY"Ƭ+¡‰Òàœ‡¼ÿ•³¥endstream
+endobj
+2599 0 obj <<
/Type /Page
-/Contents 2085 0 R
-/Resources 2083 0 R
+/Contents 2600 0 R
+/Resources 2598 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2056 0 R
+/Parent 2597 0 R
>> endobj
-2086 0 obj <<
-/D [2084 0 R /XYZ 56.6929 794.5015 null]
+2601 0 obj <<
+/D [2599 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2087 0 obj <<
-/D [2084 0 R /XYZ 56.6929 553.8035 null]
+2602 0 obj <<
+/D [2599 0 R /XYZ 85.0394 107.2827 null]
>> endobj
-2088 0 obj <<
-/D [2084 0 R /XYZ 56.6929 216.683 null]
+2598 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F53 1303 0 R /F41 1208 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-2089 0 obj <<
-/D [2084 0 R /XYZ 56.6929 83.2768 null]
+2605 0 obj <<
+/Length 1792
+/Filter /FlateDecode
+>>
+stream
+xÚíX_oÛ6÷§0°Rõçe€›8YÖ&ËjØÐöA‘èX¨,¹¦œ4ß~G¥H²ìtkæ‘<w?ÞɆ~l(<â…N8ôC—ÊÄ0^èðæ.ÌòL*¦I“ëíbpzÁýaHBÏñ†‹eCV@h°á"ù4zK˜KÆ ‚Ž>ÜœŸ'Ž„îhz{;»9¿ú ú‚pP:ºžÞ|œ¾Ç±Ûq茦—³ùøËâ÷ÁlQ«ÓT™Q®uù6øô…Ðü÷%< Äð:”°0t†ë+8.çÕH6˜þ¬6fͧ½&`”8Üszlà²>¸>ñ|mðËxâÁîrµÛ$Q)õ†@ê„1
+á–_‘Å2:‘™¬è"KV…*‰ü­7™$q±Æ‰i[;$,J«„|ì—x.¥•PÓ0ß!Ì#Œ°#+™'zúôÂqv
+Íš6[¹•ß,û÷¤XGin{iü5Ö²eÆÃø3,ûdtqyv3½žYØk¹çºŸE):È÷`¯Æ!øÿm—ª´43b¤m›–i‘#ã½,Reõ­Þò*¹}
+5ÂXÕ²+ÛÌ
+¸½ž›0‰wt'µ34… ӱܫb9ŒžßÌç³3¤SËi,¤ Gp”>ˆº²¬xDF-Õž^EÒÊø0¿º<©×x7ûÛ
+È­7zÙvÎ&ÑÙÆ 6¬·h‚ u‰.eôgWï{jF|Ƽ¡Ë)€¨QiÒäÂ%è)Qj.½ê©,ãÓ-Ä—ì¾ì*À„C ðãÔ\û*´â.>áLxmvªÊ‡&Zê,šÈ¼L—6ã%rí²ÒæP.hfXŒ‡!qXý¨Åš\‡-Vs‹=DÛÓí.?Õš$§
+JH ä«|êªâ0G»—×¥æÚW¦e;‡ù„†Ìmk£0‰:w̵
+…FØ#)}“ÌͽÆM‰úÝÂŒîf$½êª÷-ã|¾°%Nz·¶ÝJ(­Š¨xû´)‹ûm´Y¥±Íq ªC‰§Nì»Ln³Ùºz’‰WQ~ß©¥–»r÷|q®žz2 !N5çîzµãq<.ê÷Sa”§yW›‚hûlqS§Ÿ½Ç ¨®}7Ĭ ¿Æ#ÇñѸ"/šEf Ä2ÍÒòéÐC,¤ýzÚ“hÈŸ~¤}~„vácRw´UJïœyî~EaŸs÷uÿ¡©Ÿendstream
+endobj
+2604 0 obj <<
+/Type /Page
+/Contents 2605 0 R
+/Resources 2603 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2597 0 R
>> endobj
-2083 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F53 1029 0 R /F41 939 0 R /F48 953 0 R /F14 740 0 R >>
+2606 0 obj <<
+/D [2604 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+2607 0 obj <<
+/D [2604 0 R /XYZ 56.6929 462.0323 null]
+>> endobj
+2608 0 obj <<
+/D [2604 0 R /XYZ 56.6929 288.682 null]
+>> endobj
+2609 0 obj <<
+/D [2604 0 R /XYZ 56.6929 209.4795 null]
+>> endobj
+890 0 obj <<
+/D [2604 0 R /XYZ 56.6929 155.6441 null]
+>> endobj
+2610 0 obj <<
+/D [2604 0 R /XYZ 56.6929 121.3428 null]
+>> endobj
+2611 0 obj <<
+/D [2604 0 R /XYZ 56.6929 84.4903 null]
+>> endobj
+2603 0 obj <<
+/Font << /F37 1018 0 R /F41 1208 0 R /F22 953 0 R /F21 930 0 R /F48 1228 0 R /F14 956 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2092 0 obj <<
-/Length 2606
+2614 0 obj <<
+/Length 3314
/Filter /FlateDecode
>>
stream
-xÚ¥YKsÛF¾ëWðª*σ£ly½J­m$§¶ÊÉ"Ae`ЊþývÏÀ€ åªÌ4zzz¾~’Í(üØÌ(BE*gI*‰¢LÍ–»+:ÛÀÚ§+æih1¤zÿtõî_"™¥$Õ\ÏžÖ^†PcØìiõu~óððñþöî× ®èü=¹^(JçŸoî¿ÜüÇÍ=\§|~óéã#¼J“J b é4ÿvûáúϧ_®>>uâ EfT ,]}ý“ÎV ù/W”ˆÔ¨Ù ¼PÂÒ”ÏvWR ¢¤a¦¼z¼úoÇp°j?R†(Ó p6yS¥x¤•-¸°JxÿåÓ#ˆù@at
- išpKõ´ÍA Œ§k6¼ûä^¾å¯8`ó¢q‡kfæùêX­²ª-ýbÓÖ~Þ•{¶Àê¥vã&ßg‡¬õ›üA)/sXn@×R(Ø>ìàžlž¹×e]5ù_ǼZæn¾^»…ª9îWž!››¢Úø]á$p\< SÃÂíã“»ò²x>d‡W÷²Éí h7X^÷m½9dûm±tSõ>Ñ äg7‘U+7ØežÏr›U›Ü³ª<ïc{tzqïn\æY“ñÝÀõI"¤æþJ$'Z'Æ]@ñzÁ(@öP­–áPB‘„ä>Ûågî6%‰P–È~l%øƒóÄ*üÐŽšüð=÷J
-#u7¦eêÓ_\8©&Nc}ž¹ù¢i_KËÊŒU`çlR+t64½ÛÀ'6äÔMëy„•ŽÞƒ^'èÁÿÔ ¿oö˜™£üp›²Œ6j¦2ðÆÁͽË8;‡€ t•û´swl<åsp/€óà[ž}ιÇTì7 ¤šÍ„[¢&üãØ8.†,] Ù„”Ê´ßÙÇ~'jU¿øâ ­G
-†ËSÂèä²´rsx–4¤jî¾2猻W¶°Â*lsì‚9¬ùºÌ8 Å|•·ùaçB Loë7ïÖ-£6[¶~rëÉB!®™.ánüâB5.wVêLÙ#BQ\mjK7¯Ám},ýâ¡y©jq‰Ó¯6gz<©ò}ÉÁƒ™œ¹\— ©BQ~Z—tT¸oWŒ¨¡ŸdĤJœ-F†2Ø]sš^±£š1ΣѦ"!¿4ùDâÍ)$ Z](™"Ö`7¨P‡d6ê±]¹ýá¹ÌÝ2rîÅS:_–ðð 8OÏ«Œ, Õ
-#R'£Ê!ÿ»hڳdžCù†Á ©Î\Ge ®yÓûöºÈÜ# ªŽË¢uT§²Å&$4a,Ibá†=¸ŽhËÎâ\O# …\’B¹EÇ{»°}Óƾ>Ãá.k—ÛÜ”’B4oó/xSÿ—Ä€-`eá®]ƒú™Jã[ݾ0½ÛÆ%%§9ºaD'o”Ë ÄDô¶œP… $Ë[<¸Q×f0îo;uoYØÒÞœH!‹2ƒ®ÎbWû,41`n[ÛZÏp_ÛI¬£p*üa²`”&GïÉÑÿeÿÛÑå8Q/gx ƒÔèLËO@]&Å*„¢@‹¤7ùqCU ®jPJ¢«:kÏ©")wÝóæ< :oÍÈóþÍèzã‘)sl#ª‹BšS¡¢¨É¡zä:–ê1¯&»u!¿µ--›ÿv}ûØ7𔈤ëÚôTñ}i"iðÐ}ЀÁ6]í(ýÉ‹àAwæ_©¨W€Ûú¿å@›g/¬\ð7’äžæüµz{«¿7KÁYRp–6 $'›E×E!-6ép³Uß-;|®ƒý•õf¥9÷O5$ÌøÁ„,´+Œÿñ¿Øý¿ôë=çÏ% gfƒPx0Æ“±èÝÿݧ²ÿÌdòyendstream
+xÚ­]sã6î=¿ÂoufÖ\~K|Lw·½tn·{MÚ¹™^[Ž5kK®%'—
+#g™‘DQ¦fËÝ=ÂÜWÌã,Ò"Æúþþêí"›b4׳ûuD+'4ÏÙì~õûüæóçŸÞßþûzÁO®ŠÒùÇ›O¿ÞüÓÁ>_>¿ùñÃ<ÊÜH@bñ4ÿòéý»ë?îºúpß³³Ì¨@^þ¼úý:[ç?]Q"L®fÏð@ 3†ÏvWR ¢¤²½º»úWO0šµ¯N‰@‰œ¨œg2àlÆ1JñDÊ-¸°B¸{©›}[µã­hàG
+ä;÷ÂþPÐ㹟vƒæigÛ#¬rxñäÖN"™$\Pâî>§pÅÁ¡¢y[ÎU¯Ã­{ràG/žŠj[<lýãÀÿ»:xX¼2­ä,#Fðü¢ÈaŒ‰^Éw»c]-‹UQdÊ G–S‘i¯Ðò
+mÇM?*ÜÏý»Ï,§.—]uÍæM R—4ƒ7ëUU?:ÌA4öõ#¬Tw–‰•W=Ïd"è 
+r¾ª«®ØâðT=ÖEwtziURŠùmí0´ky<8Œºs3À}FùÛ8žkùªKªƒ@c¯Y©!AËQ˜« 2‚cz?huUö%ÈqûâF±–™Dxè¼áj"s-RÃ-¶ÍD¸ÒZXkÃß|¼y·øø^ኆ͟7ÕrãfŽméq
+÷ÓnœâÚö¹\ºçÎ=£?Äß²$ÊÚ¢Jë"àt
+AGšNLK3¿ßŽ"'eïj«ØÑFîïn\´ÝËÖ’ÊÇ"°°5z
+ѧVò¥„4XÈUHB
+{å±pµrû>ªç²tHÈùé`úWXä9=­f„0²$\Qy.SEúxÜvÕ>„UÝvE½,Û8Øðs{Ôÿ®l‚éÛ­³4Þ®³·»umkï¤{_ÇF~ûùIŽ"
+ ;“Ó&
+ª¡\ŠËüõX &
+ª5¡Ô(ápZA1#РógÒî„®Î
+«G–(Öwp¡¾Æ
+Éõˆ±»²ž,Ø…(×VµlÜ—îS™ÈúÂÍ€•žš&’?=\‘Jغ«™ï< ^õw}9z¢\€Ë¾ñ¯Ã­wöx5'
+«à—7ºp¼Ëïoã% 8N
+Žóâ’ibÉää(„ɹI—üPÅS°Ì‡&Xä¶y|„dä¼'Z õŠ"¬ BXV/Ó:.Ÿ7Q©aLÂÅœñ„¯o*ÕôO71b BªÓM¸&Mjƒ†äšñË‚ë±&$—œ¥ØP骿ÚÃӡǃ>K»•¤IÕ…ž…x‘ õ÷I³§8!Í$ƒè$£\L‰ó$ˆ'Êèo¯YïF8uí
+‡oš)‰Q`¬\X \­#_­æ;ˆïŠG¿âS±­Výu­üMƒMÁå²Ä»y!¸ ‹
+aÑD¿Ú(Â4çç[qȘEþ.Gmrñ͇ÝS\Ä$O[Á]§y¦†•Ï6i€›³Q“ÜF}‚§}¹¬PãËÕ›©#z¹¯è0Ê!\rÑÒF²R¼1š/.±tå6j+ëøcóK„ÇxüøëÂKʆ•&>ÚÆÇ€K܇ҵĀFeo|—1‡€BÂP—0H—廡2ŠùUóKŸ~„¦oÙöNOMß!ÈCÏ)mžõÙüÂeÛØM °ñ¹¿QQ¯jèÄzžSmdÔ¶ÅõüScsdjúžušífÂÂlâ:„®¨ì‚07©pv°c’(˜ªœ
+VÊÓ# ¢;\ƒnÔ{€l²¾øòUéÞOͱ›hè§zâvi{;~fSn÷¾3èî’Éö8ipá4O»<ÿ¼ýx{o¿¿Ã}ÇçÿýF&Ú¯"ÅjùRvÉç}¯`ÜíL $NŒGéP>™)kbxßá;óiŒÁÅèÓÆXè‹pð´&g,Õþû`wXX4΋ÂoômÅÈú`ø}.< ó€¨ƒ€àÌ`&ñNܤQ<;×̱¤3Q4W"L¥/…x‚ÀÕ«ðÛ0ûö
+endobj
+2613 0 obj <<
+/Type /Page
+/Contents 2614 0 R
+/Resources 2612 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2597 0 R
+>> endobj
+2615 0 obj <<
+/D [2613 0 R /XYZ 85.0394 794.5015 null]
+>> endobj
+2616 0 obj <<
+/D [2613 0 R /XYZ 85.0394 749.4437 null]
+>> endobj
+2617 0 obj <<
+/D [2613 0 R /XYZ 85.0394 680.7174 null]
+>> endobj
+2618 0 obj <<
+/D [2613 0 R /XYZ 85.0394 501.4297 null]
+>> endobj
+2619 0 obj <<
+/D [2613 0 R /XYZ 85.0394 100.9714 null]
+>> endobj
+2612 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F41 1208 0 R /F53 1303 0 R /F22 953 0 R /F55 1311 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2622 0 obj <<
+/Length 2462
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Y_sÛ8ϧðÌ=œ³[³ü#RdßÒ4ÝËÎnÚkÒ™›ÙÝÅVbÍÊRÎ’“Í·_€ eYfšÞÜt¦¦@ü
+;o·ô¹)»®¸/;úZ¶»zEÃÛ2ê²ð+ÊíižÍƒ¤˜ ÁœÖwå³…oiÚíâ‚Vžýrý)pUfp›T@Döm³Z²eÛÜýÎ5×ðŸxCËqb÷eƒsv4×›r•$&E¤3‡‡•Œsð%ÇûË«´Ð…“¬6USuý¶è£Ý¾”w%™¥YKýZ4;°òñ‰…±Lc‚ø¤ ™æÈäÈ”™s§_oþõéËëV¼lúrÛ”=irýÜõå&øô¼mºvÛW»Í~ߌ©ÌD×eŠI®ö@#¶ÌŽÙ2Ál–çáƒÏR‘w¡4s8À%Wàœ XLŽ_9—IÁ“ЖÖF
+{%Xn´æ̘̥`*@[©1ŒÒ† $ ºz/ÂCøÀ$Â× ?‚_<Á‡‹ëó/—Ÿo.?]½`ñüRÏ™t<ZLó~]â anœ æö w
+WBF/57‘Jù GÍnsëãep¨ßì&R"€4P†éùÚ°Áå]êÝ yéŠq3<œ}ÓÒ|â¦^JêÊð&êÊgêº#Ãaæð$Jà8º L!_¡¼¦ëË"|x‹Ç&Þï! ctŒ¿}«ùEáÝv¸¹î "ã°Q¾”`ÊâÏ’FDÑX¿¡j@ ÷¯4@@»ûm„ïoʘš»ÛWKˆÕ̉Á¤ñ òP$öÂC|W½àŠY=ÜÚ ðØ9¾4ÈܤÉ'•Cy–ö$ñï,ÁS£²wáI<…aHÕeüüª .Wd™Äˆæߨ#©?rA9Æ¿L%ž³ùðýÿlÿ§Á,gÊZ™þÛ–Ì5ÞÄLT
+­'Œ9R=þ©ìX÷¿òzWqendstream
endobj
-2091 0 obj <<
+2621 0 obj <<
/Type /Page
-/Contents 2092 0 R
-/Resources 2090 0 R
+/Contents 2622 0 R
+/Resources 2620 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2100 0 R
+/Parent 2597 0 R
>> endobj
-2093 0 obj <<
-/D [2091 0 R /XYZ 85.0394 794.5015 null]
+2623 0 obj <<
+/D [2621 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2094 0 obj <<
-/D [2091 0 R /XYZ 85.0394 752.0715 null]
+2624 0 obj <<
+/D [2621 0 R /XYZ 56.6929 713.9465 null]
>> endobj
-694 0 obj <<
-/D [2091 0 R /XYZ 85.0394 700.8318 null]
+2625 0 obj <<
+/D [2621 0 R /XYZ 56.6929 649.6644 null]
>> endobj
-2095 0 obj <<
-/D [2091 0 R /XYZ 85.0394 667.6704 null]
+894 0 obj <<
+/D [2621 0 R /XYZ 56.6929 609.8446 null]
>> endobj
-2096 0 obj <<
-/D [2091 0 R /XYZ 85.0394 631.9578 null]
+2626 0 obj <<
+/D [2621 0 R /XYZ 56.6929 576.4481 null]
>> endobj
-2097 0 obj <<
-/D [2091 0 R /XYZ 85.0394 565.5242 null]
+2627 0 obj <<
+/D [2621 0 R /XYZ 56.6929 540.5004 null]
>> endobj
-2098 0 obj <<
-/D [2091 0 R /XYZ 85.0394 493.0222 null]
+2628 0 obj <<
+/D [2621 0 R /XYZ 56.6929 473.2964 null]
>> endobj
-2099 0 obj <<
-/D [2091 0 R /XYZ 85.0394 308.5213 null]
+2629 0 obj <<
+/D [2621 0 R /XYZ 56.6929 411.9792 null]
>> endobj
-2090 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F53 1029 0 R /F55 1037 0 R >>
+2620 0 obj <<
+/Font << /F37 1018 0 R /F53 1303 0 R /F22 953 0 R /F21 930 0 R /F39 1151 0 R /F48 1228 0 R /F41 1208 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2103 0 obj <<
-/Length 2134
+2632 0 obj <<
+/Length 2068
/Filter /FlateDecode
>>
stream
-xÚ­Y_oÛ6ϧ0°e‹’"%±oišnÚ´k\`ÀºÅ–ca²”Yr2ûÝñHY²™fÅŠ5u<ïïwŠ˜pø'&:a‰‘f’Å4z2_ŸðÉ=ìý|"ÏÔ3M‡\¯g'çoãtb˜Id2™-²2ƳLLf‹?¢×LHvúçì×ó·:0K`\ÂÈõéæÍ%»üpó–8Gbeš²TÄƱ^|üxuóæú÷Ó©ÔÄŸN5çÑû‹›ÏïˆöñÔÈèâç«[vr5ë +xŒVü}òÇŸ|²
-`Jg&S¢w±!{.ôÈtçü«œB°XÁaä´¿ŠÝ¡3²„锧“á/yCg–…}1õM)–¦µIÆ&”‹Cõà-5ÖïÈm=WÀorè ž0e1>õs[@Æ$:êVnáüt«Z/¹~Þ—"5,N¾£/½À€/‡Š‰L²¼ræ¡ rMâ‹h¹9YԬ̟7õÎåýv“weS)Uªa!áxaÒçÇ)Ë Ò¾›c¼Àáb©Ù7;f½m;2ûΧDÝ<9OÜíð7‰ê|],ˆôTv«½Aúd*Ó˜¥™Á(
-f´–Vp ï <é(¯î› ¼¶võ‚m1·Q):÷ÜmÊúžÖ%j UÔXŽE±!ò²q \G!­ˆ°.Ú6¿w'>æU¹ð…ç®q'lçó¢X
-󜋧¾»~=³­8þ7»þps0rZjfæ_´Çƒê¢)ÚƒÄÜ>›)œ­UÕçu¨Dl. ·]Xa•…(Ntß>ª
-ƒÃO mWVe·;BD>ýk ^W.ÿ©˜g¾òàxiGáw¾Ý¸êª‘,
-ÃïSî#æ6åÂ
-ñp;#|’fÜjÀ33,r2H¬Ö†¥\'_ëòú¦“ î>n¾C—G§C‰öâi†Í i¶?øk]ž Ô˜¼m©ËBGzÃ?}ð¯:qÄÛâqŠEδ+ Öça¹w>5«ÂEisšª(XiÜ—XJç]]Ñ»ïn?¬Û–_¸æþgl`cŠ€ê¸— öl³$E¤3Móf˜M0²pÎ}}ì Î8KpH‡8
-¤=ŽÆ2Zté0\)Í‘ÉŒñêâóì—Ÿ^öâuÝ›ÚãÍí®…þÇEõZ
-¼r>nmiª´|UY¡ã?×å?Çâ~øÒŽ`¨éKÛ¡íþT­·vjTó†¡ ‘a`­§AKg½ŒoËêNŠ¯2ûAWÙ µ%j·¢º}V½¢×óšøö£øëŒ6}‘C>¨8Eî¿+èÑ' ÛÉ{çôC_†|칯ý8fÅqèšà=²ÿï¿ìÿF¢RˆB&Ãß¡ejïƒÄ+…V ™©.8¶«2 û¿’Zendstream
-endobj
-2102 0 obj <<
+xÚ­X[sÛ¶~ׯÐø¥ôœÅ•
+BÔ]eÕr³¿oóºÂ…ƒP?]Õ› }¨ÓŠ0Ù(~S¥Ë©3D˜Ú%‚ma¤e´Ün6§Ì€
+m±ÇźÂ¾º<{º¸|¦ÐQÜ*kÁÇžÊÁ.ã¨ÙÞß×›6Ká
+Ù‰*ól*ý¦‚‹#T¹Ë`æèºØ¢ë4í\ï:ø¸Ö“ÀÞ‡}laë+4±Ä•Î(æÕý¶%†ñXeãOò¥„q`LkW?äªnqïfß# o7Âu«6h¾mÑ!‚$°|ªŽAR&o“¼HúíÊ@™Tûëû.”&Ôƒ×Y`l»Âpþæìòú›óÀœ-¥Äg˜§&å}·KbGœy•5GÌY²\Ü׫¼r%C(Âö8ý»m'.,EL¬pÇð-Çó¯}‰ƒ½b@@xÇt¢GnI³U²-ÚE“mÞBIZ0üE½LŠuÝ´§*h÷‰Ë,(´³æÈ¿˜Üé¯^˜dÄjE„}ãá¶Ñšõø`Àÿok¨Óípþù½¹ õ;9)IÓMÖ4YSº GJ(ñ‡ýsK¼JñÐzp
+L»¼(P®‡[°UHN$"¶G´y¯Uà¥#ÿL¡¡àšPø1˜0äÂ6”…‰
+Ö ~6ÈG¢
+endobj
+2631 0 obj <<
/Type /Page
-/Contents 2103 0 R
-/Resources 2101 0 R
+/Contents 2632 0 R
+/Resources 2630 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2100 0 R
+/Parent 2597 0 R
>> endobj
-2104 0 obj <<
-/D [2102 0 R /XYZ 56.6929 794.5015 null]
+2633 0 obj <<
+/D [2631 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2105 0 obj <<
-/D [2102 0 R /XYZ 56.6929 605.5421 null]
+2634 0 obj <<
+/D [2631 0 R /XYZ 85.0394 627.5418 null]
>> endobj
-2106 0 obj <<
-/D [2102 0 R /XYZ 56.6929 504.7499 null]
+2630 0 obj <<
+/Font << /F37 1018 0 R /F53 1303 0 R /F22 953 0 R /F41 1208 0 R /F21 930 0 R /F48 1228 0 R >>
+/ProcSet [ /PDF /Text ]
>> endobj
-2107 0 obj <<
-/D [2102 0 R /XYZ 56.6929 441.2539 null]
+2637 0 obj <<
+/Length 2488
+/Filter /FlateDecode
+>>
+stream
+xÚ¥Y[oÛÆ~÷¯Ð£DÛ½_pžÜØÍqÑØ9¶sp€$2E[D%R)»î¯?³W‘ÒÊrQ×ËÑììÌì7ß,ÉÃ?2ICÍHŽ&bT¬Îðè Þ}:#Af…¦}©ŸïÏ~ú…©‘AFR9ºìéÒkMF÷óo㟑h*ðøöúâãôãÍõ/Ÿ.¯'Sb¸âãó/_.¯/®þ7™RA$1>¿þzþ›Ÿû21t|þéònòãþ׳ËûdVßt‚™µé³o?ðh;øõ #f´½ÀcèhuÆC‚3g–gwgÿI
+{oÝO³® Q&iÆ”ŒAF:p†0H2Êœ3®Ï?_ú]Ý]ÞN`ûÿ…‡ûÛºåêÓ×Ûs»Ûû«›k»[ÐI{þÅ#E˜3í”Ý/ÊÉ”9®g+7ã¶Ü<—?»Ú¶=„·ESǘ>m7¢ÇåÜ¿íÿœE¹î¼ä¦ž~~S—EW5uÄê¹—‰¿óÊŠæ©®þ
+u‹°âïå«Ÿi×eQÙÅãªUm7h·ä}æ“ÅþÐ훓޾! “„­Œµ YÓ Q4HÚõ–åXšñ¶­ê'»6‹æ1»¹Î™ß,[?Óv³®\•uçÿôV˜ù!tXÄ:~Ôƒ”J¢Üܘñ]YîÙÑö<ÌÆM½{Yü¥:ݬù‡‹O9HQª¢©ûEo‹6ñ`‹îéŒqgðêúÂŒœÏWU]µÝfÖ5?u[>–>îu~öyVogK?~Œró²›UËëBÏb ÄšuwNÆùow7§“ßfÁw,°†ÿÈÿK;7µ‘x*ëýw+ØqÑÌK;Oü¼[ƒ™¾o•BBÁØûöŸyâp DjD¥”)2^™2.f€Mÿ÷Ííi·\Õ]¹©ËÛ»×BÝ„k6]µ]íÖå°‚ŒÑàq#uBm€hŒ‡^g–q¸0Í¢OÞ0”&*Å+iqö|‡ÌÜÅÍ^ØH•à媉ÙÙ4Ë÷$Ñkݬ۪Ý/ ÎŒ–lÄÁW\é²0
+Àþ#°!œ´Óà@p6#æG¡ÃKpè·éìG=øMÁº½4kNx>i-²B'HsF‚\ÒYdt‚“´b§ò±Zþ •‹4ú=£\ÌÆwÊë”ïQ¾>iïò6£2@{Ìöõm2ú¦Ì@m§œ±pÕ¬Yñż“úö¤¹³ù|S¶íû=ÐTY,6MÓÍ«MÎN ?"¥KRº=©t t!çV(µS—)B)éáỸ¼ûx{õ¥G^H¨2xpˆ’!ŠiL©€¥E2mz<&"Lúb$l:4p†6´G$2KS€AÅz%›ªñUVž…Õ,¥²OpáÜfaéY²ñ¹¬+_fíôÒ3Øû~ié“}¾lªnêpu
+€ˆ˜ær˜£Ž¶P#ð‡ÀqÖ÷#Å©#¯Ùq:jD ÆÒ¾¯jíº©çÖ„Œ;ÁSTsš‰0ƒ¸T1ííjmiBèDrÔ ðJÔ“ˆLëmÎ’5 'Îhú²&)°¥'¯^ëÌE>>ÜÖKÃÍ0>ç»È._'@ÏÆ–rp°Ç†žó4\ø¤‰ÍD·aî¥ê~6…wè¡Ñ\«¦³œ[00B oÖáPpÏÑ­îÖ1˜Ø®ýÄ,ã*¥‘Á„ô3)aã¾Ç²½zŸHVÿsS̓ ‹°íº,Ôç‡GÌ
+e–œ,*({ƒ%/
+à”’’‘§ˆ“|Gê
+ìkÓ/
+¨Wu¹ôoÒ,œ± Cøà˜E΄ÃõŒ\.›—|•g8#7âd$61\®ì˶µ]² >jƨ{™Wås
+ÈHtŒÜ¬eL½MnûRÇÉm’r.·lbèrmRÀ{—l}Ó¤g„½m[’Ê7Œ20IBÕк»D·lºs> À õT`Ô<‚>¨ævÎlA&ª®µÔ€9~öƒìdŸÝKYI´ºdƒ Ô˜Sñ/ê”Ùc :uF†¼fÇHì7…vBõÑhK8º7c½“9é ãâ\äâl¿×‘ÌÍç ÎÐŒ) ¼ä «’ÌYÃ3Ëúv} µ_£ò8ýS \6û:ѱÔì÷*œãﯱÛM-©»¥èÑ¢Ý/ÓuÙðÔkh¬ÞÑöp «þWÜgZhsí=UƵ85ÆÿøîîS5·wiúHC
+W£¬áDêÃ\ {mÿ?»³· endstream
+endobj
+2636 0 obj <<
+/Type /Page
+/Contents 2637 0 R
+/Resources 2635 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2647 0 R
>> endobj
-698 0 obj <<
-/D [2102 0 R /XYZ 56.6929 401.9804 null]
+2638 0 obj <<
+/D [2636 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2108 0 obj <<
-/D [2102 0 R /XYZ 56.6929 368.8669 null]
+2639 0 obj <<
+/D [2636 0 R /XYZ 56.6929 752.3759 null]
>> endobj
-2109 0 obj <<
-/D [2102 0 R /XYZ 56.6929 333.1161 null]
+2640 0 obj <<
+/D [2636 0 R /XYZ 56.6929 668.0781 null]
>> endobj
-2110 0 obj <<
-/D [2102 0 R /XYZ 56.6929 266.6983 null]
+2641 0 obj <<
+/D [2636 0 R /XYZ 56.6929 607.6906 null]
>> endobj
-2111 0 obj <<
-/D [2102 0 R /XYZ 56.6929 206.1673 null]
+898 0 obj <<
+/D [2636 0 R /XYZ 56.6929 570.577 null]
>> endobj
-2101 0 obj <<
-/Font << /F37 802 0 R /F53 1029 0 R /F21 714 0 R /F55 1037 0 R /F22 737 0 R /F41 939 0 R /F39 899 0 R /F48 953 0 R >>
+2642 0 obj <<
+/D [2636 0 R /XYZ 56.6929 534.8112 null]
+>> endobj
+2643 0 obj <<
+/D [2636 0 R /XYZ 56.6929 503.6098 null]
+>> endobj
+2644 0 obj <<
+/D [2636 0 R /XYZ 56.6929 440.3004 null]
+>> endobj
+2645 0 obj <<
+/D [2636 0 R /XYZ 56.6929 370.9227 null]
+>> endobj
+2646 0 obj <<
+/D [2636 0 R /XYZ 56.6929 274.6697 null]
+>> endobj
+2635 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F39 1151 0 R /F53 1303 0 R /F55 1311 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2114 0 obj <<
-/Length 2593
+2650 0 obj <<
+/Length 2259
/Filter /FlateDecode
>>
stream
-xÚ¥]sÛ6òÝ¿B“—ÊsŠo‚—郓8©ÓÆqßM¦½>ÐeñB‘®HYãtúßo P¤LÛÉÜèÀØ]ì÷BbÂá'&Î0®R=IRÍ f2_ñÉ5¬½=aÏ,nšõw½¼<úþJ&)K­´“Ëe—cÜ91¹\ü>=¹¸8=}öéx& Ÿ¾dÇ3ÃùôýÉù¿N~&ØÅq*§'oO?ÂTêÄÂ&!Ùñ—ï¾cT¿JS–hƒl!æ_Ï_¿b¯>œ¿Á­G§—¿ý; ®Ù?~ÿƒOpµwGœ©Ô™É&œ‰4•“õ‘6Š­T„”G~éöVýÑ1å˜q2’”cB2)³J*•ËUN÷Õ¢·UÀu••áºõM[ÔUCû(µf)—q_Ófm¾Î«öx¦x2×U›pÎÏþù¼ÍÃJ™m›¼h'bÁjÆ5÷"_fÛ²5ùæ6ߌ°â,j(²BˆZ8XÖeYïòÍ®îèۮ¶*[{>&3% Óšƒh…`©¤^
-Ø'Å4[,6ÇÂMó¦!@½ ôñxüSÏn¢§h~RÁe‹plU7-vEYÒè*œÞam•W/ «ï“ðøý8"¾.nã™,€²8÷œ_oƒ’
-' Šq¤7Ez¾[óÕg±
-uR´ÖNÏq W©GˆË N¨=íb1B]AÜ0iôM›No¼þëÛliáo
-Àº¢/IÈz}{м^¯³jAನòç0LA¢U8;Ê¡ K¸IžåZêp³ô¼dŠŠ@M×Y;_a‚Ž˜³Â M¶¨®Çb
-dÙiä¡H¢ <'ƒ\] Ròü9í˜&d\ŽGgvÁ™]çÌ°ÖÖɶ k°·9 &ɶD‡†ˆñ] ”f$zØIA(HÁ$̺ä b57µ)Ì&É®iæ}àš7õ¦‘L¢Y’Ü÷MnCŒ5ƒkCŒ51ÆÚ©ÇëGmˆf0„<Qåó¯éˆ7JœÓQ®»®Û€*¸9Œ‚È|ŒõÂÊ2ÍÝн¼Oñ|JB®Ñ*¨n/Áñ w’"ጦs/ò-X‰;º,| @{ßâ{ß’rÚÁàT]Øý*V÷Šr½d¸tŠÀcF+Þ¹Æý3 ÞG.ù¤'¨GÆ< *±àI ïyÆ(²‘¤s%yW‚op¥$¸|ÉxÀ˜|ìÀì<U]×Uõv3Ïg˜Ò1ß¿PÊ2ýu3" g1 Ä2NdvkÇèÉ„5ÃpÒ‘`Õ!]ÉDMç˜È†A
-ÏJ Ü=ák…°wL˜Š«Û'S´Ý©èDZoÆPb-ÜÙ÷Wå ®˜3]P†ûÊñ êF¤&C:!'Q ¤gyP9{M™˜jqä;Þd—w¸
-ûBveÙp¤Ÿ]pËþ yäÌΡ—Òòñ^C2ÎSwÿ™Bs4ÍkÿHã]Ñ®°ÌçÞLBáòÎ'P²À&¦„RðÀªtKÈÝi–8Gq ØðÑí®Žm"K¬>0èørr_Xl9Í2+¯ë Üf=æ䜅Š¶Ók}1¿¨Š”’Ó¼šoîb {¤~ºŒÆ<x< ”L®ëŸz<€¾ßä«9åË™X×éé|»!˨ÚòŽëŠFrúãû“W³÷¯ ÉI¦ª/%‡²·õ.ž/¼o§áFê¤Û±ïYŠ= B3š6ùœøh Ü…DwµBÿ­ BÅ
-º ÁT“ð»—‚×=7Bë5£~ŸÓ”ªÍd_A}.uLò®+\¯½­åc¾/™t<Ñ=ñ:YÙ?Wõ®
-ì5c49Ø…ÒÕºx„¨bBuDŸÁ¸Ágë¾Û’èl¨º–!T¥}ÑÁz¶wfo{=¬/éŠkZ‰—òoJ7Û–\LZÃL—°—¥N»WòEM¥>ŠµD»Y7¢Ä‚#2Q\MçÛ6>;;ÆS)^²‚Ûf·YQfÆ0°Îª‘›;(¨ÖMˆóü QŸ~:yñóiØŒé6âðæ¡Ùú&èž'p‚ÏÍÁæj±½ø:–ýë1”H©£?"Ù‘„„Åöê2Æ࿆™å|ú—LD=Þ\‡BQHØ_Öó¬Ä.íÅXí¿;Cpàñ¾0:Ý!%²È¿;d5¾öºTÏfGö®EWž@ð4i9JÚÝ# qºíÏ‘µ1:ê(iß|c7¤GFõ‚†»=K¶/'oÑ+A4ª|µÎæ³õ¼k†0QäÄ)Ÿ>³oÞ/ÿ«Õ‡æ‹.ﮤþp–Ëâíé—´\Š²|÷áå—gß®Žé Õo¹}ørp¯¶g¿ªÏÜ…}ùÓ.ým÷iw®þýÛOÛ_~ø¸û\ ÿ<ù×wÌýßÿQîÿ¤Õ SÎÉñ¿!0¥R™Âû ™²Þý›yŸ÷ÿf¹Öendstream
-endobj
-2113 0 obj <<
+xÚ¥Y[oã¶~ϯð£Ô\ÞE>f»éž»ÙœM(ÐöA±äXXYr%yƒô×wx“%™¶{p ¢©19œù曚,0ü‘…3Í©æH`"«í^¼À»WÄË,ƒÐr,õþéêÝ/,]h¤%•‹§õh-…°Rdñ”ÿžÜ<<ÜÞ¸ûízINÞ£ë¥À8ù|sÿíæ“›{¸Ö4¹ùxûx½$Z
+B$5r'>Ü?.þrÿËÇÛûë?Ÿ~½º}Ô«N03:ýuõûŸx‘à ~½Âˆi%¯ð#¢5]l¯¸`HpÆÂLuõxõßaÁÑ[ûÕ˜)¸PHP.KN ‹Û #,àüË”c”*u°%1{)c¯åf~N8çœ,Æ‹m„"[ÒÑ–Z#NÅlˇ¶¬ûÎ9#snÓ´½î·Û¬}sšµ{ö›ÂOìú²©Ã—ëÜÚk¢’—ý¶îs®™(׈RšÂŒ"m¯–«¦^¿µ—+/Á/”Q/ŒŽðà­žbøŠÒò‚kFRg\¤¬k¾;¥„I‚”Ì+õ½x«³m1W0…Ò4Uçu¤"Êí@8@Oh2ÕîqW¬Ê?0¦…µ¸ >’F)7°ªÙ‘óãHƘ޲=LÖ}¹ÊŒg+BÀæKFUò´)ýÛ}׻ѳ_(sYUæn˜7Û¬¬XÇ-–Œ!E˜96A&ìí!ž®òbí+AØÍž]$)Š‹1tŒšÇ°á)RËK°‘2E”‰ °K†Í ea³»›‰¶9f(Fæ|gõ
+B½&ˆ¡l gŠMôGƒ¬ˆyÌL‹dµÉ꺨Ü«©½n
+åE,®1F0 Ç3^Ï#žai–©ªìú¢öª¬›6¨›¯<ÉuÖv×fÙ–0àuÌù‘]Ád|ØreqgQÉ1E˜>…åö î; &
+|¬N¥ÓL#©3`
+RLmLIņH
+ñ³Ì"^ÇÑT×»6Î/Ù¸§%³õ›û`øR¿”ÎY«¾iý›³ˆ‡N.#^§$4v¯eU¹¥Ûk•ì½V`y‹ã¦7,}¸Lnü«,_ú–‚0ˆbSºLؾ4gs¬Ì >voã„É&œf; M•ÒQh x{aHš áꕇe]JaÉk[ö×@×Eí>;cUP—üð. El¬˜D?33¼ì!Gû,)ý¶„õg»®›½¥3õvÈ„
+&u¡×KŽàAÊB}±×‚4מêµÎê5ôZÇzE{­‰b>v­»lìJ~*v9JSAÎÆ.X™=ÝJ<éŠþ
+$ðЗî^W!ÀkˆA,ɪ.œrÈϹ'
+endobj
+2649 0 obj <<
/Type /Page
-/Contents 2114 0 R
-/Resources 2112 0 R
+/Contents 2650 0 R
+/Resources 2648 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2100 0 R
+/Parent 2647 0 R
>> endobj
-2115 0 obj <<
-/D [2113 0 R /XYZ 85.0394 794.5015 null]
+2651 0 obj <<
+/D [2649 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2116 0 obj <<
-/D [2113 0 R /XYZ 85.0394 420.6717 null]
+2652 0 obj <<
+/D [2649 0 R /XYZ 85.0394 390.6346 null]
>> endobj
-2112 0 obj <<
-/Font << /F37 802 0 R /F53 1029 0 R /F22 737 0 R /F41 939 0 R /F21 714 0 R >>
+2653 0 obj <<
+/D [2649 0 R /XYZ 85.0394 257.7108 null]
+>> endobj
+2654 0 obj <<
+/D [2649 0 R /XYZ 85.0394 193.2733 null]
+>> endobj
+902 0 obj <<
+/D [2649 0 R /XYZ 85.0394 153.3455 null]
+>> endobj
+2655 0 obj <<
+/D [2649 0 R /XYZ 85.0394 116.3439 null]
+>> endobj
+2656 0 obj <<
+/D [2649 0 R /XYZ 85.0394 83.9066 null]
+>> endobj
+2648 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F55 1311 0 R /F41 1208 0 R /F48 1228 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2119 0 obj <<
-/Length 2226
+2659 0 obj <<
+/Length 3141
/Filter /FlateDecode
>>
stream
-xÚ¥Y_sÛ6÷§Ðô¥ôL„ÿàú¤ÚNêNí¤¶rÓ™$´[œP¤*Rvss÷Ýo)R¢-g:z ¸\,‹ÝßîBtÃNdBÃÌDAdLåd±:‰'ðíÝ <Ó–iÚçúe~òÓ[®&†˜„%“ù}O–&±Öt2Ï>E¿ÊÉ)ˆˆ£›ëó³éÙûë·ï.®O§Ô%¢Ù‡×ç—žN™Œ8ã8ºš]œýŽ´§†E³w·§_æ¿\Ì;µúªÓ˜;þ:ùô%žd°ƒßNb–“'x‰ 5†MV'Br"ç-¥8¹=ù£Øû꧎š‚Æ„ñ„ØBО- #Rj1QÒ„3îmñ¿ŸÝ~zËXsÊ%щ”0ˆ‰H˜ô¬—%ì^ÄQ³´0à&JïªG‹4ûwºZöM6XVE©
-ŒD:a
-äƒPÈÔÊ´0jßÓ!ã².úŒÈ1„KÕò8ÌÙTE=fWpÐ;0vZ£·ÝW›በPi´¡æÀ:{îØFX’´¬h­ÖÙ1ëÀh½ÉIBÐp¦¡úRô;ƒf ß5 ‘Z« ž;
-Yùßððﮎ½|÷ñfæ¬9¿|=ÄL¥e0¼÷wš„¤Ì©ìÐÓQ±Šp£»ðu—úý døÕ‡<ÓÅ®äÄäᨤ¡R¨[™!O;…-ª‡2ÿOP#x<;J½¶‹Ü-Þ®š—c92”1û!“Ãó,Nª°ˆ3ÓfNy«Çèsê»ô”^¥â^órTˆL©_dP­Cæk5¤ÆD·ÖîéQ÷,Ì}Úk?á%Š u@¦"oað2¬CzÅX¯ðÀ´éš¦Ëës|̲U^æuí¢Á‘nì½Ås/aÚUZnÓbNXÍX¨¨
-,aŽ„ÆíEˆŒÙï·ï;¿ó×h×¼ Ù¹—÷¿µAê[ ¤û5¸éÛV¹\ÆZPüg–8ÜM´Ãܤs‡«L¹€þ Êè¡uf翾¿yÉ,"ôyÝ”-¸Þ~«á¨CÆ8ƒÊ)ß®vë
-(‚’ö4ƒºBʮ͆ž:ŽãƒÊÂœ…>ÊcšCŸqÅ ‘ŒÔ'^ŸÏÐõìÎ GX²í 6(Î;«ªx}+«u×û½=‡˜Ñ ‡–0jä‘^³aÒåÛñFÝuÂ.”z"ûôö¡ã:Ü»KŸ¦é—vt‡û‚•{ž
-˸ƒ<0KíÀõ ue{ xÌňÌö^ yŸß!rÙ¾Ž‡rZÉ®òáe篾>ª¯/úå1€ó}y›yЛrðGÁ†pˆ%ý3¶@üÖûâë£ê¦Y¶±uýz 4GE.–›ªj²|¬îƒ>ŒÊÎ]:¡Û£B¡Ã“Ç
-佺’v¤c…:^ñ^Öf*ºlÂÊiXÍßÈhÓ6É0JÃÒi§ã£-sÌ´Ž\8l}ÃLßójìf `"áZì¥lìmMòLIÀ!ü=ãkê#%ºb¹»õ1¡¬cF†:À¸Êoƒ‰­^W¥oâFÌ –bÒ˜ãÅ7D$]eÖµFl¯5Ò”²[,à«Ð±®È$ãõZg4{eS¤X'þ¤.AÝÐ —2Ø»AœíN¶Ø]ê ÐÇ_3‰à4B¢Ó
+xÚ½ZÝoÛ8Ï_áGX³ü%Þ=u·i‘ÅnÚÝä€Ú>(– kK®%7›Åþñ7Ã!eI¦8©(j4g~ó!‹‡b–f¬´³Ôj–p‘Ì–› >{„g.„§Y¢ÅêÇ»‹7ïU:³Ìifw^ãY&fwÅçùL¤ìXðù»w7·‹Ÿ>Þ¼ÿpus¹6Iäüí§OW7ï®ÿ}¹ b ä|þëÛ›½ý…æ>]Z ûpu{ùõîç‹«»^¬¡è‚+”éÛÅç¯|VÀ~¾àLÙ,™=Á gÂZ9Û\èD±D+fÖ·¿õ OÝ«QUΤ22¢ )fB0ÜÕH‰eFIå”qû\7Û¶j§[Q‚¥™Q³TiÆ…6±¥(Z& Ü ¹X*„±,œXZÄŽ(P¡TEQ·‹eS?<–õå€þ?/rñÍ{Xïð²à‚‘YX_Ë×Í®êV"¯£˜Õ©ñ”_×U?ú#Âß$,M”ö/ýQ>×ù¦Œ0ׂeZ‰)ó]„¥JXf’Ä“îòºh6Õ:ÆÎ)M“lʵ}‘ë )¥eYØýMìE¸-”IØÙ9Î_Me šEkŸˆù-ŒPš¯ôÞØ :c™0àÅ
+Œ á‰cðîêö§ß¯?Ý]¼é_:,Ægà‚pæiÄPˆZŽÏO؉4å.ïÊÜ8Óó/
+O•îš ömIîŸ#‘±$ÕÁ’êv¿-€idu­Y–fA1pÒ1n–ÌÿppE„“âÌZ–HÒB̯;·­6Ûuõ…sI;SsPÞ>îa·USYó@׸Zâ* ËÔdpZö¬¬E¸«×]U?Ò}NRÞÃî`Í·»K‘Í›ïUÑÓv«2²sÉ%À‡¯Ðc¸â/ê1Ó:ê‘¡]DØâ¨, NÝ>×]þg4ïhôT­×^%]ë²,ÊÂÓ5¤=%ç35Ñ™ĉªûÁêåzïõ·yM×òÏN.¦! Ø„2’‘4³Ø6ëjù7óuÛñ¦¬;FR
++™Ð°áX®²„û×` J¦xŽJš9€P^Õ4åÐÃÍBXp3í¶\’ô ñ¤x²n°l6gøt]Õ%ì\iàÐÑé)ïý %O^™™^€ÔÙ,Îôë.èÍ÷ÈÇ'@’€#8Öp¥÷39oOi<3 ¬7}•ý¤LJ¥Fö.™òlþ!ôGûCìl!f ^GºÁ«°ú&²¸ˆÌ6 ýS³_û½ÕÐ]î-4Õ þ’±~Èk [¾^;£6Ùü‹”ÚIs)
+r+ð_%/c»bÆôØ^um¹~ð›Îë°û€çˆ­~Ñœ.둆˜ÍÒÈpæ7%<A~;0ˆâ*µS0v¯,Ö±S°¹Tô!阥aþe1;"˜ä:,¸ƒ 7õšü{¡á xªÕØŽ{LÎøüiUº@'(®óù¦éµwå:¿oÈ=ð6!- é½oûŠÅ?À¥Ò` HWÄÖKÄ8™eóê!²y%“Ff¯ËtŸN ĸµî½ÀÞÔaô@vCwÁÏ h›;Œè‡äß‚e·Ï-DËÅxH´{ó£Ë¿Ž ŸÓk8/n!5=›ø©B=rœø÷T¸nŸå'#Ä„Z¤‡¼Q’?N Ê3žž—®§Šˆ''!p,Þmñ˜TÀ¤¢ù†®äv*8âð»Ûë8Jh vÆÍü-–—ßó
+,víi—«¦Z†5s:V´J®ç«M¾\lŠQ ºõ>£XäÄ$ÚU.|VâHáÞãúp&1“•é»ã'P% Ü‚ÏïVÞÌŠò!߯;Ÿû´G¼ÙI³’’¥D>oVª3f¨œY­¦K‚¿p›¾°d Š,94•T
+l¶JíDãtî{Líü3JD§P®-$(2}%òJ–¨d„ã±£QDj ußÙ£R>šžÊÍ1‡zÚ&ê¸îù;àÝê¼l=UD¸‘¿‹„iZI7rx%´Ï$aàB¬IÈVUX#
+ÈH”ïa²îª¥7ƒwû„+rœïÝoª6Rq+¨v„Õ£ØêSái”†Â1}¶¸"
+>T,¨;ªXˆ©±çœÔë Ü̽,9±nËmî3q˜/×>JkÈŠEbÇ©èC³^7O®¤I\ÏÁ]Ij Ýžfœ IH5¸ÝÔÎKöÈ~ˆµixŠ}B;ÙÜ0Åg±CP¼Ö„üä.¬Iöoÿ0ÚìÛÎoTeÌ*51¯Uþ½œ „ÅMÞaУå÷|]yä Õ)Žq9œ
++qŒ„ÿM^…E ø‚#0Â=á:ŒpÎÙ$L´¥'¢oƒ²#|ÀçýW
+Ò
+þ¡BÒúãõÍ;zÓzÁŠ d˜m·Ã‘¦~/c±“M  S¿æõ>}l‚4’>cNv)Cq0üµT4x¯ÆÿùGY‡Ÿé”)¨Ýâð#SÀ c/
+.R~ŒÄþç[Dzÿ!ºãendstream
+endobj
+2658 0 obj <<
+/Type /Page
+/Contents 2659 0 R
+/Resources 2657 0 R
+/MediaBox [0 0 595.2756 841.8898]
+/Parent 2647 0 R
+>> endobj
+2660 0 obj <<
+/D [2658 0 R /XYZ 56.6929 794.5015 null]
+>> endobj
+2661 0 obj <<
+/D [2658 0 R /XYZ 56.6929 749.2278 null]
+>> endobj
+2662 0 obj <<
+/D [2658 0 R /XYZ 56.6929 677.9694 null]
+>> endobj
+2663 0 obj <<
+/D [2658 0 R /XYZ 56.6929 495.229 null]
+>> endobj
+2664 0 obj <<
+/D [2658 0 R /XYZ 56.6929 83.499 null]
+>> endobj
+2657 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F41 1208 0 R /F53 1303 0 R /F22 953 0 R /F55 1311 0 R /F39 1151 0 R >>
+/ProcSet [ /PDF /Text ]
+>> endobj
+2667 0 obj <<
+/Length 971
+/Filter /FlateDecode
+>>
+stream
+xÚ½VMoã6½ûWèhË‘"ÎÚÝz±q\Û Èæ µäD€Ey-9Aúë;IYr”EŠÂIÃÇáðÍã3I€áGÉf*
+b!Ž vÅ0öyD&ô °‹ºÙŽ~ýÅBJPl÷\a)I°MïÇÓÕj¾œ-þœ„”ãñ š„ãñítùmúÕÆVEÇÓÏó |G
endobj
-2118 0 obj <<
+2666 0 obj <<
/Type /Page
-/Contents 2119 0 R
-/Resources 2117 0 R
+/Contents 2667 0 R
+/Resources 2665 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2100 0 R
+/Parent 2647 0 R
>> endobj
-2120 0 obj <<
-/D [2118 0 R /XYZ 56.6929 794.5015 null]
+2668 0 obj <<
+/D [2666 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2121 0 obj <<
-/D [2118 0 R /XYZ 56.6929 513.8248 null]
+2669 0 obj <<
+/D [2666 0 R /XYZ 85.0394 751.5568 null]
>> endobj
-2122 0 obj <<
-/D [2118 0 R /XYZ 56.6929 427.0967 null]
+906 0 obj <<
+/D [2666 0 R /XYZ 85.0394 708.6012 null]
>> endobj
-2123 0 obj <<
-/D [2118 0 R /XYZ 56.6929 364.279 null]
+2670 0 obj <<
+/D [2666 0 R /XYZ 85.0394 670.3846 null]
>> endobj
-702 0 obj <<
-/D [2118 0 R /XYZ 56.6929 325.4767 null]
+2671 0 obj <<
+/D [2666 0 R /XYZ 85.0394 636.5029 null]
>> endobj
-2124 0 obj <<
-/D [2118 0 R /XYZ 56.6929 288.9693 null]
+2672 0 obj <<
+/D [2666 0 R /XYZ 85.0394 564.786 null]
>> endobj
-2125 0 obj <<
-/D [2118 0 R /XYZ 56.6929 257.0263 null]
+2673 0 obj <<
+/D [2666 0 R /XYZ 85.0394 498.9559 null]
>> endobj
-2126 0 obj <<
-/D [2118 0 R /XYZ 56.6929 191.2867 null]
+2674 0 obj <<
+/D [2666 0 R /XYZ 85.0394 418.2058 null]
>> endobj
-2127 0 obj <<
-/D [2118 0 R /XYZ 56.6929 119.4786 null]
+2675 0 obj <<
+/D [2666 0 R /XYZ 85.0394 349.4108 null]
>> endobj
-2117 0 obj <<
-/Font << /F37 802 0 R /F41 939 0 R /F22 737 0 R /F21 714 0 R /F48 953 0 R /F39 899 0 R /F53 1029 0 R >>
+910 0 obj <<
+/D [2666 0 R /XYZ 85.0394 306.4553 null]
+>> endobj
+2676 0 obj <<
+/D [2666 0 R /XYZ 85.0394 268.1239 null]
+>> endobj
+2677 0 obj <<
+/D [2666 0 R /XYZ 85.0394 234.3569 null]
+>> endobj
+2678 0 obj <<
+/D [2666 0 R /XYZ 85.0394 162.6401 null]
+>> endobj
+2679 0 obj <<
+/D [2666 0 R /XYZ 85.0394 96.81 null]
+>> endobj
+2665 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F22 953 0 R /F41 1208 0 R /F53 1303 0 R /F39 1151 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2130 0 obj <<
-/Length 3036
+2682 0 obj <<
+/Length 2018
/Filter /FlateDecode
>>
stream
-xÚ¥Z[Û¶~ß_áG/pÌð.ç)iÒ E»ÙÓlm´– ±%×’³ÝþúÎð"KZÊNqàQÒˆÎ|s¥Ù‚Â-Œ"TX¹È¬$Š2µXïoèâ3¼{ÃÍ*­†Ton^}/²…%Vs½xØ æ2„ÃÅoË×÷÷ïîÞ~øõvÅ]¾!·+Eéò§×w¿¼þÑ?»¿µ|ùúý»O·+fe&ˆ ¤ÓtùóÝÛïVß}¼ûþý»»Û?~¸y÷г5dQ<ýyóÛtQÀ~¸¡DX£OpC ³–/ö7R ¢¤ñÉîæÓÍÿú oݧ)Q(aˆ2<KÈ‚³cÄ*ÅGÂP–hÁ…ÆÇû‡ï>½Ø %T¼2Îà#˜<©„@´RÅ…JˆT¸î*Ÿ.iÂðËKF¢Ä’|°$¨[0«ÆK¾m@»F/óS×ìó®Z#^5'&“Ã/Žu‰†³s`‚sˆÖMý;¥üóés65ÀD2³|ØV­_n}¼…û2ïÊð ÷ühWúéå&‘™æ&È—ò9Áˆ¢DgTªNMÆ
-¦Î÷e‘˜IpbÏâkÂ6Û.?v§€ˆƒ zئð²äzˆQ‚T e€}&ÍDÊiè0öL,®8•Ë¢Ä»Ú¡•*‡V÷t“Ÿv¿Y7û=îݬ·y]—;ÿ¦
-FvË– >°3gþ12ã w»æ©ª?'ä'˜"FZuUŠÚ¨®®9svªqÉ2ÈD+à™Š2ñ!à©Jc€ƒü¤¼¦9A¤‘b 9Œݶôƒ]³Îw~¸mÚÎÜ‚nT7þº9á“£¿yáCïJÎ 8vPµÜ³þó©®Ór“àëTï–Pl+4ÉÏ¥ã0 .w²™LLdLN+­'÷Ç•^Zÿ vLj¥®zL*ÀüÊ‚ K?ÿ©E»wK„µ gºÍaUÞ½)vùºÜ¦Zÿáƹ©¯ÙÒxÑq.!àë‰)ÌØ«%BeQŸé 0M”Ͳ@óŸ9¥¢-|v–ƒˆh&È(ÿªÚuçÀ3õ<Oýv\e½\ ª3Á-ðjdËB<Ëñ1„>lp]ëL2š}ã¥ë–»ü±9¢ý¸Û 2ýCpµçQçg˜•øYá_<>§ìKZ’Y!f jç!j²VÔóüç©òƒu¢y„ìã¯|ØE/
-yeÉH”XrTÆZ"¹š,y¬BD]G©o›c0„ö©ù1( ÙL2¯²øq‘;WùùÔgVNŸéðÍ9Ͼ1dQH¼¿¦™Ib3qÅ©æUÓS9Õ|ùŒ¡eÖ_äíìƒ_2—ôÁ#îF>sÙ #J$8ÖÜÈëq@ã3MÝrœóâÃvhEÀ‹ýÉ×#ºO½sùšïªÂ‹fŸWõ™rÁ?D\M}q¢h…rÍÈa™°ºdÑú*lð‘Q{6ª °‰T6‡«°9 µM1Ã)Áý]ä+%ø!†+¬ð'Œ£¶ hÀA_Ž ;(ÇñãÔž°ÖtY~®)¤p\‹ku/ÀWôuÒj™²¬¸¬Û³‹¯ƒ“Av6¾’Û§ê.A £}¹=W:R"ûEÑ™4±/r¤ó8ÆÆ«™¨oLl`7D]ÓjL=•Ó1&K´½%€âš}27P$¬1—¹ë©ì0¥ –ÊÆü1¥$ú¡Ô²mNNoëÒ?vÙ \=·ž¦È»Ü?õÚ‡A¨]‰‹$¡8-x©æXý;¤š W…â»@¤ 8Žn-QBN<Nû ¨ÛûR¯hœïÔ ÊïÎ?:x´}­ŠÒ?È“-QC„õÇ«¢üú*ì+Ä€T÷VW[¬Xv‚Ë¿ëׇ)ªué*аiÇ_C J_:—W¿r]¶­ß53£Å¤_8¸ÌÇƇë஫úpêHb—OÎíL· ð™®Ç„ÌúFîl`zBô
-Ò”GíŒÊùˆBLh„èåYøT-xÚ‰9; ¡]–©©^pGð¤ªyá{ÙÆ´ÇéÇi‚øRÃG-’U׫Ðç)ÕmåÒ@}9LäQEº/™îûuáÚ¢çFÉD‡ðÎé0ôk¬jÚˆ êCCýØc¹¸÷y‡Æе^Ëw‡TZ¤r­½ZêäEq pN•:YëK—¬%Ko㔊Gýs¶üpï k.¶âRTdï¨dÙõn03FO£"Îî{Q°þ¹_Îé _Îé8^ºoæã%dE„[ñïâ¥w¥\&õ7&oÓvvsxÌ×_B©0’ +¸¡Ø„›Å"×@aap‹Cªy,öT‹]2¸Böu¶Þ›¦ gR#0B–i5¤â™ë©Üc+'V‚|Gì…ÊÛÚXy[;WyCº'ŒºÒ®ã™–Óʧlüõ\y[ßÙµfÐkŽáÍEÄCŽ@™d×o3Æû^än秭N7É;7®ý¶’àæ_‡Wy±
-%(-3uE…{ó^Y€}ž‡SœE8Žvà6MömG¦Rô昇i}H˧c…WëHýÖò’¯Â!dÄÙ
-ú‰˜áeÛy·/–U¸Â’0ÿdÕMsrî=Ÿ#!@yr‚Ñ›åPÀ©öo†‡™W}%ÖŠ«µgÜǵh2¤º`Á‘ÊAýtµÖ‚0wœ«µ.òÕ×Z/ùJÖZ#Æ‚í:u9ÛÕr¾k–eŠ]éšYÎìÔv{(Ißiàvƒæ©vé7“õÇɬà/RûmÈèOO|a…þè$ÀÖ‡Mb£™"Šöuyô½ãv¼òá9 LžïÚ¸ËÁ)8›ÅŸNÒ½¦Þ=ObÐ9{¤ËjzÞz¶„a7« ­±m<¨bk+Š¶?®+H¿ÝÁ¿eVÊ]ª5VÄb„GæÞýúú§ûß}Jìžb˜ Ï]xÅÿ5±ºkžR'¶7…½þ—BÙèìtœÎFBÎqŠGÑ“s¼p‚9<’fx¬£!­¡ÜŒÇvšÒ4àéø«( A5hM8Ìý¥íé¦.!F¸ž?O2rŠk·‚ë‰P¬8Ž!k94–'OÏu.qþWOwlvmÊkj3./ÿ†LŠ†ô_0ôùŒ«íÀCyî‚ÄÃf¼2Ñ4ð®ªcå S»InN³‹¸
-+³ötfþ6'‘éf+í-óÿþKÝù¯ƒÝ cx:.*~,2…{`‚MYïÿ|÷’÷
-endobj
-2129 0 obj <<
+xÚ¥XÝ—·ç¯à­pOpý1Ÿd—$´Íf»°÷ôž4³ƒ9e†ú×W²ìa`g7͹‡‡‘eÙ’eé'Ñçðý0bQ*Ó~œ,ä"ìçÛï¯`î}O8™‘µ¥ÞÎ{?¾Sq?ei$£þ|ÙÚ+a<ID¾ø<xË$gCØ‚¦³›Ñ‡ã›Ñ»éo÷ÑH%ãûûÉÝíô·áH†ÄA–óÁÇñÝãøâÝS{?™ ¿ÌêMæamãWhÕŸ½Ï_xgø©Ç™J“°„g"MeÛ BÅÂ@)ÏÙôf½_› [³vi§3gRE²ÃRô…`iÊ w„)‹”TÖã‡÷'wóçg,"êÇR°(”É ºIhÔ–òª;.ÂK¡æ‘A•?¾ Ö$˜›¤!œ×Š˜ÃöIï¯-<`à˜äuÓ©Ûd[#OY BqiÜÔÀU'ñ`·Érd4(—ÄZi£÷Y]˜Kã~ç\nô¤‘—Ò2h»C$’…‰
+ŸòÊ4•00*qb¿ó/÷C‘ Ê-i–¤·.i˜‚„ ’L©œ-Ùn§Í î°EIÈ(ù>[@%ˆôG
+Öåa³ úÉ-?ֆ¹Ð¾
+!Ë•"—+™’Ë-'¥^7N`ÖâR€ˆÂ䛃­F× YDÄ:s¢‰<V4γCE ÌhöaüšÏ¦ïi‚â)B
+¿í
+uÔ63¢t°)ÍÊÐõ:3žrÓ‹b¥«Ú‰j³ª×DÛhk ®³ÊM¹KŠÞ r0ù ¦"C ÀnA.Ú_4CDœˆ§¢®Î«euÌíçÝ‚Ðï\\fY~7 u»ÎEK´¸ ßCe³fàÞÊ=¹-¯7'
+n‡‹–Æ­ÝêªÊVn£ì
+Q
+.ò+úÇ…ã»À
+ _ *|( iw®QÖõ…B;’ßf'"0žµßÕŸ¯ØõÉQ;ê!‰¹ÔqùFéÆã6.®u.šü†ÈãZšt)…LŒ¢0ŽÎµò RH(•±Ãž®Rq… QÂ’ ‘nÁ¶\(kAÔÔë²Òd†ÜØ…`< X«ê²ÉUs^Qÿ)
+™GDÛe8,6šA@EN«§AvIZT8¶õô¼1•dx—ž…¤õw”¾ù=[ƒ/ȹÓëgÉÅ5c#]¸å¦tšþóP4™L°Ü¡Ì›fC÷¦)jÑxúv¾ÛCïû9Dðòàd=4P}`ÿ²OžMn¦óÿ¹–÷ÓÝlz;yc‚cK3ûv=kN‘Æ•/EÖùiâQ5@ŠNMGÀ[=u
+.ÚÙ"_bgæt̤T*´×Ž3‹Òæ,±d…—¨v !æû3HCìïnhR
+4ëíÃX©
+endobj
+2681 0 obj <<
/Type /Page
-/Contents 2130 0 R
-/Resources 2128 0 R
+/Contents 2682 0 R
+/Resources 2680 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2100 0 R
+/Parent 2647 0 R
>> endobj
-2131 0 obj <<
-/D [2129 0 R /XYZ 85.0394 794.5015 null]
+2683 0 obj <<
+/D [2681 0 R /XYZ 56.6929 794.5015 null]
>> endobj
-2132 0 obj <<
-/D [2129 0 R /XYZ 85.0394 751.8648 null]
+2684 0 obj <<
+/D [2681 0 R /XYZ 56.6929 752.0628 null]
>> endobj
-2133 0 obj <<
-/D [2129 0 R /XYZ 85.0394 153.4294 null]
+2685 0 obj <<
+/D [2681 0 R /XYZ 56.6929 603.3016 null]
>> endobj
-2128 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F41 939 0 R /F55 1037 0 R /F48 953 0 R >>
+2686 0 obj <<
+/D [2681 0 R /XYZ 56.6929 539.7009 null]
+>> endobj
+914 0 obj <<
+/D [2681 0 R /XYZ 56.6929 500.3546 null]
+>> endobj
+2687 0 obj <<
+/D [2681 0 R /XYZ 56.6929 463.723 null]
+>> endobj
+2688 0 obj <<
+/D [2681 0 R /XYZ 56.6929 431.4263 null]
+>> endobj
+2689 0 obj <<
+/D [2681 0 R /XYZ 56.6929 364.9038 null]
+>> endobj
+2690 0 obj <<
+/D [2681 0 R /XYZ 56.6929 304.268 null]
+>> endobj
+2691 0 obj <<
+/D [2681 0 R /XYZ 56.6929 107.6861 null]
+>> endobj
+2680 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F55 1311 0 R /F22 953 0 R /F41 1208 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-2136 0 obj <<
-/Length 438
+2694 0 obj <<
+/Length 1217
/Filter /FlateDecode
>>
stream
-xÚ¥SMo›@½ó+öR™îì»GbÇQ‚]C¤Ji–Á‘¥°V1QÕßlg£8Ê¡BBìÌ›·oÞ H¨{HÊ0C#@R”dÓ”<»Ü,À#&>buU߯yB Å)·—ª5’²z ¯
-h #M $)8?E^‚"øq&ô²CéE+ãŠ]ð‚!A#%{g†4 8ãƒE–M¥wÅ¢ïÇU1ÏAJb&À¼µÕæ•T»~+ûlövÛ'¤—°ë¦®<ôÀÎÇŽ‚j©Ý5Ãdæùt,5GQU³³»C×®»};†Võ¶n#Ôam7õº_Û×õËñ¨40¥Ô‘Žw®ÄÜù'$îK"U6}(o«¯ ™Û®nmÝJŠ¿‡®nãa²·‡}Ûí^›ÏöÄ]Ø÷ÂTéYâïÐÛ¿"àZ³·õðûb‰W¬N¢úæ³ÒOÛöQû?prÕ¿endstream
-endobj
-2135 0 obj <<
+xÚÕWKoÛ8¾ûWè(5˧D¢''q““`n²%[ÂZ’kÉ-Ò_¿C‘’%Ev{Ù…“"‡óøøÍ$†q¤@˜)îøŠ#‰pÖé;[˜»+3©…&m©«åèãgæ;
+)zÎrÓÒ%–’8Ëð›;}zšÍoîÿO¨ÀîOÆîÃtþ2ýjƞƊºÓÛÙ>‰ÏQ¢å<ìγkv7]Ü¿/¿ŒfËƧ¶ß3íÐÑ·ïØ Áý/#Œ˜’Âù¥¨“Ž¸`HpÆê‘Ýh1ú£QØš­–á ˜DBR
+yŒ²
+‰Ålfž~]<êx
+Å:¯ÚÐfR’™60M‘l³Êèÿγ]$®ÍççÛ—‡Ù|¹xS£-ï˜ç!åS~™œm©º¤¾%g#ÕP®g”`‚°¯Þ±ÚH ˜íMì!ìážÝel³Üp^÷öªùÏ$¬á«6P·µð©h4 ‚ÎBÆ|8B¹x²–ÔÈj)íú)7û¸Q…¤åeÓÔ€ínPX¥ ¤k|
+á+áfÇtéLqà_˜¬¡:d[3gЂ ‹ µÐšpÎÝëãÁžyåîµ·*Ïê¡â¸ßÃQíÆ°:ó¹|¨’JWì‘nRÙôaXº:gu»¸›NÈèSæþŠ“uܶi»úsõjÚÊCÝ©ƒ×}òi¬qt×P£Gžc…ý×UÞh1qêTŒÍqgúPŽQ}´™0Ì%lS_JSz4+ ·Ç¬ž¥!• Q §êE¶¥ÎÓ°‘ҵ΄7<”p=óß±ÝH ïò!âËžõ&&¶*fBÏàe KÒ¨8›ÊEœw6ãWvv
+Ïã
+—M¸e²wpmI]Àµ–Ò‘ÎÖ¦ú~€%¿l·‘0ÜÁ2EJåw-7˜Z ¾úJÕ©†«‚ 7·
+endobj
+2693 0 obj <<
/Type /Page
-/Contents 2136 0 R
-/Resources 2134 0 R
+/Contents 2694 0 R
+/Resources 2692 0 R
/MediaBox [0 0 595.2756 841.8898]
-/Parent 2100 0 R
+/Parent 2647 0 R
>> endobj
-2137 0 obj <<
-/D [2135 0 R /XYZ 56.6929 794.5015 null]
+2695 0 obj <<
+/D [2693 0 R /XYZ 85.0394 794.5015 null]
>> endobj
-2138 0 obj <<
-/D [2135 0 R /XYZ 56.6929 752.4085 null]
+2696 0 obj <<
+/D [2693 0 R /XYZ 85.0394 752.4085 null]
>> endobj
-2139 0 obj <<
-/D [2135 0 R /XYZ 56.6929 692.3565 null]
+2697 0 obj <<
+/D [2693 0 R /XYZ 85.0394 692.3565 null]
>> endobj
-2134 0 obj <<
-/Font << /F37 802 0 R /F21 714 0 R /F22 737 0 R /F39 899 0 R >>
+918 0 obj <<
+/D [2693 0 R /XYZ 85.0394 655.476 null]
+>> endobj
+2698 0 obj <<
+/D [2693 0 R /XYZ 85.0394 623.3704 null]
+>> endobj
+2699 0 obj <<
+/D [2693 0 R /XYZ 85.0394 588.7135 null]
+>> endobj
+2700 0 obj <<
+/D [2693 0 R /XYZ 85.0394 525.7396 null]
+>> endobj
+2701 0 obj <<
+/D [2693 0 R /XYZ 85.0394 468.6524 null]
+>> endobj
+2702 0 obj <<
+/D [2693 0 R /XYZ 85.0394 396.6452 null]
+>> endobj
+2703 0 obj <<
+/D [2693 0 R /XYZ 85.0394 211.0639 null]
+>> endobj
+2704 0 obj <<
+/D [2693 0 R /XYZ 85.0394 151.0119 null]
+>> endobj
+2692 0 obj <<
+/Font << /F37 1018 0 R /F21 930 0 R /F39 1151 0 R /F22 953 0 R /F41 1208 0 R /F53 1303 0 R >>
/ProcSet [ /PDF /Text ]
>> endobj
-1604 0 obj
-[706 0 R /Fit]
+2034 0 obj
+[922 0 R /Fit]
endobj
-1472 0 obj
-[706 0 R /Fit]
+1880 0 obj
+[922 0 R /Fit]
endobj
-1212 0 obj
-[706 0 R /Fit]
+1579 0 obj
+[922 0 R /Fit]
endobj
-2140 0 obj <<
+2705 0 obj <<
/Type /Encoding
/Differences [ 0 /.notdef 1/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash/ogonek/ring 10/.notdef 11/breve/minus 13/.notdef 14/Zcaron/zcaron/caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity/lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 127/.notdef 128/Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal 144/.notdef 147/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis 160/.notdef 161/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
>> endobj
-1641 0 obj <<
+2065 0 obj <<
/Length1 1628
/Length2 8040
/Length3 532
@@ -10479,7 +13098,7 @@ endobj
stream
xÚíte\Ôí¶6Ò ˆtÃÐÝÝÝÝ¡Ä0 00Ì ÝÝÝÝ’‚R"‚´t ÒÈ‹>ïÞûüž³?³?½¿w¾Ìÿ^×Z׺î7¶‡Œ5Ü
¬‡¹rðpr‹ t´P(ÐWç…C­fL9g0ЇÉ]Á¢
-Äü{fXE
+Äü{fXE
0Üú÷äè¹aÖÃöOÃoäæìüØã?ûÿxýœÿŒ=ì a.ÌÁAb¡ö™9Y® Ä£ò/z{xÂœ*Þè—ÖÁ»2#×Dj,ïêÃ8›ÇEµyÍî;Ýoª²n öA™ºÓÁß‹(üèX>ã.3v±ms™W`gÅúϨ¯"›
rn­êèš—ß¡RŽwð9£_²Ò¹Ð_8=óe4%v>oFÀk(Ù?`LÙ½¼`êú4ð±ûåÃ&9[~ƒ˜;26cLà«|r)Sƒj…×Íl(ßÛ
b¬Å7ÎßÊçÏVð™h9Žù,¢I‚°RÊ• e®äß·RÆ%=²ìÙ êt›œ(†Ì%³LÇî)®Ž>1Ù¥‘„µ…^Ñ2¼éˆO£Ý %õ‰>•pjÕr{2–ÂwÍ<–g¬™-j—!3cäáakIè,AŒ$ÁLˆÇÆ‹J¯³nöùU»Ïm›Þ‰D3
@@ -10502,35 +13121,35 @@ $OíœàÅ€DÈ
t‡Í=žÝbóÆÃwî6ß"£“˵?”JËOP2RÐ oQo+†â1)©w†¦ÜèådîI½ÈZ¿VÍ­(e÷åû È"QÔüFØs(úF$'‘qL ®/¶!õÔ ¤HvkÖ‰Œh¼È‰¬ê؉á¶o?Ùa:Šÿ±qêcŒ° gã!_QÇ~ÏWê¡1üaœ¯UÝGmã§Yñmn%ìRãr9÷¬ß0qˆ5†/‚E…(êÚ“†,W‚˜$Ù½ï¶åçLxËÎÔ|ú奕£w†Z|ÂV€ãž÷,éOd
ÞyŠGÝ ŽÎ¨Ý3lÍ4©¿Î\×T2Zª½Ag—.7Ù#ÏPæï™v¼eŦQLÞ»±Oþ¼Ô\’ ¬ÿĵJÅñ¾(š3Ç].Å*,MÎ>ÛBx(ÃSÃó|D³uû‚Þ¡ï†{:Ò‘Á¨2G9¡Cê{É•<|?ÒK áéá@F)Ø,êw÷ó?È ¸¢Ëa„Çh%Ù±o^Œñ{‹6™Ý @¥-«ä%Å~jÉwXjz1îi´·î¬%uÕ3^¿±g¸`d+ÎK[ŽDe—„]âò†YèÖýÇ?Ï>£³HjË,èkѸÍhÔ8Š” ™v_Å [ªJÖ®²9m=·âú?\‹k>¼à¬‡¤*³Ñ³ž,Y ê<‹ý¹uÓ Z/ZV$S·é#ƒmNOš¨5M@¿§rãÝ0Hõ7¬&7[àçŽAØñêOõƧÈêÚ5±pE6~d»Ž^.x¨T1¬µ¤$£Í7¿ÿ4òÆêüj§‹G1¬èípoóÌ3³QýÐZ:œNÍÆéç,0½‹Š‡Zg‹ðâ£à)‹Q©¯³‹X""œÛÆ0ÏÁ¾äBvFA‚)Y9(ÎYÖý…ì¬S…|¸Ôü¾“qbæÇN.LÔX§…_ï‚¿œ%%½¥åŒìé|°D>W²7}C–Í#—ZR¸­$º`bÛGο…a¿9gÝS%\”Á/œîñhC|?s§ Ø…šg¯ÎÙÈ)ª¬m}ÐvÖËk†Ÿ.bÉ&O
üõí+uqfº`Îa‡„°£â,I§ã¯½/‘˜÷ÇÝ›Á¤'P6ߢH‚Ú?÷›½šÙ¹˜Žà9¦ŠmHr7:pMRYŸ#£ 'æW¥¿ðKCß|-¡mWÝ躖nᲶË0–«ÞÐ3äÛÙ=j’¸Ë-,n–³e±€¢üb½iÙ;‘˜Hâ°l<)žL.ßÐYÖÿ°Ú·)wL=(‚Œ£± L|)=å'ÀÆ-Å@²öò¾µ<ÃNrä³6îµEôʃ3±d¶kÓ»¬ÿ‹%ôµøü·(kD~ô(¬_yñ‡Í; ¯åä²fùOî{&*‰äyÒ¯9ÛB±T¨d>è.<Sâ¢éX3p7«Á~ª"럽Ÿ“lË´ÍÔDQÿfŒ°Ì
-*s"}Y ;Ò‰¢ú{YÌÝÇí]p¶Òݯ€Ž¶Xo³êÙ}
+*s"}Y ;Ò‰¢ú{YÌÝÇí]p¶Òݯ€Ž¶Xo³êÙ}
endobj
-1642 0 obj <<
+2066 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 67
/LastChar 85
-/Widths 2141 0 R
-/BaseFont /QJGZXQ+URWPalladioL-Bold-Slant_167
-/FontDescriptor 1640 0 R
+/Widths 2706 0 R
+/BaseFont /LBYYIR+URWPalladioL-Bold-Slant_167
+/FontDescriptor 2064 0 R
>> endobj
-1640 0 obj <<
+2064 0 obj <<
/Ascent 708
/CapHeight 672
/Descent -266
-/FontName /QJGZXQ+URWPalladioL-Bold-Slant_167
+/FontName /LBYYIR+URWPalladioL-Bold-Slant_167
/ItalicAngle -9
/StemV 123
/XHeight 471
/FontBBox [-152 -301 1000 935]
/Flags 4
/CharSet (/C/D/E/H/I/O/R/S/T/U)
-/FontFile 1641 0 R
+/FontFile 2065 0 R
>> endobj
-2141 0 obj
+2706 0 obj
[722 833 611 0 0 833 389 0 0 0 0 0 833 0 0 722 611 667 778 ]
endobj
-1627 0 obj <<
+2047 0 obj <<
/Length1 1630
/Length2 6133
/Length3 532
@@ -10542,7 +13161,7 @@ xÚíVuTÔí¶VA!¤†n†n”.IéΆ˜f(‘N)én$†FJ Á!¤[:%•$.úÝï|g}÷üuÏùë®;kͬ߻Ÿ½Ÿýìø½
Òy¦§aáèha …«pJí•Ž H
±@Bá0Y $D¤±ÉB¬@¼¼ 
µµC‚XnxXÙÙ9þ²ürYzý‰ÜD" ¶0Ó̓;Äîì!o(þ×ZiÙ@! u %5‹‚šHƒ¸Þ¡áf鵩@­ 0„dw9þq
-³rt³þ%àÆnÿ-ÈÙ~ãátƒÝiÀH„•+Ô ºÉª!+ÿ‡N¤òWnôÁmn<­áVn¿JúÝÐÜ H ( BB<‘¿rYB@ÖP„³£…×Mî2gWèon(Ìö/ Wˆ­…«µ#¸¡¹áþÕ¿êýSõÎÎŽ^¿£á¿½þ¡ŠD@m¸
+³rt³þ%àÆnÿ-ÈÙ~ãátƒÝiÀH„•+Ô ºÉª!+ÿ‡N¤òWnôÁmn<­áVn¿JúÝÐÜ H ( BB<‘¿rYB@ÖP„³£…×Mî2gWèon(Ìö/ Wˆ­…«µ#¸¡¹áþÕ¿êýSõÎÎŽ^¿£á¿½þ¡ŠD@m¸
ÿóü{é!Oˆ`zn%lŸš‘†¬"Ïéé—5úÐÁƒÑâ\\£ý:ß¿Þî—¾(Rf~QÂU;(zÕä5¾í|¹ªÌ¶ÖÛAæÈÜž ÙË£ò¡g}ŸO4ÏôNˆ}-lZŒŸöU/Ê{LeÓP[wm©_ó™iÑÅ=àà;>WìýSVz÷|R†g_«”·¯´ÖÞ"®*ØþÊ”°yzÂÜÕ÷±§»ýðîûUJöìW8Œbî˜øL‘þ.Ù”O uJåÊߪݎË;BbubÁï<_^Ë¿Å`i¢KÙÅy¨yc@–‰Ÿ'\;ø$·®Q;S-”âs/, 9D¦Ô#,9ƦïKv²±SÐúê¿»èçö‰%…÷²õ-âÁ]3ëãÝ“±Ñ][™CæºÊlëŠÑLü‹¦ëÀ¢€5‘ؽrô›ìç3üÜ°˜üDÑSjÛðôä)Wï8Ž*öÜŸèž“3@'}~+ÏÝ6‘žˆ•Ø\Žpµ<züuÚ>AbåPóبLbZ÷a3ÒYÍEœVÁ= ¾‹­{·^®2<¿}5aq€©ÿ_5¹Ûðòµ÷>›À¥´ê$C}ÀXŠ¹­œÕ÷ji—û­€G‡/§Œdû-!j¹;Ë6#ÔÜŠ.Oé­×ôÎc´¼$z¾I(ñØÇ/ Wj®½"¹ßKÒÿ¾ð{Lš¿ÞH¥hԻí:iÓFRF<g] Û39}—ÞÞF™8|à0­‰å
b݇a›yKÜ£%t×TcaÖËF˨?B:äÐ 3ÚZP ‚ÌÆŠ} fñφôˆƒTU‡J鉽žj:»«Ï‹ºôN)/ÂÕ äE½¬^gº‹ ^/«k¯&6Ö7%³"”-ήQËòÍ“ ñÆ‘r¾“'#
ñÀèHvo»Vüy½¼Òç³³”ÎjÁÕŸ,_Âh^§–p³/â#Ó„HÊÀç„»ûÄŒ[‡¤Ê»B8Ò¬’%PË ™#¹&}Ô7uo(à–îu•úµÒ95ÀŒ¾?ËêcÕ8—ÄñâθÑ,™ê:f”†.‡Ðà¡ÝõÁ41hÀ›3):«;Ícƒ·ú‘¶Þ,èðY½:Nç5u…QEð ‰rŸ–²ÌûŠ!&.ÜYâü×É ú;á$¤`×yme~b©@{•3*¹
@@ -10560,129 +13179,133 @@ d ¯òˆ¦:ôw
ÕB¾ª\h~8©$‰¼¼·ý˜7!g;É¥ƒ\®cf>}7›ùâžÐÙZسãÁÖ–Ü^-Už&(
ÖËÓ»ÜIFÙØS­˜õOV_ºhýÐn-®
X{$¢½‰¼û£@–rlZ™âɞˊ1o(­¶¨mèö¡Ðé»÷ÝõäIŒ]Œ_-ô‹ ¸Þû ò'zŸT¶n76Gت–·& úìIĆ‹7ÎÔ‰‰f¾<B‡›&ª½úŒ×ž´)„Æc+¤ œ?µÆ(_¹à™ñ0áNZ¬/ˆ_c24íŒË¢—'{.ö¥dÖî§Çz̓¯ÛKÃ{u`‡:s±¹ Á<º'—0— HMq±LåRnC@x›ôs̈W6ß>uä3¾õˆ;)EO4,Źk&l‰#õŽ¾„˜¬Ù¶³ ½höâiF] ‹œx'´ÅfÊb\ñê{Ý?¬¹¶=ê3¤XTÕW©*®§‰\Ee¶©x‘@†Dz:ƒ!¡X¾ÂK ”G½èß>c{BŒÍCŒ±¹0šUÕ¼ƒ¿ªÝ•5xfœéÉU“Nhèòã»Z–$8û훎·òБÞåú¸;ß¾2~%~QÍ÷*|6οÀ.©ó¶H&l]ážçµÐ[èù%¥κƬ!ÙrOxÆ!.B˜“zuW,Ôêr‹9å™ÊT°CHÖ‘_e‘‰ÿð:û5r€û3.ñ4v—W”ò]ª[)ïó–äÙÀ—݈H¾ÌûùSŽ¸+¹ºfS4çHõ¿ÞzyàÂ*/ç%Šâ׻͠Ï8ôæãmº'7…\ì°Å÷K)8ÐÁ@£bÅî\ç±ÄÝÊ‚×[g“©»5é«ÅÖ¡’'¯ÔíÌ¥ºégˆ<‚â¢Ï8TŠqùœ_U å=¢¦#fœÞ*ª6í¶²*æ›\oi›–•`ûlj[ÛW*ˆ»ºœ2Ž(ËtŒp{ˆ¥6Í]š†}„¯>{?'CÆà§5zíEëÝÚÓÞ&vø¾öŠ ÷dYcØL‰8àÇÉu°à•GËÝšÎñtûëV²­ˆ’eÓëû­&KÅàჃ‘oS*.m•»8ÕîŒWQì3ÊDÌûj OpHY²ï®f>×¼ù‰_ôŸö‘Ƥ‰´»ø|EÀ’=PzêîXDƒ%½+C£ˆ1_ù¶‡=AýYœ:&Aaú;æ¬U¾öÝ*“ÍXJ·=à²ùˆ1¦¬ý<ð»©,|# O'Cƒµë“M]í¼æf°ºÜS4‡AÇ÷Mj€“Ò·ÐökxõÊáž™ËG‡ÞÕéú,óÔ92‚¬ ߸gp0o9)ÁM£«&ChVF=Vv¯ñõ­Åž¡üÜÈT·Žïvä(Ê´ãé¿7jzä­ ¾¹Â6]E³ÚŸÉÞeIGOIùç…&˜+ÊZ Sl©
-Í`ƒ©c½G¯Lsé:JθÿÍàÿ þOX9B,\‘p' WÀk yªendstream
+Í`ƒ©c½G¯Lsé:JθÿÍàÿ þOX9B,\‘p' WÀ^CyÆendstream
endobj
-1628 0 obj <<
+2048 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 66
/LastChar 78
-/Widths 2142 0 R
-/BaseFont /ZEMYJB+URWPalladioL-BoldItal
-/FontDescriptor 1626 0 R
+/Widths 2707 0 R
+/BaseFont /ZMEPZW+URWPalladioL-BoldItal
+/FontDescriptor 2046 0 R
>> endobj
-1626 0 obj <<
+2046 0 obj <<
/Ascent 728
/CapHeight 669
/Descent -256
-/FontName /ZEMYJB+URWPalladioL-BoldItal
+/FontName /ZMEPZW+URWPalladioL-BoldItal
/ItalicAngle -9.9
/StemV 114
/XHeight 469
/FontBBox [-170 -300 1073 935]
/Flags 4
/CharSet (/B/D/I/N)
-/FontFile 1627 0 R
+/FontFile 2047 0 R
>> endobj
-2142 0 obj
+2707 0 obj
[667 0 778 0 0 0 0 389 0 0 0 0 778 ]
endobj
-1396 0 obj <<
+1441 0 obj <<
/Length1 771
/Length2 1151
/Length3 532
-/Length 1712
+/Length 1711
/Filter /FlateDecode
>>
stream
-xÚíRkTSW‘ª¡¬òRIÕzX%2yj   `,žò˜{CnIH@Ä•TeYÄF—<EE©°ªÔJ-±
-SÀiaËqªUð5¬««ôç̯YsΟ³¿ý½¿óMóˆ’1D¶ÅP‚Áar„ X*•pØ€<³Ù-‡å‚¡!rŽ@à"´jÀ]Ø|!o…ǧÐ@0–¡Ç‘4¼‚é“$>i`QÈQ •*XCÖPÈÕ@†)˜Ð3H­ë&od‚up&ŒgÁ“Âá
-9DdÄ@PÖXG*f1QŒ ¯
-¼]µ~´rÂÿn÷„6ßõÊHQç/gVH•Ò7‰²½©ó•Ùz]×¼ìæî²Nº`†×Ö3Ÿ¾ä~uÚØ´Ùf¾F}g«êØ~Ýõjx¬£†³%N ã>?ßY`÷~nQ•új\Z?¦Û_^fí?ºóRv̇…æ»^±îeâÒ׶ ±õC¶åI‡¹B—&ESƒqÏŪÇcÕÁxYt¢ývÊ–ˆai}ã‰Ý;8‡T9%Ýs [f-ܹùg·Ç˲d•_¯8Ï/ÈŠ=Êëœó½çâb¥äž*×L»'î ÏyøÃÐ{ö!£KžÄ5¾°ªúÎøV”H†¯t‰nµí¡Õu«›kÊ
-÷HçÖºlx/ÌépÇá5'ÿÝ%¼ÏÚǩˈ—¯O-wûVŸZÌ é1>
-k] ¡GZ±Ç5}M.íÌü|QYP÷]#ª”ÆÎëåù¿ 1²FêD{õþ9œ˜|V@û,|±ÀnÖý®&|þ]j p삸5ùZï—£kwò_Z’Yôäb†œXÕÛgÙø4;êpA5µn€ý.Êÿ üOP¨a9N`9žNù7pQŒ‘endstream
+xÚíRiTSבª¡¬2©¤j=,Œy5„„1 ó$1÷†Ü’ÜK/7”AÄJª²,b£KFQQ*¬*u@©%Váp"­"<ÂòY¤jUœzÁººJ¶¿Þzçü9ûÛßÙû;ßÙ4·Caà` %&G¥R ‡ È3›M¡ÑqXN $'`!à^`µV ¸+
+9
+¤rBkÈ
+¹È0z&©Õ`Ýä °΀ñLbR8
+l€S”šÔ$A•à¿!múÛT&Œg¢€Ç”L: EBªÖVRXáÙ &µü²¦ÖªÕárÍdù)§þ’—kµþw¦I×0¤ãètj üFœ†­fzVBÈÕˆB„¦ªaÀà¬d²W¾Á‘Œ`DC¡P¥\Oá0
+MWBú7¥ƒâùû×N%#äJDêÓaÀþƒ=sþˆI“pDØL6›CÉýö”4­™U`‚¦.Ï Èq\®§CDF<Í
+Á:
+-ŽÃ(15>¤Aoc%Bz
+Ã:XA1ßÀ>[>Þ{j[mž¸ºë¨-=c¡ñð–Žs[O}˜Ã}>N×ð¦"á~uÜêø1rÌ¡t$ì+¤äõSO‰rLÙ2ÖÖ^G“½ ½rŸlÖÅpbòŒKåímïil¿k^lIoò|ð£ûÓ;™çlë×Üãð«¨#E3koÞxù8/mcg¿ÙîKÈ}¨”’T~zÍ8ú¿wŠ¯LÜÁª1sÍ¥ù‰ûž:¿2SÛn÷¤Ý²7
+ åR›ëFßsØtr “ÂÙŸ¶Ø[&X-Î^èu-ºÂ¬Þ÷u3Æúµ4‡I™=ØM ºßí‘ä–†ÆH¢F­tRÔ.Pû†ÔP­á†¶øVz¡ÐÒ°¶À)­¡‹ë[ÂIoÚC[—2þ’öë’3Ÿ$=Þ÷ìµÚú@‘ífåz|FŒ§÷~ÿLÏaz›j{õ3“[œ\õÅ]BäÚg·ÊЮù·ÿ@N˘Ä
+®ç»Ü8ò™»™K¹'×ì­ø—4ÞóëfÓîD±ÎJwýp êáÏ[ û¹ÉÁ })g"oz^ªk<_ä\W83ÉÔ\½¤y6Ö;0ßÍÏy¡Ï\Q¢%¨vš/ôèŠï«Îæ8ñ&Æzèyá3ôCi”©iä°×¢<Û¡Í Òv2ïG.ÏöþÅæ\X]Š¾Ë»î„éûyËöB‘9Œµ{ÓŽÕ†ÕnÓè æì9*hxȱ©È9ûDÔü²/õaŸ.§·ÓÖ_®{D8G<¯JaâqþgZÛPµÏÎäžùh=Ï'1õUßáuk²wm|ðèæÊEÛ×S„v½ƒjºøÓÒ¼×[F{C´vŽâæŽ3z÷¨ñö÷ýˆ`póÙƒŽZwßد–úµRëÏÿglÕZ×Q™ÍVÇyYLР–*M r±\
+§z˜]MRço%O\QSKºa[0A;ôòDui4+Ïһꤗ±f¬JˆÊ–JN©—[͸=sìq©«å)¾éÀÕP~cÅNÈÿVeDühå„ïî m¾ó呢ΟN¯*¥¯d{Ræ+³ôº®yYÍÝe *t -§?ÊþœûÅ)CÓ&«yx¸$úÆZÕ±íšó•Ðh{ gsŒ@Ç}v$¶³ÀæÝÜ¢ÕTê'¨aiý˜n_}h™¥ÿÈŽ‹YQïšîxD»–‰K_YÇE×uX—'â
+šM †ÝªJì?ŒVâe‘Šö[É›WKëï²ÛÎ9¨Ê)éž[Ø2káŽM?º<Z–)«ü2Þï¿ 3úl0¯ßηU”œ{b¨X\s õ®¸74ç™ÿwïAïØ.ysÆXTøÜ¢ê;í]Q"¾Ü%ºÙ¶›V×­n®)+Ü-[ë´þ‡C—…W|wu”tð>i§.#^¼J8¹Üåk}J1'¨Çð0¤uM„nÅ‚ìÃûšœÚý™ùù¢²€îë;GTÉ×ÊóB£dÔ‰öê}s8Qù,¿öYøbͬ{\‰ûô›”þàØyqkÒÕÞÏG×îà¿0'±èIÅ 9±ª‡7ϼáIVÄ¡‚jjÝ
endobj
-1397 0 obj <<
+1442 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2143 0 R
+/Encoding 2708 0 R
/FirstChar 60
/LastChar 62
-/Widths 2144 0 R
-/BaseFont /UYGAJA+CMMI10
-/FontDescriptor 1395 0 R
+/Widths 2709 0 R
+/BaseFont /KPZHNG+CMMI10
+/FontDescriptor 1440 0 R
>> endobj
-1395 0 obj <<
+1440 0 obj <<
/Ascent 694
/CapHeight 683
/Descent -194
-/FontName /UYGAJA+CMMI10
+/FontName /KPZHNG+CMMI10
/ItalicAngle -14.04
/StemV 72
/XHeight 431
/FontBBox [-32 -250 1048 750]
/Flags 4
/CharSet (/less/greater)
-/FontFile 1396 0 R
+/FontFile 1441 0 R
>> endobj
-2144 0 obj
+2709 0 obj
[778 0 778 ]
endobj
-2143 0 obj <<
+2708 0 obj <<
/Type /Encoding
/Differences [ 0 /.notdef 60/less 61/.notdef 62/greater 63/.notdef]
>> endobj
-1136 0 obj <<
+1430 0 obj <<
/Length1 1199
/Length2 2269
/Length3 544
-/Length 3057
+/Length 3056
/Filter /FlateDecode
>>
stream
-xÚíWi<”k2ed_â!˳ØMe['ŒÆNeÌ<3†1Ã,–¬ÅÉV–É’#[Ñž%ÑbJ¡Ñž’(EY¢SïC§zO¯oï·÷÷>χ羯ÿuý¯ëúß×ýáÑTÃô­ÉÌ@ОÉàèch,àB ä² DÆVým •ëÄ!Ò0&Â55Ýi:¸¬ Ú²@"‡ÆdàˆÈÇ=ˆ 8Y€À ±h3¬Z£ ¿;2YX
-Táò™[fX4‹F â
-'/úâ)D;2³Ø6€âp°(T…B6$›‚d€”T¬ƒlË ]$`ÃõÃÑX j,µœ†! f$#fYˆBc—Ú#sÃP Z8tÂý
-¶»(„œP2*6Ë+ÆáoYÔû­t^)š­d—abnÓ‚\-%"%蘦øyz“ víû5ˆžIt‡bÎ~…‚’׶Ñ×ß©ÕÌøhZØÞ–"¤2eÖÍù¾ w…)©Ô”× »Žè˜ËÍ'M¸:ÒãÝ°°{¼V:8ioÈ–Ëçî~ÒÞâ+rîͬt]‹T@ÿÀUQã„{©pNãû@%Ÿ¦ØÖÛ— 惪›(ó§xaåÆ[ ·‡=Ðë>í…Èx—Ôj£{Xæ÷Õ…dïÝ5êíqÕmUJoŸÕÑļÔR¹¿Ð¶·MTŠßÒ&$ ¨Ù×Oš+¼œ:RçlâpÆ›¬çm
-„‚“Çý+QùXP W±
-V+î²ïÌêÔ`_ðŒw8O /L(î³¼ªWÔûlÜ{óZÍiáË>™1u
-W»Gí'oÝ\%7rƾöö:¡ŠÊ¤©œ³?„b&TáüqD!Ï¡øtí).ÍñòÌû%
-wV¶šØÍú6‰” ÜÜkì¨0
-Ön»Úd(Ážú…XjwTêÝÙFÙçþÀùñ€L´²ÁEÙ¼f} ¹H=±î…žàÕ¥êŠc ûy:W|Ôf"yÕ=Û{ØÚ¸—£ôpæ IE´˜ýæ|vb.›ûÂ[Û÷c<îõµ3‹0™p2hàª×*?÷Z˜Í>Ó(yF:þúÖþCêãñtÿ
-)å?ÿTsr0ðõ—F›™VF×Ï9~Ðzèt#p¶¯‘ýEñ^Âjd0  |7•ˆ/®Îœø˜“ä+¶BÌ뼤:œVb61Ò’¬ühM÷®Âª0r<¾tþo/VŸ4,RtÈǘƒÇÓíéè[¾Y)Éy;àá„€C‰6{‡„ïÞzӌ؈èMWy° æ½/óÂ]†9Á+¤l¨ØŒÑûË$¯P2A>”šˆ‘˜l¶Ùår÷œuedÇhç%±¼`EP¼>8·E}Ç`Md@xº•hÌo#­<uÓ™SåG.ùU¥çË]Ÿ™£âÝæ_Z(_È!O/ ïð—(³Áöô¥Å(&×—0¤€wgzåaÂ×^ Ú˜³2’‹î Þ.ý¬îbyŽ?¡.Ýo´ý,“på rÂõ*©Í
-‡7ñT_;´K°V%Áh]§ï%Çùqú»†Ý--®u8õŠn½ØüX¿/Ò9­QjñXÔû¬°) ¡,LzÌÓ\`dîÐÆ_Ñ43ƒšnjSnq<#æ¢ »¼WƆ´†YÞX3?Ó>–eëÄ»7Tÿͯ=ƒ¿\,sÒÒäÉÎÁa° _ÂÒO`sÚÃÓÙ¶ÔÂ×+¿Rv|Ö\öù%dÓR„ƒì±ybîQlk«@¦ª9â³ð#ÇC\F?Ÿ=à"0‹ÍcÞ,Øåu0ÏBssz¿Æ®ÃWì|úøòupSЖkúÛCA›‡½olF‡ ž€g¸u~îìº$Ù÷Ž¯ëÙQíz­-=ÕcÁþ¬>—yÒÂ*¹ë(ù#/¾ÊWûöü»ÊP$á`ûPéŠVV²ùýÛÒ/Ÿìžg¥\)9Ä ¼\›¦¶æ×;µJg;gQ‰šëºÓ
-L[ô̸ iö±•b^=“¼täçÒRyéÍ}G®‹±a¥0á VšÚxGßûÇ[5DH›vlx®¡’qÂîM5·:{›Ví–Jì‚A[DùñÛ¨¦UˆeÞî,žÃý‚ÀȳÖcZÄ£*Márn“JVéÍ>œ£€|¼§øÄÒ »«âhÓ°¬ÚÛL­§ „c_Q®>³þ®âÆ"„B#0¯mWø"û¬úv>¼ë.@SÄP&v^îÌ52
-Ý5›õ‰·Çícüžf„„ËMÄö
-E¯ÙÚÉŠ{}$³OÔ¯—X@|Y}ÓÈdLÜ\9a,]ÊÒ5‘,!¸¡˜Ý)¼.Ñ^¦„%§º)¦ÿþþm‰­ x›|wrŸCóÅQ‚£ØÜšž{—ׇH˜²«q+!¾ïfO¤—”É $ártÌX±õù¹±Î…® )ýõ¾+ܪ‚m‡7|(KÐ/¶²d(å¾7*c¥ÉÝ’xPjrè±FžêÞ R*3S/·Ù]ûNÔªdÎX–-Ï2ejßP(Ù­BÐ/mò~ÓÑyA!/÷º/ˆSšB~|£—d—:ùR¹ßšõº±Ÿ=Ëï8Hàm³O=Q«ôPö¡é¹>?j¿Ö¹2Q‹µðjîšõÙUÂgñ7Õ2…úK»äÑÿåÿ?Áÿ‰Yf(‘alè‡rñß þ/h‘@²endstream
+xÚíWi<”k2e$²ÄC–ÆŒ²Ò £±S3ÏŒaÌ0‹}‹(N¶²”H–{¥Ý–h1!²†RQ*Z,Y¢SïC§zO¯oï·÷÷>χ羯ÿuý¯ëúß×ýáQ”ÃâÔ͈toЊNc©£‘(CÀŽâïÍfâð´½êû@2Û†…§ ƒ‡+*:RXTpM´`€x…NÃàY£°Å3
+T¬%hA÷_!`ÂWôÃP j,Tc- ýhô`Zøš‰B#®¶Gdh8Ñ(lÐów
+ „>ðp&>X 6þïÀ?wp4 R,À$CGò“2ƒ¤o{[<‹A <PH
+  VÞ«ýÐáé4jèOw;¼?hØ¹íµ±pQ]«ÿžæætˆV­§¨kêkh4Ô§ŽÖ¯¬?ôø®Åª‹§ü]+ê'¥ D ¾µiù½­ Á„f@¬Ž¶
+ðO~;:‹B
+béLÊʇBtп`Ž>‚ d2¡CY…@ñ—¤–4H¡‘ Q<ƒøðØ ¤ÓêIA±ß÷$
+T"†€ø`?°ó°oÍáúÅ fRÁê/hµè:ÍeËjÓ©\cHîf; ¿2)í‚9ýÌ< ¶ÍǸÚc½íz®„4)Ëd½`?óäF!áx!î݉’o‘—vÙnžÚ„èšFµH¦“ÈÎczw÷¹Šy7Ec‹!\]4zÛ¢û«×ö0)™Š¢*^û×ý*bK±ïíwS£ a½œF Ê7öH6ßž›W~RÞãÎwõí‚pUƒW_ÿms~èÞk8«fÊ[Ê­LÏ°±ã¦æ’Oyié' HgÖþ€aµÎK.ˆä±æª§D.°_½•ˆs=T!ß\Y^ü¾©ôIAÇEôK%™GËMGšø…šxD¡ÕÿúIq«„MK¢y$Fg—Ù’y6R—}þœç9‰Ó2³óa2¦¾ryíV­©­
+ÌëÎQÖ×pÄå÷’GMn«åv?ŸtÝf»YqŽ÷¦NdB@×fÁ¦£ŒmÐ}𻕪„@©-ñ%mã_•ñÖ¶dÝŒ¡KG`‰üDù¶šË§šZsÂf$áîOœtCUñWxò9ÍÇ97Ç¿{ä± þE*ËeÇÛͺÇ3S£Å†7«Ã¬koO «·jøðiUå¹ei4û‚ð ·›e±|zæ/#& õ§öm 9­aÐÆCîo`4Õñzx½;;k|¦󇮕R…SRö Ÿ Ó6ûaíJ¯Ž¦¿:4÷$ õÍ•ÁÜf¯Ð4Õé‰Ãžwßr˜CGƒòjëÛe#0—.n×ÜõÅËUÛõɵ¬bÓ(‰Û¯­¦ïåÞß 6~Ùª²cOqIìñÖ²þymÂßËÂ'9ƒ‡ŸòD%)Ïèrµ+N¥<Ê—x°¾Q×rÁ½Ž¯°ÿþ«³Ÿ@‰×`®ÃÞ<ÕK
+öÌÃÏD¹¥DíÁ>ÒQÇaÛ‘~‘PiÍYIÑÌzuc±`µ-Ë]¾ ä%'–qUn¹]”›æ”ÿõüÈ)3n–ÔãùË$Ñ ÿ›ímXÙb²aÆ We÷Qd¸Ë×>ôB÷½fZ£|³ô¨ËòBÚåš­—…ƒáo^ZÕÒ„>žKò,’îÿóO9Û!k},Û^ûz žnª}÷êîY•‰¡á›{Þ =5Ì/’½Ñ‘¾‚ôE@O0*¯<uàýǸðX÷-붸\Û*§äë¿oˆSó}r¬¢3,çÀp)ZŒ3(œõÛ‹çµr%­ÓÀ úÀ¹$+ª7ªÍ=5>.ó
+ÚÅQÿåÿ?Áÿ
+â,º?žág€Lè‡råß þ/uÔ@³endstream
endobj
-1137 0 obj <<
+1431 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 97
/LastChar 110
-/Widths 2145 0 R
-/BaseFont /DYYCRJ+NimbusSanL-ReguItal
-/FontDescriptor 1135 0 R
+/Widths 2710 0 R
+/BaseFont /NYLICW+NimbusSanL-ReguItal
+/FontDescriptor 1429 0 R
>> endobj
-1135 0 obj <<
+1429 0 obj <<
/Ascent 712
/CapHeight 712
/Descent -213
-/FontName /DYYCRJ+NimbusSanL-ReguItal
+/FontName /NYLICW+NimbusSanL-ReguItal
/ItalicAngle -12
/StemV 88
/XHeight 523
/FontBBox [-178 -284 1108 953]
/Flags 4
/CharSet (/a/c/n)
-/FontFile 1136 0 R
+/FontFile 1430 0 R
>> endobj
-2145 0 obj
+2710 0 obj
[556 0 500 0 0 0 0 0 0 0 0 0 0 556 ]
endobj
-1064 0 obj <<
+1354 0 obj <<
/Length1 1608
/Length2 7939
/Length3 532
@@ -10693,7 +13316,7 @@ stream
xÚívgPTݶ-HPPÉ™&çÐÉ™–œƒº–††î&K(HÎQÉH ’sÎ 9#$ˆ€øÐïžsn}ïüº÷üzõvÕ®ÚkιÆsŽ¹VmVF-]^Yª„p@óùž4`ö–Î(]°ƒ¯ÜEXYå‘P0†pP
G8ÚCзÿãºP(
²BÂÑ€Û¬Z
-JñDÛ‚Ñ¿s£`·n
+JñDÛ‚Ñ¿s£`·n
uƒZ|™BX‰¼LLIB—Qdt (<okbu:æ}Ò{ŸíûÑ쓼,Vôâº4¯rèéMûäŽãÏõg\=-äpöæxèA­3gkö£¶Qî ~ó<¤]ÃpÏà µ%l“Ç+Ú:æ¹×w醄x‡ß9}™]²}IYΉ¼­*"ÉVb—åìì²Å|ý~ÎÞÑÛÝÕÙ|ŒÓºNÉÏ*î‚MÈæë”N#m¢_äa™ ŒéøÛÔªÏ!´0sL^µ$0ÙÂÿTh5ë¹[­Fúù{ª\™ÏíßÉúÐâ¦Ùé%üföC ~–fí*!Î:‰EvýÔzð­´÷Û6гßÕ•Ü 곺£Âgü«e‰;}ƒv©b]ùßÖÒï6”‡ùÚ}sø.Gj¢T«$Kñ£•I âQ–®‹Â~ÒìEÛ1w.ì*Çbr|¬½}$oÖ‡·Gs]> Ã?V1ñŸx£+w¿³^õ9’e‡Ð†ŠÚ¥ÍäÊu””7œœ¸äN­Ñ÷ˆ¨/ùŠõ.‹ú…'Ð)á0äPùÝÚ…ke
¸éÛR§ö
]8sô&sß±­|*åŸî#>cÕ¯‡‹úœ‚ œEëÑymeê÷AÆ€>8m„ 1œ4¬jõõr¦XÜâd8„²³¤¿V>M¼çÀ7ÁÜ&N\€*ÄJÒÜOµøï8•^Ýçôáö¼J%qõ‡ ‘®.µ&у;ìXBÒ0ÊÚcVKŸ0-SÛ·ߌG?óí·Eƒòñ(€(§¸Ëš’=´øô•ú+y\J6.æꔋ‚œÞ»ó^eúÞ‚·V„(õb*$Ã=AÁžéÌmEéïa9žoñ€Rý3™ÙÑS×!÷8ÎãÒ9‹ÅÕçÜrƒÅ£‘C™Äù\‹-ÕÕ²k±ò¡øáÃÍ8
@@ -10725,361 +13348,356 @@ QH;ǘ¢&šùŸe“ô¿žUÙ|µ°Sc0R2YE]¨
‡á{__bçâ.°ßþ
LóÃI8GU–¿Bã¡\‚–Ÿˆ{éõ´Sû›7M‹Š–…;ûÛ䃵h¹0GQœ&÷ <‹"œ_ý¼ÈAze‰ÀN2ÿPÜJ"u]©¶ÕLòs.}æQùü‰iõHö5¨ñ‹‚‘öqLðëƒýUj[’ =Á®…1Ñè²YÆHOŠåoq ’„!¿‡RÒ¯¸ð%ê«~u¯ ³¿0Š×·6î;>nE=m½aÔ\{\ÄcïQq”&T/bµ^þü‹}m“¹ò A’ü陈×O/ÍI>c×b%ÒÌ&ìýºªú· ¶mJ;û7žb{ª6eC‰Æô_è<@ÀbW’+Q'‘šäçÚU›‚ݧ/ˆ+ƒË°a
<¤þdÑ _IÒõ.˜ê¢Ï\9¾§é-xÚÖ-9?›ìÐv_ wóý}¾éH`…Ñ'>Êß4¬>äŽT‹¬ÌÛúGäµGÔà…$Í ï‚7LI›u`žUJ2ì„΃79ç¯~f´lá­ÊΚìïW 5?|¸':U—.ûrJo ÇÓlÔË5áAÜçxE ³º×ا‰3Ç•ÚTñ#åKþtâ•.iKW@ö/É›ÔÑ÷ ûj&Q ¦Œ²È˜¥t°Èð§Äh-ؤ1íý b?e¾™F Š– ÉXrÙ/&Šjz©¨rAÁM°re.2Òe%ÉÍ£™6"5[¹(H4 :\mdb“™[i:ýP½2“¿Ýä÷ö0JÑ»pÕh¯QšQ¨ý±Qó_»Ã7;mþã«÷Aú^ÁÐ; Ó èvñ¡Õñ¥ã«*’Hóß¹,QëtT½}…ÁbWý€g”ùxÔ$Ó¬GÞ×™®'}¡uÞói õ´’D§ùõ; ¼xðÞÔ¡Æ°~. °öâ%ÅÅ4O”˜»ª¡ Þ»Bï­\ÿÆÈæ 
-†ìvm…$t§³ÎLd?莑ˆ+í–«I&VñZ"-¿35MGöÊìä§7À Ñ4‰>ÅauA×W¯½r‚…`Hã×W{Ûw1Û®­¹E¥^["W¬%BŽ… >«íÜMÑ#nNCuy‹¼Hû %Tž,TÜþ0]4.ïdîžk0œPañœ„5ðY ÓëF–?ªU'?Õ‹«žäfü¸Š·Ö¤qCr®až1j,†º¿÷2Ó“=²õáÿ¶D4ÏØeÊÀ¿I Üóv¼vþ´b„dîÿ¼ø)xý)\+"oÜ´¦ÜD1å[|)h$úØûeGUeŸ?õ¾†Ó<åízznKB†Éd–¬ö…Àÿò!øÿ
+†ìvm…$t§³ÎLd?莑ˆ+í–«I&VñZ"-¿35MGöÊìä§7À Ñ4‰>ÅauA×W¯½r‚…`Hã×W{Ûw1Û®­¹E¥^["W¬%BŽ… >«íÜMÑ#nNCuy‹¼Hû %Tž,TÜþ0]4.ïdîžk0œPañœ„5ðY ÓëF–?ªU'?Õ‹«žäfü¸Š·Ö¤qCr®až1j,†º¿÷2Ó“=²õáÿ¶D4ÏØeÊÀ¿I Üóv¼vþ´b„dîÿ¼ø)xý)\+"oÜ´¦ÜD1å[|)h$úØûeGUeŸ?õ¾†Ó<åízznKB†Éd–¬ö…Àÿò!øÿ
endobj
-1065 0 obj <<
+1355 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 36
/LastChar 121
-/Widths 2146 0 R
-/BaseFont /FUNHRG+NimbusSanL-Bold
-/FontDescriptor 1063 0 R
+/Widths 2711 0 R
+/BaseFont /GAUYBT+NimbusSanL-Bold
+/FontDescriptor 1353 0 R
>> endobj
-1063 0 obj <<
+1353 0 obj <<
/Ascent 722
/CapHeight 722
/Descent -217
-/FontName /FUNHRG+NimbusSanL-Bold
+/FontName /GAUYBT+NimbusSanL-Bold
/ItalicAngle 0
/StemV 141
/XHeight 532
/FontBBox [-173 -307 1003 949]
/Flags 4
/CharSet (/dollar/hyphen/semicolon/C/D/E/F/G/I/L/N/O/R/T/U/Y/a/c/d/e/f/g/h/i/l/m/n/o/p/q/r/s/t/u/w/y)
-/FontFile 1064 0 R
+/FontFile 1354 0 R
>> endobj
-2146 0 obj
+2711 0 obj
[556 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 722 722 667 611 778 0 278 0 0 611 0 722 778 0 0 722 0 611 722 0 0 0 667 0 0 0 0 0 0 0 556 0 556 611 556 333 611 611 278 0 0 278 889 611 611 611 611 389 556 333 611 0 778 0 556 ]
endobj
-1061 0 obj <<
+1351 0 obj <<
/Length1 1166
-/Length2 8686
+/Length2 8911
/Length3 544
-/Length 9500
-/Filter /FlateDecode
->>
-stream
-xÚízUX\[ÖmàÜ¡pww—à.…+ pªp‚— Á58„àN°àîî—
-ìhùgK–nÎì:Ž`7Ð[™ÿ ~Pþ…Yƒ\¼\‚\
-ò[^(>P3wÀâòõù߉ß¡pr,Á®
-{ 9Ø888Üÿ\¿¨¥“£½×¿ÂUÍ@
-òrÿ]ñŸ^üåߨºøêäø—ä[G+'€à?Úyññ¯–ÜAèËlþcFÀ¿ë«:¹‚-@
-ähù·”²ŽN–`Gk€–ëËTšA,ÿ üA[¸A /öüy@/ïþµ·¿y‚,Pçœ,„ƒmk‚[oª$I<XwƸ»ùt®žÝ(xP¢ía¶Ø`»T íJIxr $eɨÛˆU©ÀÁ„Æ‘ÈFó{Ø Jµ±!bã„`Ã*D³ÕŠ¨
-¡!1Lüâè&ŽÿH˜’s íÕ§pJYve@+&=Š­ê„çOvÜÛwQC !/Ë/GVÛŸcÄ¿ <QS°÷ÓB˜l—á° KAUìh˜¼¥W¢6_ã”·a›ÎÎõH¡óúÏ„Ê£¸Öœ™“”ò µvpÝÙ|ùfuW5èœÏ«Èmì¼ÌÒ›ˆj˜·Ù«ÿ¸ØÊl燅ð©·$Ú·ŒM”¼Õ8P!B ¸éXèC•ÔÑtÆ<ÛV¦Ò«³.ŸU¿"ïVtÇåþ´Q«¢ÓeYóŽbÒ¿ÙZƒxS›§ñZ§í\O2~«{E3
-\ßâ»Ü&âéy.ßSÇÊë<c×CÜw*⚤Kø0ݪ¥¾ÀU×”s—¯ÜŒÊr¯Øn g
-èØœvèkwyþÚ‘72çٛ斥‹ÚaGæ¬å`[B×Óà‰ññÓš goø$ÝöeßOáj@³pLñõ[>(™eÔ]Gþm!2¢ë!D
-[D« “-Á'u™¯nòŽ<'Xð"Yeð&­ øc‘#Ñô,åKXÈm®_l™Y¢o׃GÐoR:©‡;Ѧ¯êJ³Š÷ѧ‰mŠoâºë•Bå‚n‚‘7Cj¹sD¼˜<îcØGÌàwÛlÞ—q+Z/½²Í"^Ø|$Go-ÅlêØTåPÛû2oT cÚÝŠùýüÌ yÚô~8!4}"–öj6ä äkÝ8x>9"¡EVj› Y
-˜ñ)l¾ÍkU¾q¥DÚÌå¼S2³òOyÍR¥vHDShÛ!¤ÍÙaæÙþá¿U ¿ë-¿ku§zIúèçÝ ‰ŒPËi‹.7
-‹\÷+í°Zû²Æß5eEmüØyò£ ¿×Sewœ•õ‹k†­bטUÊA-”Šß »,ÎCz7†–#œ$%Ïɶ$¢Å*:ú8¬û¼!Ì·ì«%×ç[âÁÄeÂ[³6æÂîŠî×ÙšÀ³õðù‹Åôm›Ÿi8e>Hg33nlGº®3có€_ê0µihù¡gÊÀäxFnPê¤ëηk,4K§ͯ_MKíkû ß 6ÚÀx.a¾+íÌå”o·gKR™¥ Œ’H!ÚèE=é_–9ºã4? kûŒê‰Z*¬ wøŸOV#•3Ul# 2µÕ¾Aé£ßÚ¿d›K€–¤–g§$ýæªâ'ÚG÷nAüùuÊnûF¼‚›*ñƒ5_ /NŒšrþj{|í lÎC¤r è·Ív¢âr‡"¡þßù¦…µš6#qØFn²‹³9ôgåÉŠEg€+Á öÊL–¡ÀN,@‹%8]è:ÔÊñ»¤>$5o5Ò"“a£ø0ªÃ4v~Ý«¿~õðõ@÷܃3/qviùk'´-âzÞ<öë#n×
-yíó»Ñ€:+ÅIÄA=ÁÅqÇR&…{Åšý ÈÉô\‘Ñ›ll„%Ós@÷j¢¥”¾ì{P¡
-“þ¡•Æí‰÷@@P‡‘»‹©ÝeÓ¸­
-ÜÜŒ”9rƒéÔ˜OÓ[¬™ï!)-oB€û³}‡rñ.ïÞ%¸ÂÙõ@
-º" "†9ûˆÄ«@ŽŠê&z
-§/ÔÂŒV‚¦¢PŠ\Ký`a0Œ¸É0òç?æˆn8Ô&Òm†_Ž'{•ƒ
-ÈxìúYxU‚Äb/Ö[áNŒe­pŠÞŽéPS{Dí÷æØ*÷¤ë½þ[@ìŠô`ŒJ´ÝŒ I¢ömu:¶>ÿC˹@â!±S „Á‚Å5ä!4ˆ •ï¯ÞÄü65ûö£¢M#·Dž^ëgœÒ–óÖp|Ø.õw®òž‚ö§E¨=z¥åÆU²ƒ¬]!áß9Ø)'ª’,4в¨XûrYuPÖJÙ35S1CKX{ûºE†å™ªwïÃ(aÁÛè|êÍ tþ MLªe
-ÕS”Åzo¢É-Ê–¯‘®xg`ùÕ56b]¿¶Ù0-÷9§ä:Э4•/
-‹ÔÈN¨ÆÈ›ÚM„XÉåxÔʈ•xšê®c€‘˜ç$KÁT@üäÛk? ÎT˜þ‹[ìöÀØ”†©´ý²Û7Ç´c¿ÆäâÛê̈GŒŠÈ9ob»ÊŒ¡˜‚üDò÷à-:=N&”b¬Ö,áämŠJ-)¸‡0&Ù{Þ‹zîoHª¿^ûûqN:zá¹HÏâxFbq‡Ô›–wˆ­)ÔµîNØUOíãõ¿ÊwáõAKŒðÉõñL
-ˆ°S‘bð(b¬Ùj›_äá~5BWg<÷7©<Z;‹‰qfvèrBÙW†×KïIl¸)ý1·—$^‰ü“ªND ³(çiºVœV÷ù'±/ö³Æ”ù¸÷¦‰0‘1úµë4/‰[&W£„Xó<ÍÜ áÌzêMë"a
-ú¡ÖMz*xù³Ù™Mœ%˃­ÚUºîC<GëÀ/j °ïÐ’žSäsݹɑ²ò<;/Â& Ü#Í ÐfW8­U†¸ãCWÓV³Êô8½dmÏɭÇ{cÅ®]0­V’/|hÐþX×›fWÐó¢‹×ºö•­‘Î(ª
-!›Ý RŽ_hJK`*twé½Âð!……܇î[ ‹–4  ÚohëðåŽF(]F< Æ©—G©_
-Äê~¢)cGB‹/U¸sP8®mØÇúÒ¢¶`¶Tø`M»"²€œ<Tûh«¤×èÜN%’ŸÆ
-!èµí{8]$W.ú ±ŽRç@¢¨xÀ‰–äð-Aì®°° ˜¶VPPyéëÒ$ò±œpxÚ¯ JÌ‚vÔÀ¢æø“µ$ߣ6ÌK2´ÅŽfPiŒœ™åϪÆG:+-4!8`†©7¬þÀîºNíÑú‘m„~µ5I*0ÿ;¼aƒ°Ü“ÆŒœV:ò³iuxQ‘ÀëéÐ
-ó6-UNy"Œ‹4°™L;ù4±IKpVƒœÀÞ¤ºT ±ØâigÆ%^gÞg¢¹ÃXGÌs§v
-å-òý0òe [¿½Uey Z ŠÜƒ‚¢½šý~Îƹ©Íëw·ï ‡rø;)¶loXë[–ˆ;<ªœ‰¦u†¸,‹#ˆ¯ ±Ê4#Æ–LkžE{èä" Þ{WMÅoão~ªJ(â¼þíÈ?ÙíÛqLºdØmM¢1ö?kæQáo•d‰e ùbÓ
-mUm‡·Ã—ó»@}[ñ½óþw8u"n‰m´ýºß­>?¦ƒé\Wm ázCFàS©þ|í™1ú¦
-(ÿC–MsÕXAr^Ó17êLÙÌžlõ­$/xš®X;õi¢¥=bøŸ1_mb|L½dò¦Üw'>z²ò‹O¼#Ìÿ(€5¸ÒC¬Tpy½’kô:Fd‚yÛ¶±Þ4ÙÏi#¦ôâ^ÑpdѵˆÂú#¬áæË”CbëÁÃ%1“}`5^'\[v¬j ‰vý¿ÆÒ›Û'5\ë±IN"(Û D\ã 4˜Øa.O/;ç÷g™¥XêÄêÜŠ¡šWOWÈVå黤{ýg›ß¢‘ÕR÷w¶¦ô$Ÿ2Így0iƒCif0kgÓm0qÎS.Gp·Â‹' è§ûŒ”nÔ,=&‚,bœ”ËUƒ­üøèpß.Z®¨È À¼®¢O6àøŠÏtó¾I›¿Å˜ÑdGŒW ;VÞ`š#L†ÑšøòtÄ’Ö‰àŹ|Ì’ûÎëžµ¾H°gˆGEŒ²/l“9—w^e ™A]9|LÕX/öU)­;tT#é³/‹ñ«¨ƒ0\Í!ñO¼É|®Îiæ*¿ªV#”±Þ.g)óøá¬]Ú­Å„‹©(üŠý8zËÞ³e”R|6T…HP£l_›UÔbyv˜{²M6öJxEuÕ5½µlŸ!rl‘ĬïD+«<]á¶Z†«×ÇåmT 'j½‘3~jÇxݸç'3Úµ&ÒE…ˆ.š§.ÿ÷| Êu´Jë*‹Ä6·W,
-mCC$³%ɺ¿¾rš³övž]%ØZ™r˜äkЄäªUºN %U+þ÷Š¶[÷þå°GgÍýÉçà¸çaÿ¬Q9®èB€¨¢â&vÚSó
-­s3uÇ…u’Õõ ®]Ãý=rY˜NÊåGÔdÞi<Ô+ßoÆ‚’ôó"hßÇàÀ¿sUòrE© Ñ{zØÞkpO‰(b„ær >_e”iqÎÑ ipemë…¦Ôobæa-Ƹ±.Õ=ò’ó”èÐÅã?0Ábxºœ{ö¥]æÁèo‘êËä¯dŸt
-½Ä»¹MmÎG“¯ä7ñ“Z4š-W!ׂçØù{Öe–”7ÁRš5\ÀÜQ^jRòR©éLYÐ9)˜ÀUnoꃶ:6Јàn!_¾]‹¨'­B xÒƒÅv{FWÚ„3¡jì¨cn$“@¼y\ D,B@nš¬ôÇÈpiÍèïï°FÙ|w‡4D<=Ãa§w&ª
-,;.Q39œŸ£K÷Uʃ™/!Œ
-j6ïàѲËY[M'㣩ëÓ3ëK)ÎdâˆE~=‰ÓÐâZ1ŠY±SÍçw¿
-à¿(žÃÙÁY>P
- Ã{Q”(õ¦ú`í|ª[]˜’·.YMðÉÆ–™“ƒ]ZÜ•[NgN»Ã‹¨×ê-Tt×n9ÑB{^Ù¤â¡?Á’#]ü–KÝcôƒvÖoÚS)ãPß7cï·Ž
-_™v5Ìh­a6ÃŒmäs\mµ1;×Û,¤æ‚pVƒ?Qñ:7i‚ð,yK%Ô‰‚/²Þ4?à'…ÒpV¥ú®”ÊYøÖåw»:/û 0JpaäÒ´øm'v¼ÝŽ[#}é<‚ú$OY°ÒÃ^;W ‹ƒô <
-3M©VÞM` €o³z˜ ™Z`¦›E?É÷c¤«?\ejÆö>îÆø°Ü·M• BöºI@;xl¨Sã0¨ ûŸFTWIƒìg#YNßÙð~+\ @O,¨­ ¦ñåiA7Th¡†QüÅö«a¿8ý ¥Ù¨ó³8Œ±g±ÂC…ì/¿õNìññáß$d×.†”Ó‘µ¡DÅ$!Œ˜%eÜ''¶¢
-ïË»6ä½ã¬#Q2Ï EèÈMmaYEÞêÆ´¼F_wKßûLãqq‡ÿeO-âùgk=þIh®.íéÖ9ûr‹ÕÑÅ)­µ–aJ_Ü’ÁæG&Sb÷~ã‡gŽÝoûé ·ÃAAWQLÆ|C¦Ä,hèÓ×Ê›'jý1ÃʱåwôF5
+/Length 9724
+/Filter /FlateDecode
+>>
+stream
+xÚízU\\kö%‚»înA‚»»;PHî®!x 8 îîîîîÁƒ<$ýý¿ÝÓ·{žæm~Sõp¾o­}ÖÞ{}ûœz)
+U 1Kˆ9Pveá`e
+„8
+l)qøCÀùÏ$AÎ@‹×¦¼Øþî›âöùØ
+¶ü³%K7G6-0ÈÉ ('ù?Á¯ò¿0k +€‡“Ÿ
+qýñ$X8x8þÆiÚ€,ìÀ@—׳ø“‚-ÿ–R
+l±­®¯SiælùOàÚÂÍÙùÕž?èõÞ¿öV ×@O òÊ"ÄB0Ô¶6´ý¡ZŒØƒe’«Wëî·97rŒ=ô7V˜^e»bîÜÛwŸ³$UÇl„+ `•`¡Ã㉥bø<ìøÅ;X°°Ã°`d#‰NYë„”P/駯Øûˆ¢ R¾Kx Ê^P”ÝéÑKL`i„CpHôœTà‰ÉÊò+TŽøñž‚ÏUdíýÕàçG:%Ùmƒ#RPä»géäõQOï±+:°LûÅÑxæÃe]k/͉õJø:'º8ŸlJÛ¬žªGóy乌טòQK6‡ Ñ+íLvþ˜ð‰Å16(ÎñkX„Éßš†+…¨pœº–QÄ´Ôß^î)RêÔ[W,,¨Þ‘õÉ»ãp%n×)iuGYÖǚπñZ¬Õˆv4¹›îµ:®uľõ­«GZýÖ:„<=Ÿ@‡ª˜yÝ—l:GBÎÚOAs½À:rÁUuiw™ª¨,w‘ʽVç±ÌwZ6ç]ºš½žWßÆe ͹„縤h£öÙ8âØYWÑtÔ¸c}ü5æ?°5&Jt”ùËÞ¨—OÉËÛòÁHÌîZ‚pr_‘\OœÅ±„4šß²~òIÝbâí‡y"ûÊ“¬4òŽZ¦¿;‚Àždz™RÑ t[^cíÆ=ðàæ÷Ÿ‘øÜÏ•ä =X}§^ÍóâÓÌ:Ë;}ß %[µ, ýÉЛ>µÞܱ^4AXç%ä#¬wÛ±W:eÅNã¥S¶SÈ“H f÷ÖϦŠKuP ·}.óF!Ö§•"k¯“/ågö«ÉФÁ
+ ê2³Õ°"Ý ÝkÇÃñJ
+¬°PÙÜHyCOÍbñ¶ªß+óN)$Ñd®å]šU$浈—DÚ!΢ê퉆‘´dGGü4Éøp«lУ³LdÒîJ Ò-¹¢TÓÞœl-t=ª²ÃlÌš2iΊÚÞÝÿåOóáQDWX™ ¼ åßSͦ¶ ðå«xÂAÄ¢<ÄQ“IÔ/‚ŸÅe8XW…4XÞO¼ŒiÿÞä]óÓ̇ô+ö`dsaÄÝ´6âÄêÒú6këás‹ƒÉضÇÇ8–²"‹½ö6~r_¢¾;cç˜Oü$µytégÿ¬žñé¼ôˆøy! æ“_;ædx–Vªÿ`©«m%sÝ8Kçïˆ&êîvp§ ïfæZJÛãåªxfÉ°E#ƒb˜&Zazé{_¼ÚH☦τÎ{KÙu¤®€ë™IJSÆÊ=x4ÆŽ: äAºýá£,ñ‹iÃ01bT2l$qm®JþïiÏ`—Õü@;å³v{"•X”IAÖ¼Á~ر*ŠexATöxšÛX'ˆè.m;„E…ÛC·ù¦_ëÔmÆ㱠ݤV¾¨Ñ]V$Ë:\îøCت2™Gƒ»1­– dT4ûp+p˜®s,JÞÆG‹Lúí¢“¨.Ó¸¥-¯¡†“7Ã}‹?ñýˆ²K*Þ@P¿5ðä±Ýçr tWïËßSzy×SìX…»|Û;PRàFá/x˜ìbúðYM¤+#d!&»À¸&æ*I˶ ‘U‘ëQ2ÛañáË5Z#ЛÞöWLAjÔÙ¯é>@“"˜»põ‚Öã;$8¿†²NXæÜG°ìVFPüãï§3‹!ao|n›ôØ\–`Ä9Ù©¦Y"]°Ý1I`¡ØQ²¯ô9WfD$ë%bJ=ÓBM·–Еõ„|}GC¶;%ýkȃ_Â[]Õ¸QJ•)MÓ?¡×(ür ~é9[m;3l }“}Æp%gˤ¿!ríS-Q‡‰<=•]»Å©É¤LˆógψæÌþÍ)j‡Ÿm‹{¢R××ãÑQædÙœNæ<#C=$V㙃gú±rÃÜ+…>ºJäå28´(”ø±ºød•Ø²3/áUFIÏú€.Cw'S»Ռ۠ŽjXPK bæøÃ[HS>õ@‘z¾‡˜„Œ1>ÎYçÑ>ÅÊSÞ³Sh¥£#ʱ¸Ëú;!á· 0/xßydÉPPÜÞ_Àê$…´2¡V]Ò.)„îÅw™é "E2 øNÙ‡cO4 µ[àÖH¡¾ 
+Яªh 0/Dý-å€ÈŒcæ½]‡KºðÂý!¢½ž¿ ÎÐçê!ù‚nÝÇ
+Å øÓhaeÜ1ºÛôȇ>ì0x;J Û”†Ôáz©ò]É”çQÓ
+Ëlå6¹hèÏû©Ü)sýüµéð´ÊçzïüR|Gz”ñEß@«M†!»0µç‘“þ¢Â5Ï;©Ó÷›|3Òáž4!Âð…ßÄo+Õ{w¸Šý\Wá )rtÏŠ“¡÷FŸ¯3]¾ Лù ËŸ’n´3–? ,õŽzíFÞMÎ_6uÑ‘—‰òµRçW¾J
+}­ØüN²îé_ßDЄIxúÆfÛ´Âçš‚óX»ÊT¦
+cú»â«Ì;ìãàc B$æàO|‡féã«îèB¹·öÅÓ¶6›$Xu %áIEœŸ·ºÉò%F
+žP4a€ã¶VØ:!+¤»×¶×î‡ûl ´0j;¥÷oŽâVA[…Îá‰`‘Ú1dËíæ;Õ6áŸïÍ&6ò3ÅŽ Þí·³ÕíëJèþ:g×A6ÉÚ›Ò®œtјûSÓ­&‡£sO1Äõ7d% YIe*sÇ~ö]/ê¬nojÉw«ùèjh~í”®>ŒäXzÖ»Œ¼Q÷R©¬
+)XOAlþ莻ªÇÁCžòšvšÈÊ—\mKéÂáçÞ7Œƒ;vAʼnš„}¢ûŒ–4Yä-ÅŸ³×{#+Hm ~±s8Ì9µp/¾{Ô.Ï9m«ŸÅ%²2궩xWEGÖg=Ñaœ‡ý‘*þ3ì[ã¼"EÉ<˜÷ðê¥pÉJâ‹Zô¹X¤.«‹fÛk V–séGk´#¸ß=ìk×O+n¨A%¶ ¶b§èôÊÆ;Šü$\Ž°èêÂD˜‰Î¸.Jñâ<YÔï€A׌œË¹/?ÒÊÈ« brrG Â­ÐìZêÅæ˜Î92¹sJ3JÞ¿iÅŠ9|Œ@”‡Ê <‰Up‡Eˆ{’`®ÏY•åªØÊ£Œß±7­px|$ÚBg¤”l®¹Ñ…šÏý| !nâKÜQ $?õúŤ&ái²ç£×“4èÚ§´ø†ë|.­8† ׃ò¬WÍÏ,´dUÈJݦ‹04ÞP …M—âåÙ>¬ïFÍ]‘\Jdì?QÞàÒ!—ÇÚó‰
+eªYÜÕ›«<l Í㟮ùÀŸi÷yû\'-f"e¸ÌB‹4UtêïÔ&üú)ÀGML]§Åš¹c™©ÜÜ–e"I3S4››k`ÈçÕþÀaø•ïDáWʸ)ËüÈÐ¥°»&; ­º1­En âÇצWÎW_ŽÉs„¥vƒvžhâן2²g+•Ñ¯ú¢IÌÖ{¸æ®¾Õ©í.׊$9Ã]$ƒD3Icc §Ëþ4žZFW—C™×¯é•Ýƒ¹ÉóD¸_7Ú’ì9›/z¶§ìmZ›ƒñ“¨‘Ð)IOòMq×ð¡Ñ£Œ&Ùñ†*q]O[Å枯ÐÄ£4°Ž4LØO¦šåæm‹Ä
+n²&†°*¼j«€e2x£ŒM}-ZNòCMxOC½…ã¡¡—•¹äå£føæK²2?‚ÀÝo5Ð6CœgÄô,›¤ä’`p%oL¬9l'…•èa¥—4ïõ>Èâƒ[®Tþ{7†¨@×V@õî±9¥ú墑-7!¼çì«=pÕ0:Ý/s¼h 1(šïr’»&Çí4D
+òÊ¢rÈY*caVøõÈ€ØV¤®M'êÞ1V>?®#n>¿ƒñ—þ«ÉÒ£!SÆ€j–©Nj5J6Dä„oÔ¨µ8廿J¨‡Õ+QiÛz¯éØä-³Ö³Uéh±«û
+ÄU¼\4Èòá ÜÞ¯Jý¨»}
+ûIøR1\ÏKÌj‚MM ÔÖ[èÛ ã`R°tžLIþÀbÀrgÎˬ!ÔÆ{qÒrÖðú3<?€<ÓÞ»# tºI¥}Âþu5Pq'žT|Û9<}ù±„K|£ÂZìªB24ý½€·ùž+tEræ¬n¬[t8 šmœc/@=CD˜ùxVúKŒÑ"Õ¥júøý‰Àw j˜Òú¨`Uá›e|©¹…5F:ŠNÈïÁyLŽ»g[âM!2…òÚÞcÊ«˜+6Mx<Ò…ÓñI‚³[x$g¦°ÞŠ¬,³QVûÎëzGË\öí®jÝ«;Ç—“Ío°ˆÄg˶ü,æ0ûD$g7^çZf\‹ÐÛJhÖNžñJY%mÛñ‘”wó8E-7{‹BîRw~_ìZR£ßØu*ò¦§–a ç— ­Ž)
+ʤÕ"57Ié=J ÎüF¦2$hó®4A³¾H+²|Ç”£Ó ë-Ó/ëGÅ?¹¬ÌÏ=£tÀŒ/§¥ô‹RÆb³Æÿׄp1¤|ZÍ&6;CÌ¢ùC/²^úXI=!A]Ñç3ã´Uï/‹H˜-EΰÔ!OÛO˜}-ðùL,¸_`¥Ég­üT’gMtÊì¹8¦ßwb/17 ÷à .ÆHÊ
+E è3‹$-,¶Æ¾+:̆µÔeyø¡úSí™»‰È÷?ÎV›ßõw=€ý$ÿïk~²o™HŸƒIßÙÉŽX`
+‡UžSØ,áµàé|=
+g~nM"up^ÅÃÓíÓêè” ,{!5ÿ8¿UËn
+÷&w?Øú&aÅ/ê?1ê0Öù½úر6é÷&Üþ0†£,Æu;m· uÚä‚úí&º‘ï^C“u"Ëe_(w´#øÕd5J, ;çaÌ3EßÁ,EÕ–¸™zèBeò³ æ:-ÀåøJÜë¥Óbb½¿j‡%Úˆ!í«û0ê®.>h~÷ycLWÜØɱ¢n©.È£sr´nÕVÆöÍZŒˬ‚²ÔÂUŠÀö|¥¿Î¥åÚþ ‹Ç=É7÷N„ V—|¡°ƒw¤¢&닱¿•Èè ñ}¯ö㳂ÌÅïø^ŽOu” Ï™r•‘¿½Lyk¬«P9~gë(ïòZð틆GªDöž;Nþ¬œo™ÍI¥âÉl᧢åЪ!ÔÞ˜ìb‚uh*²Òˆ&úË'cÔns®~Af=çRhÈâ2,š9tX¥Üä]œË1Â&Û'©AX™»ãp …-ζmmˆ¢ðÔýa¨òó=“d£q !³“Nγ
+>Íýøee‘þ„1~ž¹Lèdéק‰˜§òUPG;K‰SH9÷µóO9)ÖÃdøì)Só̇”ùdؾh€vå× ?9kèd¢^—Û1ÊÖ¤Gœ¯¯¢Ö —ü2@vùÈ}˜ÞIæ,h~‰:ߺ$HÖìgù@ÃÔîO¹Óp*@û8¼ÏÙ©zF64¡Ësó"î@­,íþždb©d\‰œ=ãhŸ#§ˆ‘øíÍ-”Un`ÌÔg­ñ3“HR\»q=éí­pȸ¤Šø(âög=:À£³¦Ä'ƒ}ÞXºÝ^ýb©¯-øo¸óÁ‘
+ÌÄŠvu
+˜ȧ„P겄A• ]fv/‚Í–~H;ô„¾u oRùxoù}‰fí0æóÞÕj[+uñêN†Ã¶¤P!%8¼ÿH|›‘]@^Kl!@^) <8›Ž·n|,ÝyŠâOÉ6MýZîzq´:}1üä$?ÃÃJž<Žñ èix±ÿ«]×»+ é´ UÖzNYTm_ ~É­m.7,Db nuM±ŽÂϺaW! Ó‡gÒx 4*Hzé·<Ì04,%ÿ£ëzŠ¦ˆÕÔg”ó¹f÷é8¶Ñéî)¡¸<‚¤ðöù½ã™·t"ú_9ËÙ؉5|ó»9Ä ×Q§XÍþÔn{2θI™ÕŒg$=A.u‰÷›ÚjÁ†û…浉MO´÷ I~b $tdIî~AáB"Ð9ÍÙü97d'ŠÚ >Šªï7¡1 ¹Q\cHj?רQâX!ó¢KÌó= í Cä üë‡]¢U+(}µÌ}‚önB-ý²ä‡¥­pÖã‚–Ÿ8½5üÕ±]‚bɶ[Ò}ûs~3L±Xw’žrº_o=af—'œ=s‹¸à8Fag£Ð|ýæŸÛ†><¦¥ª˜œ:¨¡Ó”¦ iåSât)Ñ °¢$3ÕnÙþŠÞΖú•·_›GJí¤·Ž\ÑÂ¥T§h¯9´KÕª-ŸÝ²»ñu—©Óe¦IùFÆwòÅ'3½=Ê
+™œzŸŠôÍ‚í ÌN†ÊŒ»*ž;+[åñ­ŸB–{Œ~g+bò¡zü*É =x¯Îc9GØý}]e ìq§ZŸµ`)¡µ-MêìÒ¯x5«9Ù©s‡(‰žObõÝ@wk›«`må¹£x!WOŸ§LÐ[óÔ4"–:ëêô—ƒ[°‘»g10Å«š5íÂssÌv³ïÈÌ<S3[‘zÔPE+ é:ûåÁ«JùéüJøc‚u–¹©¦h½”l~þ·œž.â,>œ¤ObŽÐW½E´«iÚ^7êµÈA·ã,»ßô͘O”¥ÍœÓï[§9õÓf¶ô9°åÂ#Ÿ×–6l¦G“š˜Þ1ÊÓdQqÆÞË®sÀ¨„JÉøï}ˆ °Ü,€‘;`aÖ5!€bä¯àbÖl§ÍS*Köì„¢Gµ„ î’Ø̯üLXz¨ÈµÌAí!gßÚF÷¤Iè¢MnÞã?µ-§¹éÏʨNm*°ô²èîˆéE1ô+[çD•½Ì‰Ðö|® 
+ÕÛŸX%`z¼Lõƒ™±î¤Þ1{È‘HÓ#ýEENð=’ôGž»‡.>iîS ®Eò€R‰ÁÞâ–ì–.£aÍIÖÛ^š}²iø/ÕÈ䆪wÅL~4?O¤#V΂öOØ”%';Ãê!“Üd·p²…q!oceZ³sbØàß
+Ðú‡ä9¬PjK¢!zóÙ!ñHaŸ´Þãïÿ¼£êOß,?€úVÐz¾’¢Œ¤ñ¸gTW-Š«XÑèƒðN¨PÊ94X}chAc~‡^ÅûI8Y½-°Ji ¾á.˜<®¯ÇIâšo,¦ÙNì¥#ÊͽÊûÊàùk¤lùnýh2³ÒþÝu<Aíâ$FŒþ¦ÏD!þ:ƒêj%FDõŠ‚QúPÀ„´èÖ#מbG¡³°ï\ùe%mËf›‘g'CÕ䦨 Ñ)Ê$‰‡x`A%*›H«¶#Ì'å;…p‘ûÚ9ß/iÔ¤N…ï#‰yàE×Óz˜8ƒÄÛ¼êpXe€N®Ñ †µ§r%ç˜û7¯¼Çé&ï`Foùª’׬ó›}tW™ë',4Ó‘õÊ™‘8‘À`Z*\-šðú[Ü‚JåÕ®{i!Ux„T û•ˆ¼‘‡ômÙ85û)îÛ¼e¢ý¾KµÔÌ;¨žè{ÜÈ¡¾è{´Ñe¼Žò»~!–±l˜×R¡^n`žTG?ÂŽÎCMž—û[©s¬ ;ZWÀá¤ì`±3iSw-iUÉCW
+ÚVâ>xj„E‹ŒwêIo³}‚üH—ã
+Örú ãkÑnT‚e¿S< ¢x K»«- 1…‹54ËÆa«÷-ÕÜ@ÚUóªîÐsL/}8ÀѶ›Ñl¡ò‰ó9È+ß©O¹È¨qD‹£RKˆ7hëÀûÚë,l³Ž[‹x³#‹³ÆÒ4
+¶ÿÚ®½–ZJS•ñ~´õÓp+S!¨yWC6Æjy.Lä“X5­ ^g˜Â£˜ýÿòƒüÿþŸ°°š9»BÌœí}œ.®ç?þ€‡ü¿
endobj
-1062 0 obj <<
+1352 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 2
/LastChar 151
-/Widths 2147 0 R
-/BaseFont /SYOHHS+NimbusSanL-Regu
-/FontDescriptor 1060 0 R
+/Widths 2712 0 R
+/BaseFont /HNLRUX+NimbusSanL-Regu
+/FontDescriptor 1350 0 R
>> endobj
-1060 0 obj <<
+1350 0 obj <<
/Ascent 712
/CapHeight 712
/Descent -213
-/FontName /SYOHHS+NimbusSanL-Regu
+/FontName /HNLRUX+NimbusSanL-Regu
/ItalicAngle 0
/StemV 85
/XHeight 523
/FontBBox [-174 -285 1001 953]
/Flags 4
-/CharSet (/fi/quoteright/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/five/seven/eight/nine/semicolon/A/B/C/D/E/F/H/I/L/N/O/P/R/S/T/U/W/Y/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/endash/emdash)
-/FontFile 1061 0 R
+/CharSet (/fi/quoteright/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/five/seven/eight/nine/semicolon/A/B/C/D/E/F/G/H/I/L/M/N/O/P/R/S/T/U/W/Y/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/endash/emdash)
+/FontFile 1351 0 R
>> endobj
-2147 0 obj
-[500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 222 333 333 0 0 278 333 278 278 556 556 556 556 0 556 0 556 556 556 0 278 0 0 0 0 0 667 667 722 722 667 611 0 722 278 0 0 556 0 722 778 667 0 722 667 611 722 0 944 0 667 0 0 0 0 0 0 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 556 1000 ]
+2712 0 obj
+[500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 222 333 333 0 0 278 333 278 278 556 556 556 556 0 556 0 556 556 556 0 278 0 0 0 0 0 667 667 722 722 667 611 778 722 278 0 0 556 833 722 778 667 0 722 667 611 722 0 944 0 667 0 0 0 0 0 0 222 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 556 1000 ]
endobj
-1036 0 obj <<
+1310 0 obj <<
/Length1 1624
-/Length2 8579
+/Length2 9769
/Length3 532
-/Length 9445
-/Filter /FlateDecode
->>
-stream
-xÚíwePœë–.Npwkîî îNpo Fº¡iÜ‚ \Ü!Á îî4¸CȽï™3uîüš9¿nÝ®ê®ï]ÏZÏÒw}ÕLôÚ¯¸dl¡Ö E(ÎÅÇÍ+лX{¸k@!ê\²Pg[-kg0à Âdb’ƒ€p0"„ƒÄ† [€<ÈÀÏàÃdÈA]}``{8€U_׃ƒóŸ’?*
-ÿ†‡;bÿÏ80=fë rw¢yâþSæ ø/Ù]]}þ²†þ¥õŸ1€áî g;nL>þ'Ÿ6ð'ßö`&ÏŸaQØA|¼Ëm=\ÿy‚`ˆõÏÌ°=´…Bœ}
-«_5Ücâ->³ß]¶UÙwºHY:Ó@'ÔÏÙ¾¬2·‰pì„òX”àdÆùΨ¯£˜óìlŽèèZ|ø…F3Ö&
-qh<ë/=íq|ÜÞ>“f¾WV “Ž]m(;Íe J[<ÃaÃlœùb\¾¡ æúžè×}#-#ÈÉq©¾çeÏ[9Já¼ù¢_¸ØWaøáÖß
-ié”ç-ÚX'ÕE1xãÕ^r%LSõ)çœ+眛 Ë
-<Hh–~H{ úýÖ¨¿®_#ø{Öq»†ŒRÞ}ËêàáõwuÈ­5/‘ùfXo0º²ÙȨ~qÑÔ2š^¿—•tËLg¶M–-‰—
-K1<›@T¨p\¤’‹¤«oë¤Á‰Ý3´Ž'öä÷6Ƶ"n^Þ#‘µÓ‰4Kל‘(_§.‹Ué¾°PµÏ9iil­\ «|¥Wñ¬=ò7>õÞÇÂ[&Zêy#ƒ0Xæ]&òCO#ÅÛ¤ø²¹2Eí úIlºgÌéÝ·akÃÎÇáòû¥Næ ´ÃöÚ™5ÍËÓV¾“/M,-±çDÇZÛ>Wk˜DCÏ7rRIÝŸ’¬ð1È‹diøÚ¿Sü€Ar%çÎ{*“AèÊôŽÙ.… ®mÏ«Í–ÐW®ýkD -ca¥ˆ:ÚŒás#ñ€îÀpolí›ò¾°ÍDŠNsíò2¸‚Ö#Œe
-·&üÖ!Bë}àBA¨ÛÀΡXÐm|¢]æpvKºXKõ‹•‚Eí3MâɤáÝìdtÉa~´K_\ â4HÎý**iœ·É\Ìe:ŸHÄ6]«W•}]¿­ÑêS%S´w< Ü‹åîOìkkQ^¸ù‹Kû`ïJí¦¼W&MÕ½%)–›D6Bc<\ë¿ï’+8H„
-uŸ1Í‹K
-|TúÁ.øó-x{dœñØZWäû¬eÙ—n¶R^v&ëgD& Ê&>2P&õ£±•_aG*Þëýï°`eNNAU{yßÅi\îÓÇê#‹0xðØï†×c¥•¾\ûõL$ü•ü¦ð·ÒæªØ,ªl'<]ÔLI½à†ž­Ñ¦°¥ú_Ûµtk2aÁŽ§ØÚC~4¶âµm1²¯I+ðí^a ¤Ft(†VP É Ç[è>C×ÿ:_!yà»uµ ÎVfVúôz–ÙÀOX¨{ëµW°{מQcVõª)ÝŠ…?÷dɱ8~EÎHo<O?µÉ1Q›? N7öÙ; ~­Î6Ä“´Õ"ݾ2.A;Á
-ùzòÖ€Ç'éö±i©Ým¼…Vk%ßÕ’·3ÉÄ궋åË+Üt ¢ 'ÙèÚßF¦TÓ'ß{öÛR?SƒÒÚ-búpVûȯ×Ó^D .P?ÎöMF,½Ö—BåIψWcâ·å}eâ²ÔèÙ7lÄŽÓ$•F/
-Wòí\Mߢ[œ¸ò³FŒ$¯áƒc9Iý|Ù—r d ž…C"ÝÛúÎmÌÔϧ>)3'ï÷*Ò]_™¾ÓÄÔ~Ÿ®vx¥ÞòÊ¡
-wøvÄü¸61vø'6çlò=n¡íˆc–¾Å[확;ýQ3Z¦Á„äô™Ò+~Yq"§÷p1_—Ï<!Õí;âæ§né© 6×ÞË!ôÝ*?Ö‚/Ø\ò`r*ËšúÑtØ´Yó&×NŸ·d0êë„«’k{%Ø!£ÖŒ¯ª=~ s‹úŒÍc|Ÿóç}¶wý>.pÔáò[ ¥`«Ë„‰ä9“2Cƒ‘i‡“žÆáWö.—6Æ™ÖE(}Ruã̱«˜10Ë _S0-ÏkH“¢JéG³ÂÌV³ßz/gѺÇ;Öö#ejö¨0Øt5¤^yE½mqÝ(X q(Ú2”*n#œ³tWtV¡èžã`Yõ±Á±º l/W¢Ù©kü:e·´\úö†K+=à7éë¥ý7§B´ÌYUÄØŒbTáœü"¡ o–ãú£ùwh rU ‡¾á%y›?qp©V«?e4¯Ue iPŽ—YFüF$Má…­s¥E>œŸ²G»ˆÏIÝ®6‰"t:Jí¿Sy“]Åá·IߠȼhåiÖ'«šÜÝ_Û¯Abí±šŒbuQç“:)õ
-ýL?ë´êpUn¿TöùVnEÁê?Ø×_¾´pãúâ`(ý”b z@¾‡ínüºSw©õÙ,"ÃeçÝ4b‹x™-R†ÁÊÚî™â “”„üKKëšÄ¶´Ÿ­äü”Fõ.Ÿ1´c~¯U¹¯M]p¤)ûIoΰ2$Z`8+B5®Óµ³ÎJ}ô²?ä\ –³[¢›.ü ¤Æ°Yd¶SêZDh»¹áYºœü€~IÒG>\ {áxÊ/õÉ®[ávÅË/¡‡')Ù®oº«;ùqÄuj 4Ö„bùàgÈ•ÝçOñsÆJŠwí^ùÏõ £†þè©ÿj/(xý¬Úñõôó//]ÈÝÅüæOë~Ó×ʶ•àt`e/ûïè ãûcOû) …WU/“Ñ‚¯Í–Þ´Gù­ÙïÜwTîÏW.¼)ð—«{žÿE4%ŽxôÕ×ñO‰Ö¡ìѱüBú®^?² Ò7Ú‡6i–”“´šü»;ÈÂœ{Ô¯6-®dó7
-DŽãlÀŸ_¶—s@“Mú§„ây¬ödæº/ŠP‡}øe(x¿ÔR^¾ŠÎæ
-5ËéZôO±N>%¨ˆ¹aâôOZ3)€å}íÖN¤§fQrÍ›d²~©d›Ã«°]µmä_—–õo‡öé´6š·§¯t`0ˆ'¬bXšz˜g­âA;Ìƺ‡:ÄŽ/0´ ³’YÍ“Ó^O¬œ.~èÿé“1 m«ð(¦Ìÿ#~+ÿÄ@è…†–1‡¬üþÖZš‡ÑÏMŽc…#ë,…põ «—½ ãQ›q„~ݶDwRÉ­±­ðç}ˆãêЀlqâÂmƒéN¡òºât»ÉÒy•qÝGŽó©6ƒïXd,7DýiF}/JáP*Z°ýƒ[ïÊñåx´NÞl¾d¯÷ÝêèïM‹Í¼:,ýdÅx#µÅøÇ—ÄæÂч7jèÜÛÓáöâ¡Ï˲¬¸x›·wê¾Â'_=Sz<Ï,NîË!É.öš«çY¢¬-j=-¨¦a”%m].'Û¦œ|ó+êçÞ Û!)Žoh\ð(~r£hc*o±q× q+fõ³ïóäÒå62†™·«ª vVij^×Lb‰—'ä¦ÜÌÖR8ˆ
-à–¨ÞÏÙCãr±`Í1º'Þ3©$.GæEHÇçʚʗrhüúŸ·Òb¥éuž!&¨qΉ6öQnªÒ$:ZC}˜i%¹Ê­»ßàÅË]¡;J¤ü¥íÄáÈ¡¥æê?^0ß-±9,ƒÖ?¾oŠ¯*4ë™XÏ¢ÔVúåœó5Ë%`*fÝÓ áõ €¹Jx¬ŸÁ«|ÉÜ-MW¸Æ1–Máù*ȼRé¹!;vúŽËE”¨Km
-ÓD‘ˆy“ìÆæQj})ó½¤dï=¿èèWh£‹q>9Öžc蛫w¿YøIoÇÑÛ>;V;Íúå¥~$»Ï¨AÒIK(¢Û³@Õ0¦Ô£20¸Ê )$çÔ*í> Lª×5z(Ro,ÙõÝ#ÿ}àQàÉçÙÛy\1°Èöºc.FÚËcuÉÎÎý D­P”0Çj XS;ióé,¶hqPÞQ×I®y² Y%Ó&tÅú­;ôþþ ¹„ÙsQdÐ+-\yª×¹L&¯Ÿc݇)ùÈ69ëzTê|øÚÞo–ÖÕwÙY\9C
-¹oú•ÿ™„WÀ ßóÇÓNV]UÅw¥Uf]F}å'Æ ~’Ò›Xœ#Ëçž¾cvB¯W/¤™iÐÂò:Èû°?¥Zï³ÚÜt!r¨±w(P¶¨^á ô Û}3e/¹N \J¡ñ¢ufý\˜‘ãLT(1 „™YÍdãºIé;o¤äú9oÒ>ÒçMªá8rCŒuÁÀ߉DL6¦ëÕŸ¦D¹í[v¿ 8½£ÉICxY'ž%¸)4ãl¤Ã!þ"2J)/E¼4²%º㉜Ɵ1gr P
-×¢<Ð;’A m
-b&c,±í™Ðò´6@ýMãÇlå‚¢Ý+§¤õþŠ´JX)Ò~Ú ®~_òŒ`|µ*ÊOw`à™]ÃtíÓ?³Ý…‰ÎZÖz¾xï¥<QFöè>ÝQøP&_DFáî?¸jÂÎóï¨Ùšø•À„¯çäHËlÅוäÀŸ/¢p«·ýj/
-¿¼I-*-]‚×X![0O²h¾µuí©±°njî¼Ùõˇix6·ÇüvàÁ~ó©O‘Àù‚˜lMT(Ûf™)Ea¡
-«f\‡Ð¦¡$ƒ±È=Ñ3{UvŽyo{VîÏë ù P`üñŒT¶Ve¤âZ­²<§EnÚâ)ÚQû´%¾ ¦¸7ïI¸tƒæ¹H)w)I¿¯r8Ú'‰uŠ‘VäaÊ^äZ¬Øy·ºÉ’ðô`ù³d^z¸)Æ6Â:F´lÙGNŒî;T“Aß<68açÛœ\Í„˜P&-‰*Tù–†‚û9n‰ƒMŠ.Ö _®¾˜ì»[tTç5u|e±ô(z¿‘1­ÄE¤m½9FGyü…Çݲýu %b«º&Ü“k®[“Jf—õvbè,úS0ëò£KvæOìÂT€l,Jc§wyÛezŠJ{ÍG¿+Ö¤²)¹¶Ú¯ã5ßõzÕ~^Ñ™,UËÜíj4¤fÒØÜÔ–Ÿ"^£Î|ÏvDÿpï2®ÀžDrng/ÿ¨F1}ël†±ùÝ/àíÀÈ/þ€%À!yjå—rG?v’ŠÁ÷ão¿1ÎÞVlJq§FÅã®|‰ú^òñ{¾°ì¤&>M†J|)§C'[¸@wÑ„¾»üë’N¨€‘ÇA,‰MÒ[PÊqu RÏëgì N™*>rˆÞÌþs“°Š¶ì×,¹v¸5½âz*¬Çsu€yÂ
-wñÈ6úà ”mÕé²ÂþYTñ0¶ŠŠn˜ÄVûÄ*ª¾“z<ÓËåoœÈ-ÜÌ€9ð®Éü̸˭ojÊÁª&ÁU/ðޭ목;íNˆ"ç}%éÁ´ä}£‹>òΰLžž4^ùÂí°Ä`üÃ\½[s!ªÝÎLð.ó¦ŠÜlµ ò"±Úu
-Ú匓$S¢’ 6CSûT ßé3çDIЩ49VTÑÞê_Eb:ÚÃæšúa,M[a¥1a=“Ûÿ³6]<·1Š\KŒŒjì…¹¯ònð /u Än锊ê&½7Sl x±*#Á ÆxpC‚yC[ >F=ÂT@Dæ©F ¨j`ŒT-Fbj ×t0ÿJ"Ã.c0@mY{PJ 5¤Ì'¶WŠô(æ
-w:©ÿrŠ®­|¢©Â¸¦z$:S÷5ýe!Óné³úÇÈ‚®¥kîciqç`“&"Œ»ñ¯[’¿ +Þ^aæ’W~Þ¸‡ï¼¾L¥ [þ¼RB ¶¸¦ÓP?¸O/Kch™iÆìɶ69eý«Æñ0C¯zÚV»\€3ÓF6F’×PK(Â}<….õñG¢7uª–íöx?Q:¢/³«¡ÝUf7ù0ýÖgß´—-hyŽéT¤ÂpÕ äX´Ùð!Gf“$~°Úù‡A—ñÃ0¦é!Áy[<mÒƒýÇ×?^Dtú¹Pi(‹Å¼¬ŒfB)…iã™Àòfr°.Á}ã4<åòXFj¨ž‰.<P?ó°-—RJF6Žr¤•ææ\’è¬ìÔô51^ßúkÔkÝ ¢ø²ÊáuÑ„ªE¿…û¾ ] +9Z@ÖñííwÍ®¸!Å4¢mee&®PÖªñÙÊ\;ÒAª{Ä-h'æ!z}²¨ª5)äZ呆π$‚~WÏOLŠSá+óÉ'½-±sꨙø˜\I¯m!÷²ïY½’똟“Ù¨*Bqä¡*¯¨ß$7”ïæç]J…î%~ÌNoÖûšÁþ•_6låÅùÝukA³ Ê–‚ŠBûþCñÑß‹?{šØ+/øxõš/c#MÎE ¢ˆ$YN?Œönˆy•»ndvúv¬í´4• à éºñt½~¸õ¦'dFX¼ü8a
-É]g¤ÌÒìÃ<¥)7‚Ñì¦aìnd0² ã‹ï»¡.{tm)«ÿÚ;ðÅû¥™¢ËÀOû&*‘8$nÎ ¢7ï A
-/TÍ®vi6Ð9¸Í>4â|ßï½@G_C )$œôÀÁ¡S霿<+sK…¦–s5KÃóøêÄ寶Pþ}JýHgëeC÷ÁUf2‹ïU ¦(^9g­5Þ’‡®?¯¸ËÎïPrtAFžÕŸþzo…‡“Œ:¾æ$žýf¾ ÙéÝ›S”¦]¾‘õÉŒ·‡¶3­×žÂBR­Ì]þ
-诮ñqÂmdàÔ`7nƒ¨RWºÓE[œ–™Ù6‘9¶?`ƒ=p®ç3Lã,oئDLß÷˜¯ÙTýŽ§Ý¯eW‘öîònQÆ—a)ähF%ö¤5ÙÍqXÒÜâDÍPá±S)ô|ÒÞôÔŽUYïÃÛ›ær¬f~0?rén#º«mH¼Ÿú„Âl#¦u¬…85ˆ#FìEeU§ ¼¹Ô_ k<ÿk¦°ÙbA%R7@"ÿÔ÷»Â2aë}ñó± Í„½![/©¬‡DpÙn/Éo ´=ý!"o×Ï¢ðœoâ}Nó’Ïúýk'´$ó ’;ŠTÅã8æWÌuTš+Èó
-^õ,mÝ>µsªÇÍóQ™“™:…&ÚÞ0Å(ÛHj…`ÌðSòèí$¬=Ý3UÊõú”ûµ̒yæMŸ"¦*lÊKÓã)¯ý¼ð^lØb$vÖˆH 0癥l{<
-ø_Ê'Œ.ÌGöª‹é–Q}é•.t(f2‰ûjéŲ¼[Õ
-§m#dì^Àz#ÎHc3ŒÕA›Þ@4ýÆaù ÃM¸gGs´+l®ºhXÉ¿N5ÙbHË5toï<Ÿ¶¤UxÑ£(½¶§b^j
-Ûó–ÊŠEVÛ*l‘(¯;Ä¢føqOóÊE½WÇçT(ÝkEfAó¼žýÂ
-rW²tˆjêÏé
-¼õ¥¦Ø[?°qI„Kõ⬟5~•)ž¢7StûŒ•_ÑባûŒÒOLû-ˆè•ÕóåÉú¹@¡dÉE’]_VJDù»ýõW……¿].²dt~ˆ˜ˆ ëM„í[z:ð1¼meãðÎW &If° ânË5èŒqJ ùHçq$?HÒàºN÷œ³ÄtÉÕ¶øhÎ=øi2Ó1\‡>ÆQºO€Iep3ó¡5_€lª§~—å6í×ðnþ4à ;h·M±VH½r4­ÊvV & ¯Ž¼ ml߇K€#×?xÇ”³îL3sÆ™¸Ö‹ô¥{Îcj+;ó÷ˆ™¢à#ÃZIü7£aÛG+ˆñøÝÔ›QEíÀ’¢#­ƒ™)­ìÕ¼`¤øÍíø´) ’J±4ŽL_$/Ö.,ÇÑYéácòwjÖlžvÉ[ÓáþhÉðþð‘æó|[×L.6y¾WLMèJÕ€¯ŒþØ;©>âÏ  ‘Y‰è4‚ïÓ+Å·®‚›m=Ø”°YXÓIp}å°ñ YÙ߉ŽqûN<Ëúæ=´ûÔg·>ÚܼŽq9ºT†¸ÃèGSyçm÷p0ðÞû[  ‡s‰³3 Éî%ø¥/ÝðúµnAi•wÖ,[é5SõˆcÜÕ°Öº×èÏÕÇFÍ,Œ;nòAï-´´€Ä߬ug¬À!ˆ <*’Ïã´ñ—Ü›£D•îÔO/ý-?*¹Ww×%sUc‚ö6a u¤´ƒ·¶ªVq«ù|4F;2¤¬«šßh1Î2éj˜ô÷8æºÚÀ¤¨Ä•½š:q‘— 8roBÎJìÞÉK<<æÓ?6tð4)=Oö¹nÝ úy33ç4ç«"s_ʯrXZœ´¿":¿y€Ø`eóúþèÇi™f*õÀdP[S Ú^D$24³ªSpÙçr«u +¯X£ð\½àá)™—Úùìû.¹ò‰¬vY·S‹È¸w´þÓÄœŸ£ãì/âìœb†Î#aÂ]ôG1ë-ñÒ8;iµ¡ø LÃ,c¥&]#¨£V¥¨wʈտ™f_ŒWi—²]Šã—â¬3—ÄGBßèòQB]Pö½!FUßs³Ó¨ú­™¼‘JÂÀFGíÂ
-†Þ[ÕñºòŽABjÙhaLMô\¸©·UÇ2lucJQ¹ô@!5@ç;*>ƒìïâ _\Hñà‹Ea{¢ê’7ÎV[ˆso'Ƈ.–¼{èãrœÇ<˜Ê¢©5û&/gý©~ò†…p´F7Û,‹™éÞ& ƒ–PvZœÆé<ÙX<Ç~ÚñDRx›±Î°mé¿,œÏxIÀBµüïgE/Hý£öÓçVB[1úüû¼×+,(ëÈj‘õ8¶DšÈ1éV%á*>ºÑÌÏ-ÉbW®V§…* ßcoÃÉ«Šx›B¶>GžÀ>­š-QFÜHÑÃâ•°8ð8—ÿTO¼VJ›Jfo!ŠËKÌ4,pB@<ɵŒhÛ*ô¬W¤ˆ¿™Ù³[¯6€œÚ§óªE:§…¼L¤åê•B¼¦aíe®7·víÀe™4U8Žm]èÝÜA±ÁYažr}‰Í#1ã™Ûµ*j”ÿ ÑŒáè+àu–L _#Ƶö»Ìñ˜S}­—qmm(›1öÑà kªuÊ}$ìL„_hH÷,½ÔtÚšw½álœADöâ‹Ctkôq¶ÁîV1)Òö" Ô»gFbØ_ p(xÿ—ÌÿOðÿ3ƒC]€0'Ìÿ
+/Length 10632
+/Filter /FlateDecode
+>>
+stream
+xÚíveP\í–.î xÒ¸»;ww4t5Æ5¸Á=×àÜÝ‚»k°>äûî™3uîüš9¿nÝ]Õ»ö»žµž¥ïª¦£ÒÐf“A-ÀrPG;§0@ â`áê¢
+uTa{µ©[ØC
+ÈÉú¬áðŒ=“i@]`.–Î'àÙ«†ŒÜßqÂl€°?¾] Ï0
+ÃÕâhýÏXÎ`k 3ÈìâòLóÌý§:ÿÌð_²:9Ù{þe ýKë?c€À\ÀöVì\ÜÏ>-aϾ­!Ž†EÑÑ
+
+àâü[ruúævþ«@Œf†é9 êhï
+ktòó* íþ)áëB¥æ÷•!ìµcÂMž3‡NÛJÌ;/íÚ“À'¹¾4Lyø+ô-,;¦…Ø©GúÑÞ§ßUÖŒø9õv6F4µL îQ(ÇZxœÑN¯™hÜòi¯œpü,“¿Æ}ë…{Qõùðˆ>aÿúŠ¡g°¿¯·ý¹s›œ%+NÄ ›>*à]¹„‘n©w­¸ìà0>¦I‚Ôõ’7¶_„›üë%^ÍœKüÉâWöIñ‘ë¨âx&CêŒm
+ä¿àh×ñ€F3>ÒaáÓ®GÀÇíí3IúYbɘ¨•šâÓ,&ÿ$ˆ)66ï7¿ï†%ër¾Ê_îoj_Yüíl§¾v‹w'J‘ñwÛàÎ}¾ÇÁú„l±•÷êµÂœé7ƧøêjܪŸl±Óä½
+™ç
+™zçFˆoxDÔŠ
+’ÆýŸ ò¸K`º•ü~O3¶Û•Äd2.›ïÈ"oÓª›+sÅ¡9&˜qèLÄä÷,Ä”U´Æ—ÀÃâÂ.©éÔ–ÉâEƒ€"~ j´ xÙ
+ÛrɱÐ×_[Ú)±£öô-bݸ= ñÍ —öˆÞXi†šÄʨ}— )Y§(ŽRìº0U²Î<©¨m.[*ÓÖ)EûšÆŽG±W_óâšîÅœ^sÆ•U*âCw-ib|Lñl±œt‚z•ìqz«ç£©•´:lÿ#Xæb¿ÈîmÍ«akÔÊÆ¥is¯Iq8?#33¬YÁ±æ–Ö
+U£p¨íùz槗÷7§DË\Ô2éª^ €4¹œ¢Ë0i΃@©”NtiôV øÑ-{î- ^ÒßúCŠQRæ—?S„›P·Öh ÷DUÅ•ôm| m«QR¬Û|Œ¾ÄCún§¯yè…Å>p>7ðÝÀoì#O!ÿë˜V©Ã¥ ÉBMb˹ ëgj„“ñ¹ü·]Ìį?y¿ZìtpKqtŸáçí¨84Îd‹Syþ¾¬Ÿtv­´‰ß®U—^òȧò ²®4-íÌ’ÏŸDáYÜ›wöjt¿Âî}Ä{µóÉŸü^9ƒ›‚'¦Ežbõè>ÝL»âï¹8j¯(¸¿Ò10#·ŸÞy¨”¯_Q˜qÊýªRM­¶#_ì<Ð'Þ:^ìö³¾#ý½¨¡&QZz±ÆÓnš
+0L_ÅÈ™a攣×w¾js¾ƒ¯kc‰ÓoÌòAoÔH”¾•Ým<ìè·WpÔ Ç>£E/óMæ¨
+¢Ãü)Ä‘‹™”!‚¬QMžZVçü£ÅÙ?f t˯f'+jÉ 2& Ÿí¬1~»3Ù]*¦eæPˆÁÃ
+´(®×áú7¾õu³°XDsÎФ-ßæ ‚ä< ]¤UO_CÑ÷ßC}Þ„©Õ7ã«$³$~©T)*üſתŒ?p3Q©}ÇéÉ“h†Ì ?‡'²½KµƒgòëÎA¸t,´ïG—½Æ2ÕqJv¶"ùÄÓ/$zÀ¨Âo>Óxùå„?æe“`µl˜&eo^äkbMšn«Ä6-ý…ù.Ìúo$KÅž =_Í@Ÿq¿úܳ}ïð¾) î†QZ}GN޾Ȁ"Ÿ× k¾Åš{7&H¢ñ©5ÞbTü®ãÔw6”ˆø×g¬F¼×ØNF´b¸ú ¢L¥p1–Eñ‹
+[=@{TÌÏ à¹ä„á£úVBØW
+e?«ïÀï9Ìüï†LßÓ;Rñ÷†yá ZEåÍ´% ¢ ÕÚeªÄ&Ù—dwàšÂ#ºŸ1X*Bè$XË5Qt*Ñ"ŽNÙ²”äÞÆx©º…”éÙ)Ÿà7,5Í<²wážÿð€¿($ò/ öý²ÉG
+©^0?J¹Þ%S0F½¹a[A3ª_NáÒŸ5VÿBÏ~
+þm!u‚±Ý.óû<¥X¸L-åÀ£~Næ;9äWh·¤ý/"Ù+‹bˆJú;ò®Ùf—ùMØÅÆ©ƒ’™Š”µÔ›ãÂYO±"X{6´¸8ÑO YÊd–`+…þµQ¦ÞáÍ–éŒÕae±ÁwmÚÉlSäæøFBîÕÛ‘GšR™Áëxù¯Ÿ<ýö‡é/ûR#¶*w ©"/@€P+JcÞ‹¯_¨L$¿mìS ©—áV瘛hòÈüÀÊ[†;{Øå\I±Ú>k¸ŸÍ6ò®LèWhÊÛ§d¨n%ôÛB%ÎK÷7­8äÇ© )ˆ¹S‘£ª/OjÛœSNÕ[7’•ªq®÷ç„ñ'Æ °88<ÉŽê Æóß>q`™“a Î*($}RÚTžPÐio £·f›oa?ÖxXž“`gôß%î;P»®ùÜ°R>)5Ë5)ÀÚPoX`¢ø`*7…ÛÄ»'´«®5ùÇ+Öúuïno¬ﮟ9`Ó<´»ÐÜëOÌÄpâ’ÞÀæO!&vœÝTéR~býî¤á’ŠWQ|Œ\!EÐ:¸ çB«eV>*EÔOþÂÁs º
+µ‚ˆVžÍ¼Jæs=Q‹•]28m*~)„2…ß<òY§ó‘˜
+D츜£/3à¹LÜZ‚(1±»wéµM ÓyKMØjY,XpjuG£äŠ3UMx9½gèOl´zÛ~‰ïß4û/}è´÷tUj»^É0Ô.½¤ÄÍ6fø¨·ÏÇ´ÉöH¯ƒÔ³˜-«Eƒµ™6y]Î(.öˆCŒú›
+þbXïýÖî——UçN âô7&#ú³yź)¤µ¤*›= A+Õ/µwªY|§î«Itô^¨œÞýøŠ kc!@Ìâ×Îoé–TÐÂKª¦ÅY&ÉŒåʹÃI
+“Z#ω,VÚ(œ”MÕÛ‚apa®šR虶¡#ÖqW3¹©aþHï«Û‹P>koQÙYvÓ}y»´7ˆP%¤o&Ê5ëÉFpJX¿šG™sÈè’ºñÑ Ìã‹AøÖzŽcøáC ô5slì‹vRuÆê=|aOLÙ!ePÇyL­Ÿ< ïíïaàŠ)æ¥:K,…_îãþ+t2†:Šu’&½ïë‰ÚxÀCÒÄüTœîS$°#géDèxúl+ÍãÌÍqä]‡çÏsº÷=5¸Ù³˜–ŸÎÕ{À¥pYqBx;µ Dj/YØ—ý–3¿¯&„¬¥d±ìTâ”qÙ+W{|°[TNôƒñ—SÿP¶§Äh™ïE?ÐC–Êt#½l
+Ëc$9h
+XGô.£Œ1Õ“MáX<´¼¢y¢ѽâ ÞÃÐÓò™wN7¾·ªûTÂW¤ .Î/ Dxh!Öw·%ãTÜHævŒMië„»t*‰‡Šm-õ'œ¨²Exz/s…‘e³Œ£ë›'>À&­.`Å:¡Äíy¶*9Âï¼s*q$x°ë®L˜L}ÍÏ3û„ýÆæ—Âo¼–N#Õ¨åc¸ „iÞY·S÷¡#ÕÎt@
+æ@à§ÃÍ[tW a¦Oc³%r"|”É åoxªn‡8àÅ•Ô6úÞwuÉ^ oG„$®Ðè{9³IÈêÊ£¦9]ÏÛ/FVÊ,‡2§Kv¥mLA†Ü`£ùvÒÞä«ß>ìÌTF”‡OhÏ‹#¬É}D¡j«Ä>ÔwLæEUý•œSm×òm Õ˜_©C=D4É"Û†,QVJ;2IÖ 'ËÆ°jW?EçÆpë«iœŸëÔÊ(ŒlÉ—km?\æ ]«ü+ô»¯òOõRÑÜhImV‚ÜÖvÞžÓJ–¬«i†˜’®ü9~.Åò?AEWðZQ†ú2Šo]’˧Ž¦¯F$PEy¸>¦ëD’à€q’_Ï•o[¤KƒægK+Óq¥õ{MÁŸÚyª¡WÎT°ÞW
+ÛÚy—ÚnvI]Íd¤L%úk(““¬Àj@bÙñó0µ§ÕŠ)'ýÇŒ³Rf•±åE*Ýç-å®}€)W ùR Wôœj»•ð±Cÿð81fôêôq®úø×'DÎßÃîÓ.©Â¹U´ûÅKmM™úŒÜÒ¹d¬âyd”„è™Y~¿ôÊ@=/jÉR½è¥ö.5SØGäšl‡e‘ÓŒm
+ÈOâÙ~Ù'V«™S0‡xÓ™8C‰œ†d£Çýsûž"¯¸±]¸ê´î>œ³æÐ|ñ‡™
+Jünqèèרô§Ty½šƒÊ¿¥I·Aq—õá‹Z%9?)¥§üŠp¢#^lÌáŒðÖ„„I’³ÑÉ!´ðKˆ«åWü–¾UÇCÛ¹†’º‹×®z*®éhíç&îÝÔˆ¦ÒpXNƒéÁc¾ù."”ôÃmPU›AJÒàäÝ
+Uf’å¤<k}Ì 8’„›åy1eª«‡¤7óÈu’p¬®¥s(OeTh—{ÀbÿýßS.…ˆKÞ”PJ=ËjgóÜê-Ô_h®*!Ô†—óXÒûìfÈ“7æÂ4{í]ùÉÚÒ‚oyâߟ0EY.Fœ ÍKŠô@ LUOŠi^w/Üê7¼C(˜ÞÚ÷‰éƒÛ~õ¨ºØØÕÔë’K‚qbHØÔX˜‡+…Ù¹=€ž£Zgk·„¹ž³gú²¹ÕpW-;ÏùzƒÎñ7°eO›âðy~⢾ï´m*Œê30V.o ¼/ƒ«ëŒF¨±L¡Ø65<_w¦âchĨGN Œ}tƒ®ÛzIXÈŽ«‡ü¦³ÅƒP†P^è2Õ(È—ÖÖL:u¹6—qéÍq‘Æ”7œ·Ö“íû“¢Œ—oŽ£å†më/û6ª9r~¼xtM—ÙlЮƳ ¤Ë4¯†‹30ËI(o³ÔIäÈ@¶Ô„Î<©´U'T9Eí”㦷™{²ÿ|Ð\¢ˆ÷4ÊNó> ÏÒê(HvÏÆ-nÂíÌìä`Þ0DEâÌ
+ð¥ªT Žºù&¡‰àëvHìÅÎø—â—¨|2#‹ÈûjàÍ­~ v ]_¤sË–¸÷£dLý¶‰¬óªl?@7~ÕìÁf/Ôý]ŒéB¾ˆúT-êS“H¾Zª[Ã,›ìÁD#wÛL­øÍ”PÀ68I…ûs—t5\œB¦Ïq G)fŠ…î ÇÂŒ}”ðª4,m¶Ï]ÍŒš£±éŽ@·Ç"4BËý˜ïÎ÷oŸ¿ˆ9uK…é‚V¨‹Q2dY’㇠•oÐXë\\ÁT7ôéL§ æ“Å=„«ßKì»×…ãåÞB^¼ïñ:e:ºûA¾ºÖˆ…Ø×%YäÜ´évJ÷\«æØYûùJV},6>Þšv½øÈÏi÷°6™’^¸OøM–!kÚ^Ù»<l‚'ƒvØCÜZ{óâË!3’î‚UDpì廚ŽgŒ}ÞLªzî…’b_V©ò-DÔ7™h~úÐcÅn»aV¼þŠäãôî´­Ô8Të/Añ^»»£öQÁ*I9ŒëMö|±s£[CËÈP¿Üù†«Ëeõ+tÐÍ ^‹$¾qobC!,cˆqÕÇ_ÎÌuMÔÌß`ÒÔ0Ù˜ú¦BÃညàŸJ}!éGs19lÏñ»Ö—³˜ZéGÓ*HËH"$o—¿Ub-;¶e;žÑœôGé?Õ¥AÉP§ãè}/¸½B °}¬<‰6Çz«ë=ƒS`ü¤4#\žÀÁhRoÜ;½¡ó”sTocíLÀä¤MøX÷ÓÃQ‰
+½å>V·.—
+ÒÜîªQè]‹*ðåVäIw8¶ñÂi›M‰œÌ¿$a| ÙòȱV¼ó i×6\…¼“Dýð¹¢\ý£¡J©ÔK•¹¡áXl¥ÝöVƒoÓÞ$âbÌegž#ñò¢ïF’pÌ ¯Úè‰Ñ^rÅ
+¥›S+YÊ;Ūìâ?¬_§IÅ>Ø7!ÒÇÏ£ûQ
+aÑF"$²¯Ö­|3ß!i#ÌT<ÆK[tô p;w»Ô.Š[°
+ £M~Ñg<ÇÿšâNÜ~¬Š$’
+œ\7±?·-ï¿ý÷¥“ MEo,ÖA„&±}â÷ÂE¥§Þ[:Ö¢•P’º‹qݼ¡©Ù¾u¾1b’0W—¦‡WG&Ù¼2ª¡t7· ,Îĸ—Áw¾Î”…uÑÎŽÕý9f8xºH]*ùY=ŤÔ\">_xÞä¾dB²a×/Ë—œ{íÓ›ã¾p‹Ä#åN³Œ„„×ÙZ¿5ð
+‹¢T4ƒ %ŠÑÔfj ÂÅ4L7¹ág¿«“qàïÖÈ@¨DDF‰šO`„®vÓ(…dE^€É0Þ±½ß­O{_õÌ¢„Îú‡Rô¤ê quâat¼ÉXe²Ì¾ÎKä£^´¹î¯é,’Ôªy–„ø<œ§c9\`9[B½‹º‰¬ÍDªc£ø,̅ò=åÃÄ3ª"&‚Œ™ž :XKdÓNBl|ÂX y‘|$F¿¼EcL;×Sü¾g*›EHç8’‰¾óűŸôûNYµ]¿FiS_q³;¾‚AiœôÂÑÅúÈÝÃNÞ‹Üwæ¬J¯@Ï“¡–ËG±M· 3% ÍÀ·°XÄ óv¦18+M“wÉâý÷8K‡ó–ŒÀ:ÉÉ/Œ-y$"£âµ°S]{:‘)EÜYíkN
+Ä¢ƒ7Ó*e¿§Ô¥Ä‚¦o‚¶n»éPà:m;Zd%«xc¥Nâ™aÔŸ?¥=€ýZuxçY+¤ó^¡Supã}ÏC£Õ,ô\r”xW)<çK qm’E+Ëç‘‘DÂó_ïŸÃñÆ@V7³îÒ³3›”a¤)dÚ?·Ý‰@xäÄÀc”´Ï0̓ºÏó"óâ½û™µrJóòZ˜JÅ›=2Ónñgkù"áz@éóa⵬å½µ?ÝæöP¤!}•-ҾфýG¨ÈVËs­Rñ²aTRïäËâ‚k\Ãb¿U¶.ÁãgößvQ¼h-aó•âœrfAÞ€ÊUÁèDZ$ù('€»¯LM£/hj¸ÒRöâfòg ¶ËŽ§ÝÞ»'ûêºn ³XÍw‡W×6>y~ëF—Æ”§üŽÓúÝ—HÒN•Ûë{Bk}ÒLþo†ô&‰¨¶ßgÎ~Á¼Ù„¨;¥rÁΑ½‚ãi?:±{Êc<ű26ÏÞSˆS¯ÉIy¸z/´Oœ*kYi‰ÙË6lRºQÜqà
+8¾÷z³ž“pTÞC»e1—´}FyèAò%Ó¼&Té³ ÌPæsî'éÄÕH]†ÌBøÓõöa"unáQaÝ,«N”:FÝÑû£i'Ñ£1»Ö[¤$ëêj€þFuÙ¡dò–MÏ~Ÿõ½bœ¶¹k½žØMƒGµ*‰ÃG”0õé ™ØЀBBVÅBZ_Âë /y LæBÀkˆß–œ2}Â)<ª2{2nUb^=èΗx¨oDÒš6ž_›ÊXÒÙÜêÚÐ×x¢–ÌnM¢É'¦WÍäŽî$ 9Jœ )o¥ÇH—ð“ q\£ÍÃ/Ïîí3
+†µËÏú蟥çf³ÖõÄ›M÷|!¶g#=êŒ.wtCìz¶u¥'}ò°˜_¦*›­PtÜaŽw’ëöR\v^ èTª(Õ:¢_ àT·Q¥´æd…úê’ƒŽCð×F³î>{ÄÉúÌÕ‰&Ž]bÑØ›Ë+jžÅýr¨gt2fÄêÚ+ÏÞ›í–j_€âY^
+ë1£äª .WÁPxjSÞI#Üʪ֊ çtûuiš!Çî½ÝSo·×íÓ8€+zqõSÈ¡,È!ë*T¶CÌ]ˆX­9v]&8S/¤ê`諺aÄcmHê–ELL.&Í·c_ƒ²ÍçˆSÈ<:~¦¹OÅ;E¥5Íq˜ÙŽà¶?ñv— nŽÓŽQ|oyèNÕïo磞YHºÜÈ÷”L¨·½ÛìC$?Màc¡"ÇN7ÎâbLnÙq:
+§¬ì:9§ËY×ûM¹6­È"Ù~ÝßïJ™uz¢ƒÏCz ©aÞÉ!âÚª8µs¨•<Ä× Òð쳯†²Å³XcÄ*3å²›Ëj†Gˆ4£j2Æ÷Q@\}’Tyž¸¢i¼á8t‚ê·ý†ó`gh‡M£ïBD¸ëÙ›0Âp^*•-ºkjÚ·Z»æãÜd¨ ÅüîÇ&n»$q‡˜,[ijK„½½­%¡“îe6eS. âú˜ˆfÄ®ý>e¾î–â ¹¶« ŠØ£>;–¢‚/MòI”¡øi1-ƒ
+¯‹3ÿ²]inÁàÞËDÒ>{ÓЈ dx—v³©lò9 ‰N‰+¶¦zöÍñÔ#é)ó\M£[s@Z›ÉR'õRÇ}ËAÕNQ¹IuÒ.8þÌÀˆ‚;a?ú“‡ö8ζÜ8ùx ÐxoAy橵"wðõçÆÛƒã)ï¼àì…ŒÞ Ί@ÌcKÚ_Ù¼Z‚{+ˆ•\£\hr‹v·ñjÉæǸ((%Õn¹ð· V•BòÃ{9y¦gN°œ fµv*Ûï›s**o™^þ(Ú‘r)`lV3°ð‘öTÇãèή hYmš´0”ÚÊ÷8K¯6ù€›§vóÉy“Æ 7D倷»ò§1 \eÌ}¯ø§5ˆòþ[%fvÄÕ'œbÛ©ö¦&©"ò­ƒõ4ìË*Ã5[Dô`1käý¶Õ•Ï ê`•rM<4{áôUC÷­øwݲðãT5cï¨ûët©„U0í ¶»©kµG#G”Ä~}±yôd¹üÄI!ß©¬ÐGÀEîn‡NOí¬PË$‰šÍµÃ‡WgÞú©é!q@¥{ß®ê7ö$¹UÔî¸ò¡Pšè¾Ð›ÍA©a•bg¿fD(s ¥ùv®gZÙZP€=NÕòä9èÕ&çýw…$H›Àì×Eg—ó¹-}>LÁ•Ó¦4üF¸pâX•*À¢„ƒ0¸LM­+ª[‹Àãco®OóbÖŽÓ% Hé.. Ê X;éôN~'R‘`&‹¤­óH–$Ѹ½¤[*¶–›< ZG„‹m8Blà ‚`•‰
+& ùf¾±<£>W†2<퀔ã*õˆ¦¸ïÞºÑbï)£(]|Ͳ7.ÅBêOo_™íí—I>Ĺ=à[väÍ$ø¸ºBÎk[œ y¸;ª$Ô¶VÔ¶¨ì+Qý †$·fø‰AÙu­õ€•ô퇚|ÄS)¬ß©ãb
+ÞëÇáØ(>§"´Ô?"¸ÔvÂj“øÓ‹©OïDkº§«wèKêfhÔu­ÐàÕ–®L~vsÜLðw~ùŽø›f÷ÀGY¯y²™)¿ÓbOú©ogɺeÁ]ñ¡—êÅÇêá0 ·H—c<ØÔrZ :ÁÀ]>Ùã‚!ååÅÈؤüð¹‘c›€ù«ð#®QÆÂùOsYŽ\$yÓ&ˆ³±Ò„} ÏK÷ØÈó¢ä(ä&&¶¬SÊŠ¡ÊÛË4öË(d®NÏpT¸ #;®±õæü_>ÿŸàÿ K{0Ðu
endobj
-1037 0 obj <<
+1311 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 35
/LastChar 122
-/Widths 2148 0 R
-/BaseFont /VVVFYL+NimbusMonL-BoldObli
-/FontDescriptor 1035 0 R
+/Widths 2713 0 R
+/BaseFont /PUDZPM+NimbusMonL-BoldObli
+/FontDescriptor 1309 0 R
>> endobj
-1035 0 obj <<
+1309 0 obj <<
/Ascent 624
/CapHeight 552
/Descent -126
-/FontName /VVVFYL+NimbusMonL-BoldObli
+/FontName /PUDZPM+NimbusMonL-BoldObli
/ItalicAngle -12
/StemV 103
/XHeight 439
/FontBBox [-61 -278 840 871]
/Flags 4
-/CharSet (/numbersign/hyphen/period/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/r/s/t/u/v/w/x/y/z)
-/FontFile 1036 0 R
+/CharSet (/numbersign/hyphen/period/slash/A/C/D/I/P/R/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/r/s/t/u/v/w/x/y/z)
+/FontFile 1310 0 R
>> endobj
-2148 0 obj
-[600 0 0 0 0 0 0 0 0 0 600 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 ]
+2713 0 obj
+[600 0 0 0 0 0 0 0 0 0 600 600 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 0 600 600 0 0 0 0 600 0 0 0 0 0 0 600 0 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 ]
endobj
-1028 0 obj <<
+1302 0 obj <<
/Length1 1630
-/Length2 10814
+/Length2 10888
/Length3 532
-/Length 11687
-/Filter /FlateDecode
->>
-stream
-xÚíteT\ë–-w‚-Ü ®ÁÝ-h h…KáîîÜ¡p'H ¸;—àÜýqÎíîÛã¾þÕÝ¿Þx5Æ®±¿5ךKæÚ5¹Š:³¨©1PÊÎÌÌÆÂÊPÙ;;)ÚÙ*0«Í•­A€7€ ™šZÜhÙÙJü
-  ­`fç°þÇ`bgk
-ú«5'–7.Q'€ÀÉhz º™
-k°ºÜ¬š;£ªj_!Oð$ã­Žˆ§·ô~”.ù~8T7öè>&)u±¸m˜ PX5‡G4‰û·7´½Cý}çp]ÛDŒÙ±HÔ.°h4‘~ÙDºåžáŒ[ïjwÈbºr¸°ÌN¤î“ƒðÆüSgÊrUm4>_pû´e{eÊóÀ@’ªí!B¾^gYâ¶fˆ^FT{ônRçz[âœ5Zóì3ŠìŒ—*J–>#
-sÁx§¼*o.á_g}wýœñl^îkÝŠÔ'Ø’(Mô{Ä'’WuçÙ>`·pòdèŸoR[ÌÒö! íë&XôÕFZü¦½ê>ì%Ü}g·û[˽æb6J¸uq ÖDP»}"ßžo«/2åKžxÊ$©ü&Ú6|I²k¢QᲪÖÒß(Fà"A=PÎ2íܘ??ý@²å·‡•Hki–óº‚i¦
-Û#Ò¾ç‚u¨Öåºp³àž\¢4hS ©–Eéf< ¢sj`ß®›ÌFpï(üÊæú|k-è=‹ãEâï°ü‹üTvalÝ´X\0X¿Ù¦?˜|ew…­K£KòÉäÃïÚجäÊŠíŒ]Ý: %¢˜~¡¨ç7GÊÎÉÃÄ} .Íâ<!˜ !†As¥»˜ö”ÌÔš(;¯3á‘7ÅÆÊ0]²Q|Â^ÿg×C´U´raáfùgzfÊeÑE=n«d?8!j¨¤WR-å…D¡œÊ¯mh$¦œa—C½Þæþ©ƒ®Cä¶wk!FËèIØßaNó4dý6x^z/ë„:Ž ºøÒÈQgæAÊN6æ ž›pP¬Š?¼û‰DÜÄÐ9Ó,4(E#´Íô;Õð¬ŸIaê‚«{Š‰ÏU–¦/ƒH»9ì’Újà(XW†ôí¦Ëø­Œ¶ù¸ä»Ü_Cþ[uë†LFq ­Æ!ü
-[ù^®bÓ7£‘“Äh'–y¥QT¼æ ÇÄÏy±a£üNåM ¾¦‰ÀUOE_Û±Õ©Ù÷œDS±&(Y¡ô{iàÇ¢r_žv¤Ñ«8¤Ab1è±M-„ïÞHHºrßÀb¿Oæ[‹h×èiy¯øÉƤ¢¶­„':çÄE·tzUÿbË–È.ØÖ;̶€ƒ¡</­DuR‘ZoOdNÔjFÂi/_ZŽ 2f€ÕõAц‡($k}ÍåcTsí1R»°$ˈR÷k»=ÍÈ~€íãÙ3¦èýÅ;ÂÝ'ÁP¦µ ƒ·ù]DS°3Ýø¢$;è›<£…!sÂÁé,ìÚ t4aê\D.ÐÒ/Ýöƒá4$ÌrQàK,T†õ˜zv"ÓÕ3(²Ö«ñ}Ìsjnv4ÛÏ÷†NÙPJý‡ÆT+Ëç@f4eËâ¹×pƒÏ˜—yUz„P•Í=ðˆñÚ
-5ú\¾“8¡E8¢ž/›ÿš{¡ ç³cƽžÃ ­þ©mÀeô¤]§¸ýÏTn)ª¥3½Ù¬Y gÁQ hñ}7Ú_»U;ü‚ h@Øùû3Â)Y#+³RÌ \pgùGÝq÷pÜAiµßBwànÊfµ„FGjœJnBáð걌¿YâYQì Wqò0ƒ¿ÉA–®îUH&@O ¾UÒé“̾„ï”®¦¤ö¨b×SHôôò¸Q™°‹É•è‰G|)¹½žqt绦_jF7øÝ¡Ôš×Ïi¨£ÿÉ@HRòÎjûioÎI­ÍëÖÄ°2…tZg¦¶à]Qˆ¢¦ž:µ.;›#ôªßt0±ÎlÌ{ÏàQüÛvü«¥´®å€
-ª/ªœ{Äøø>º$ÉvŽÏÊ~{ÞÏ>ÐQµßS°Ââ¡v»Út`{æÙ°¨ï•›( wJÝ$ÒTùœÖ’F™yˆç·é›Öõ¸ÇÐv‰øoµBï:>ï2ýôK-ó»}—®ÒÁ//Ä€fHÓªQÒBÉÈÏâÏñIW]1NúX˜ðCk“L2 Ö¸V2ûØ/‰.®#G`1¼6ü~fÔ R–|Imd¬²ôðh„{üÑš¤‚™Ë»äË´ÿeÓ.ÿ…Kµla°.
-‹jm“Ÿ˜=~ͼ”øh0IzÖ¦ú·O%_Ã% óa:¢hšP³
-S¹ÏÉÝÌŸÜü¾ØœQlq¸†=žà~pFÛÝÓ³0Ú=î,ùƒ272ï‘,n&£#:$Š¯JÚ0ˆ/ŠRžåe\ßoeEÄ`µ^×!Üæª-î¶ÿš¼îKÜ¥8ÈT?ß÷£G§
-÷glü2®® O!ÝèCÖ½93ìôÙÆ_*©a …õD¼3»–èâ/ˆ’Ö®¼à–tõÊC¼z]îú¾¢(ñÏ~½ŸM¹ã±ÿ.#à:ônÓJÆê|ošAb%¬Äiªê3 M°úá]@’œïjoj'õÙ{˜D—ÚëF*‹/‡?Éå'Å!\˜ˆeÄ£
-ëŽ,/µs¡*/m¥$±¸§Þ˜¾§Û›§pnBÌHé”S*û0uœd²Â©èyÁ„Sçx"ŽšÓð§ÍïB½þôÁü{Y‹ð"ÂÏ1·¾Ú½IRA®ÙÜà‘=$Aê[ž„ÍŸþ媓D¸“§B1·ø ¼•"Höû÷Åj·Â¡Tˆû\ÑiÀ´G¿åG»xÿtÊí|ú?Ã4fÓmƒŒŠ% 2ôÝLTW¦‹Å&wË…j•¯?CÈÆ6X™-ù» "zQ׶Ó6å[g#Yóñäúd[†’°‘ã‹’È®óÐË" 6Ç”wue# ¬ MË%òG¦ìü) T sbw^˜¯ž«TMZ‰âK_5¤÷ýÈ¿“ÕÌß/ëâ¸|cÐùò{ý†VðÌSÛ¯Ã9rFòâý±6„ëhˆ·u^òö´g?›õ¡çxu) ìEºéµ5B=]× ;¥Â’Ë0¶§s7ÁjèSƒè‰#Jws¬Á¦ôE`"¨€:¾2̯sû6Œ¹cÌy!¤¬èb‘߸¬ÉZæc¼`ãû”mÍ—áM*ÛM&½{Rù³®óL–/ìœËG¬¤Á‰ß/é0™'
-ϲiSÛz´­õ…¡I§ `~œm5é—ÀyyB‘Áƒ"[{ÁûqâoÓÐåºïªðRBøœ
-;Øw3øGæüõù¤…Þì€E
-ªõVÖ>ß"‰Ï
-žzÊ6âÄ:gÒ¬?yéM|â(¦‰RÕùr ði­æp2¤ˆp(â 1¤¸£œ¡æ1Rᨅ 59©ðÏ~J{ÖÜñÙôu³Y+ÂJàå)$Müà¹kMˆz,ª.hÚU ñ…1FÑÖÅ*§, /+CÅe+ÅàãïG›},{S&›1ê’™l8ÈÏ›òIø°°€¸¤•·©x€*Ú§wH™^kŽ6ìÔZ$Hq¼Æ!Ü Oý#$*%UˆÜGP õi±}&ÌKá6ºÙÍ(ô@€ØuzZ Ý^ˆà>ªR|­ fö*9 Ÿ}&R°ýgFÝ^å†áÞõ°(|õA~øo,"ÊŠöjes>@vôfK=²ŸßýÄý¥¹£ì“ã§.WòÞNBtÎáÂLå*B±Æ5“¢MÔ®øÙûè¡Cž)øð nßúB¦€×~µ_ƒ8c“Îãš(‚×'ÏÙ¿²6¬iÓкõ°T«¥‰;kÔ4¥ÒªÐÞ™bä® 5˜Ò´íEXŠC†q)6ôfWº‘d0¥àl‚$8ç<
-Ì“ ¦Nó”-ü¨(Û–7 .\2Q0¼[ã>ÞÞc¼9&‹+LÄ@¸J°aiÆ—23Äoâ+Åçu%•!·îÐ èä™G—!WùIŽ‰ó¢fÌŒp V[ºÁ);A Ž+Pc¹ÚY¨N7ÓfH¡RÜõªv¸¯Î_ÛüdE…Ð鼦‰ˆzèže.7-„ê½NϨ?iœ¢}U'ÓÁ¦çÿ
-Úóž¨e6[x5±IœG·6ünñ>ìlu ¬YØÐâBZ *7VU?Átr T1[¸™w¯ËÖj6Ó”äê#ŒSÔ\D¾y¶¢yÂw” k7ÏC¤Î‹ b‡døé’|7ÝÖè¯:9so³h2ûñ¸î–¾ÈUªû—rl’9å'sÙ°Q@ýBîå6Õ:íkX‹(­ió¼·õUðW¼ÕÂîcŠ˜-¹¤ƒ¾-Nyˆ®:RjQ4KàŒTÇc—ûÜœï¥&)ëdQb¼‘– ˜hïáœ#±»¬žS£`KXÓK5S°]Ħ~ WUðã?É g7ÚX¿~p™ÑðÎu=*•ÝGK;t·Ú›iC¢­Õc‘n6=‡˜ñtÄY9ÉæU¹¿«õ¸² êvæão?32y ÊÂEò^‚iYk»QD}ÔÓp>ÌÔ>¨[ÑeØØÙÎGuncáTçÊÅGP½L`.عjÝVͳ…U16–!]!•PN‘âñ³ª^{[T´^Þ•tBÅ.‘¿˜ç‡n\¾„a ªáàïëðõGn‡ ÜÌÂí?¨‘‘å²cýP'}¿ô51iå0¦Tz4½‹Úç=Á‹º£ë°½„ª&koMæ!ø\ß"g*ãÐu»r £6„ŽÑm­³šÞRAàÐ,H¶ëUõ@=ÒØೞTÄ2–‰ÆŽ÷ã3él~ éÅ»{ º;j•ÜvÓœ:Ý×I“ª]:³Í~ÿòYŒ“o4|l‘E½&$è0¼¾Mi4p˜òÈK]Pào½Ö§Y[5¯…ˆDEì¬h.«POýéµû’%
-‚¤=Úd!³ãdêÉ‚Îl4ls~…ŠÆAQŽŒr÷î XøT¼m­97bZâ¼é2œÄ‚M<µ/¬Àoþ´ùŸ“EF:oÏƵ¸rÎrs_€Ezùã\D¯Ð2ï]‚㓼BG­+¯£x»oÞ#‹MÞ¢•ÿiœD|!# R­þ ­1*׶àN ]püPÞ2'¥ò¦H˜f)–ó¦ŽWv§Ä…© :V"å‹G’v
-ÎÒOVYrX¢ïàwJŒSôm‡¯)&`WfXñï³’Ò‚‰oRâ­‘cƒ'ò­–c^ÎlïŽOF–õ×Ùgäëf>MÅ·+(çÑ£ø½fM•ÝiïJÍ+lÉÎ$›©Øȧi‹ Kº¢»»þYÆa´á+“Ðã)ÕÕ;{¶
-{郎£¼Ã/ô‰ï-˨–ÞëijNg°ÐMë"@þ0ƒ[ ®x<Ey3ºs ¸I=t¾0fÌдƒ
-Þk—Ç|¶=pÅ^„°·Õ`›óû ŸRy£!«#ª£þ²s`<5…µ1Î}¿äóè-É`Js_!ñ ®èë媌D›å(:>žd/mý€p @{ m·bÊ3ö£±™W€¯>š‰øç_ìŒïyž"ÿÜßXvܺ†FŽ• -+›5Æô™6ì{ˆñéŽzÔOBz>1%Α}}mBl*î Èà+’?îÍ6 ±3™þ™^\É;<·ør ø»(YËV¼5,{n½@Ø`2Ÿ<Þ#‡æé6~p/Ø t+—¢44bOT§UŸPʲÁ%Ï™Ý×êmŠ¿¶kš¹ÒÍ»¿^Q6R|Vœ=¡ÒÝ03ÉX­®/Õ¨îmˆÔ-gN
-^Á?g½Ç[eœ[T.¸;8Ëñ1S¢ÒŠs¹£ìãíÃ.õy‡¸MnÕ\v¡.Tü©Ä%ñõdaÑÉ•%úh¡æÍ".‰„%{O÷0+íøHæ
-7³”rÁ©£håIËC3L—ÏÝ| á`
-4T¨Tç
-ç!ÙYê‘éó`þiîcînÿ)£×„ø6RÜX†™éЩÉ^ÚŸnà×–,&ªn¢r‰þ¥»GB=àðÇïÄ‚†v|q”Z¾~½êÓ¾j¹ú–RýÇÕ? ô¨´xË™»ýñpŽ~Îe|E£PñÎPB´*Žm…ÃÂ9}zùµ‡ìDy?¹8h•))^Çj¹~žn+TêóÈ÷Ð=ƒ,¼¡a"란)¾®‰£¶:—J¿ŠúD4$ç›mÈXfjfÆ¡ñy%[¸"6¾ÒxB)•®ÅÿÊŠqÎ>¨×l´—틧¡{¥»¬ëe˜R™ÏJñ­j}Ú§ÝoìU¿ë à{™ä–\©†õ6Ü:ƒ·¬ct5I/« €,¸Eð=÷ Â8i¢+~[‰2ðL~¿%˽ΨEdµÄ3C}®éX…VÇÝ?àëV!CŽä‚à`D2Òé4Û%‘çÖ9¿×õH„)¥ð„ÁúO”P7tt1iU~½&=I¾òèÏF}=шû\XUêÅá[&¹î3=ûŠ†ž2¦8Š¼á"GĘ›À[pClC½ÆXÊÉÍÿQi¶Qk bºmj‹df$Àw =õ´åƒ‡”]·¨¼þÑØŸKƒ©ÄøÄ[¨žúÝðq*ø!y›%Å…øØLÏ?×-+Ù‚õ´RGÒX I†ÿI±`dìÚhZN¹Í"VÛ‡ûô2_®ËâÈ«Rßó!«r
-2¯å²vƒêõj:¨¿Q<¯%C/õ±c“I+úI~ŠøwØc`µÝµýƒ§¡þŽ¤ûJâ˜ô ]8 SÆ/¸÷E.ƒa©4Íî¢gb‹òéž7î;‹f"pçìÏðB]u±¿‘ßó‡èãb·4îžiÀ[.þB&Òva­¬7*l?TГ„ræÝÜnàœ`á'r¬Ó¦Ló1&9¿å8ƒÓG§~p…QxcÃÒ=´Z‘ðŽ±Ä5ä‡Ø×n™ù VbY§©àùÏ"§Ñœ}úþZ–§75’¿@-[Ë›œ1=u˜Oÿa"&¦u¶|Êê;ÏõåÅÆŸ'?Hl4ëE\³Üà#ï<Æ—
-¹`†\ÿ¥¨ª1¡Õ–£ªø«¤\Å'GË'²RSƒbzûÀ…´ãé‘!©¼?ôdFÕ±EÜ%üÝtk'õð‹äpNA‹Ûº†‘ã«óµýñÙyõ)¶'Þ¸$—( ºI‰fÞê¢*)
-£ÖöQðŠ,$ªõ@˜Ôáö%Õóø*(lŒl>9h¼à˜áxJ¹öÅþãn ˆï§šxíWE¦º²Úa2”b÷^+BBF¶-c¬>À‡ ïç ›Ô„üR¸²ý³áìKE±®èÕ'¥Åq5/ÃÊÛËÑ»ï-ï'{+Z‚"Ìô”{9…Öñ›‰ò¥YnY’8ùUú³­^dËÈæõqàÝÝÚJÌ7C)[yðîñïÆ^3>@–cÉã1ùé
-NaãLïñ˾œ[{Uy<-Þ€-§Žà@÷ÎG{|Ñâ'ú*&MËDß×°‚ÚKÆí¹W!¡ÏN¤µ‘ÖÅe<Ò}øÖÐÇÞfnÑ»…³µêmºŽ5Y ’8&€ù³js¬†]ea^å(Þ¦14üŒ`pË{B/{ã“ÜŘÊgþ6<ÔÆGE§Iwuy³¯<¡= 7…ýÉ̸¶ä3…}€ÉüR4{Ò^ø<zN‚‚!y™ÃÛíÃáxVRο0,¹V‡}’Op7A7!ÐTÑQP˜ùT™ÜÞl,P½ÙTE™>>™åÝ°^ûþR›„»¸8'n¤-ìJk®²QC
- ¦Ô"ZñwOòï™»ÏöP÷ê¨.ÐJî~&Ö>zm^B¦[s°'òYøš×Y­D˜¾
-¨ÿKuß!å"|ÐÙEÆVÌð}†ô¡¿ O'®ÖÎþ€å&-¸ùhì8ö²0ËüÀëèæy€ôõ«`o­$‡Rš´y?…|¨ç>K/µ^¸°«l/J¿í§öÙÄ¿Ñ׶ݶëÒ“<‰âïŒçî*O©ÍTK?5;º(›o³ÇUJN¤P3
-øÍæ6?ÅÖ%X<²˜6˜ü” èýÇÓ·55ιbÏ(L853ïáˆÕë¡›íÐêº/ÂÐ7q‹^¿_5
-r•ŽQ¾¹42"ÒQyܽ…8[E~*ï\ºÊYòÃå«&R½n<NÁŽ¨ÎŒóöÀ8mÈpf0 <«±Ìœ/Fµ{ —·î9ýöÝ„PœÒÄ@cÅÿ4¦; ™«×”¯ü¨K­ À$çdLÎð©»$?ÊCîYÇF¢á‰á&Ø,ØÏ<Ú#@Ë%® ]g‰hƦÌäÒ†F`{&(]ž·/iÇÕÜ\p±"Ëbö>¸M¸  ý¡$úu}ÞÕ*äW˹ÑwçQ
-®ŽW_hi+yñ¸âÅ‹…†
-ë‰f m…ÚÐJï¬ùÏ¥‹û ´¤ešÌiûFt& ß–³´Ó²ë“´›>Y`™å³{ëéÄ2 û“°dõ>sf gz s‘žI Ï¡¡Æá÷”êK“VeùÞÉÄ;NIN² -ÅêàÒ[xŽø?‹¬ !¼Ž”xí°åJ¦v<x¬/ OKÁ5
+/Length 11760
+/Filter /FlateDecode
+>>
+stream
+xÚíteT\ë–mpw÷‚àÜÝÝ-@€
+(\
+www4Xp×àNp×à®yœs»ûö¸¯u÷¯7^±kìo͵撹öGC©¦É"nî`
+’q°‡°°³²
+°
+˜Î K ³¹-ÈÅåæû¯éü³OÀêèèhëùw´Ãß^ÿQâ²µ`EfçxËiyËm ¶GþðײÈÛ[8
+Œ»C]ø¶ti ÓRß÷ Ý…X«´m¼L»AŒJÑ2uc¼Ïf•ÖaõyØtv7GÕ5ŒJžáÉÆÛ8ÏîÞ»àRß:¢û™¥×Åãµc6¼Ãþöåè˜6ùàî–®oxp ¿ó®{‡„)7‰FÐ 6:À)—DT_»Â;’iºv—"®;)ˆmq*ó‚?˜1û5_ÝN[ë’ǯ=×ç³"/LIê}Ä£›k¼¶lBñ«¨¯¾-š|oRkÜó&[Þ&±ÝñreéòDQnßô?ª[K79Ð7/Ù/–_!ýmÛÑŸ ·¥Ê“žHÕ]Çy÷A8­\¼ÙŸ.¶h¬æèú†ô“­Bj£­Öè®{ŽúÈ£÷ öÖt=¿ !æ¢DÚ–¶bO„t8&óïû·ù#¿-L.Ii§¼µ\’îžhRºª® xïN
+®°V
+(Š0¢™PÁ´i—µ…½g` äÒWDWN=%&j c6–K…Á×M囑êæ>vEÂëÁ|Ž¹Eʯ#«îu€U•ý9å™x¼.­dávÈ!ý:8ò¾€Ù€;pñJ#WT ¢Âª^Ûà'áHðmAFr4”,=gK3M¨Ì(R
+ª¦S0†¶5§(ƒç•ÒÃòÙ#ÀÀîœj›Ó=âéÈmoßÐ
+¸wÛõeä7ÊüÈ‚Wª¤I„ÜGñaquÂŒ†!q”ŠÂÓúF›ºNÑvw=É€ˆ ø?©þ¤ÝÊCÌõ ýß{?~µCâ¤ÝXœì†q&ç1j;¯ãI¢™Ô§U$´ö2s«Q6·oÛ†±Œ•°ëãä'n¢ªÌ(" iÅ ÚPV Ý£BªÎµqt¸Ö•Ým™Y•d>Ã[¶‰’¿¦ÛV­¸‰õ»ë+WÓP¬Å`,kE}±_Ys™°
+ä’Þ›«+;Wœ‹ò,ïV‘äîIº9^Ü¡U½0~˜ðâÝ^ ^ñܤOgn}Â]^¿¡%K(îù˜§½ÉõUÙó˜×òÁ
+îÑâ§Ó/ÆÔ€P +°-¼ÝyתžVý(/}_#™mѱ¦€*¥f~[ópÏ8V†ÉÑ8ï„$gÿ" N:<3Uwñò›ðžÂp6­Ö‚ËI&Rü¬ÜŠÊ“‹pžÓo/8)Ô+~Û Js§\¢­öÊlöí»i{UŸÈ»Ã»4´½ÌM_˜š?Å]FÌ©•A·Ö_\"Óƒ‚’Þ}#FG ïK}g|ÿñÌàë":ŠEù×%ñ’õ.C!+6‹¼R±ˆà!Qê˜_};¼È#Ëö]¿?Ü~d'My*½{·8¿á+ínßû·/ŸuG«ø0¢ß§ÒÍéÌ–àb“'¥ÿî¤ûm>‚ÿ«?‚´Q õÞ([ºÁfMÛÿŠƒ´–?Â…?¬Žžš.Tùô+ª©ãJ¦eUq8jrÜ…Yp?Á ½Y~H…#úò=*Ïqí·Ï™‚T蓦ò¡E‡üA‚⫘Lm=ÏÊ72Ø÷]‹Õ™+eÉ¥½õ¦ ½=¾¼Eó@•3.¹w¹Gãd“•.Å/‹f\OFJ$Qó:Ñâ
+ýò­Ã)8ȉÅ)7è_£Œ·ÆT÷ô壌mMÌœ+¤
+G¦©J¨ç­$î}0ÿx¯R7ë&K.iËP6RÔ.<,ë㺥1~4XÛ¸¥>÷Æ ètž•>¢Â:Ñ#)á>æk[¾»ïÛ'Îåõž¬Ž"¥à P¼Ê!B5ÿi‹ÒÌÒ÷ÀI¯´æ6‰ïíÚK²j?uFéi‰W!Ü’½ NÒ.TEtmúÖF°tŽ¹.†}-¾ü%`úµÙVîC¢p?VúŽÎëÏ-jû-fÃrÅó$î‹Ï„¬\AËÇlä¡NÉWô˜,
+Ÿ`bêTèÖ6çCÅx+Äèô@›þ`ÙvªlÐTw»J·ô+²ùøp4Tâî]” ðâú>êóXÿfßdO¤Ï£\Ï”H:[PC‹Ä²¡-‰­Çó|—ÕÏñÊŸ0ï³iov%§Ž=Æ‘»ñfLu³$ŒX«Dm|BØxz’‘: ÍDï¾T–[&n'îóšZ) ¶L`z˜÷Î(1ܦ—Éc¥œ˜*`ï3Ÿ+F(ò¿gVà/_JcÄh‡ÛÑ|¢Üm:rGæ-Ãì]07‰±?×›­‡¶­0RK4åÀí+—‚`îŽDÕÐLºÎ’ùˆ9>ñ¯ëwe£¯ÓÑ©<Ôº:n;=]7¶cm$Ïjô¨âÉåx¸Õ8>Ãp:'`=2’¬~'¡·:é'î•üc|±#úvN<
+É‹|9
+PÙ·åI,™ËúP5—ã´"ªYžBRÒ!¿Ñ)ÑEï…ÅEUÁO»« Ñ ¾ 0Å)Û»9Q‡‚áT¥áååh°¹íeýè²bOäo¿*Þeº}N5à„M=*,".}º.ØÒ >Dï7¼¤O¯·Äštéþ"Ìs¾Á%ÞÌø-".#S„ÚOXõNèWÇl„Ò]8T‹0üPÔ}zZÝ^„ð!¦Jr½fî:5…€c6Z¸ãGvÝ~Õ¦ÉþÍOqøÛÃÂÈ5Bl’÷eÆT5ª–ü€ÜØ­Özä€üÛ W–ÎòÏÎBÝî”}]Äè»vµ}V­&–h Ô0;5#ÙB탟{ˆ>â‚ éñ¯/bú3 13„;6é:®ƒ"|sjü”;“ã´iK—‰Öcˆ­^#kJÚ•üMCG&³ Ú#©Áœ¶}äe-Yò
+iÓpn¥ISÖÎ.DŠkÞë‹eªñÔY’ªU
+{&p–è°ÌO@¤)ˆ
+á(ÉÐ'k‚ï¾}ZuqåÙaÕa àuß+•?®Ò ,ç<Ü¢p)Lå¶c§z7ƒÜÇc®{Öß°Uþ­ÝûÁÞ_)Pùîã0Nh_4SÌbÉ- Œ”²:ã%¹îL¯EÑ)ƒªÇ7D.÷{¸>ÈL¾¯“G‰óEZ:|ÇL÷
+ƒÉ/¡¤èïiÔò;ÌóêôÿLšUïÑ[læQÎaœ¦Ñ>ñ³G÷™=}!C‡áóoΤ…ÃTD^ê~÷Yñ5l{ž³×(᳓* ŠŸÏgé­?»ñ\²Àå'Ç…îñµþ@vǸŒ‡¨óÀ9šæ‚Ã?ŸŸ¾èxŠBœZ÷ö´köö†dqÏ‘"$!ˆ íxðÿ"` £þmÍÓK›ë.¿ôe|ê:Ÿ†›%u@éœo('_
+¸=Äõ¹Â¨ìW|ÝóúõyÆ壹Œ O<ã–H¦¾kû»TCT•3SQú˜8EŠ9·[Éi{ªðãá²Çäve=§ûïŸ$)e Ù(ïöyï6bU_>`R¨ÿ™2Qt˜çR?=ÝIêbĉ& ¦yÍèZ÷;Ø%U¼å͇⌌àÊ·«6ŠnËLJ˜S2tqŠç+ÚóKÄ0H ûÓ'­½ª~Ï”aLø˜±ºÙ‰l½,£ ;ˆ$ùubq¹ñÝ8cC¨.b /άKÌJáÖR7£¸§ôŵRì`çzËb“³Z'º½$ éëý€Õ÷ÒÞù¡À.(?ü<Óo' ÂX£¹
+½‚ü\Oãl}çÏ rÉ^Ü ëcërhÁÄ{£ x.;9¹ž³¸#ÛO}+ö H‡Gzøå% Æ®¼ð§AjS2kí;<)Ÿ@ZÍÆ»È`n#çPglv<C[HÀB
+ó>çxž–HhÑo°þ¦¯£mÉ،Ģo­»L£ÇQ“0íñÅùuâ#ø2†Nü®{Q[V¯Àj¿¢»þ?ƒNWô¨?ƒt›á%¦qGGö:¼®*x¼ÃÀÌžÙÍÙ^?£õgf‰•çûúpïîLÂTÅ7^\ý?0[ÅÃèQÄè$†À×}ÝŠIÃP±ªÇdYvgä‰e¦w©Þ$àŒ¢_™ ×¹Žéß™†Ø'DÂ9ËŒ?h2ó¸%¹ß̆Ó6UÖ¾—õ„¯m“±(ò¨øÈþ­ÉæD¥«‘÷§½ºwõ¦$MMó:2ž“ú©‘ƒ=‡3Ït]ÆF±°i\Çã“%N¥ŠaÿÝ£ÛEK¼ôÑ×îŒ6y.G­†(®AM†<ï¹Ö~Êyõ.‹ï—²À.õ8'_e#åBâ[7Q:¿žßämø"mƒbìS ƒŽÆZá 4¨YŒ•{t¿Op¡Æ¨à‹!| ‘õj—/™§ÐLve§eŸ(ú]<Žqž(Á¨ð칄…ÏÀßù¨;ïAJGZ0ý7ùˈ¾†[(-®P+Uìp¤ëñ|\—;ï<?ÿTlX8ÎíDò§ ê÷ç·ÐÄßÇð“QÛ¡ª›¾ž[,d‰É;´Š±¦IÄW
+² ðêwòoÀ
+=+Ñ ºEg¢ŠÖyé5,˜bQÚ¥x®Û:>ùÝ27r¤v¨x©t¯½ <¢íæVþ–(ù’]”Û­®ÂãBB²ßâ ïE›Üä ?•ïd
+ž¥ ̺”k®ÖPú-F3{^.|àƒM],¿Òck&Ïý"§^{9D_o·äË•ÄgDwŸÇ>B_6õ¦F§zJ­ïf¬E§9åGÆŠ(IK6na mü¹¢äßúta\‘±+O|oÛn™ÔĺàÙ_ $üÔ>­Šäkës±7¡{^´2ÐX úñ©ã³¼€¥=Š&I×}µîäØsU5u¨ÿ’àï"VB”—~²rön‰Ã/A“¯>k]苬’)ŽÄìÂèÌ?vYèäF8ìúš
+M,b?Sœ†è‚-\ ì‰ûdVwÑIôœúá~Ö7ŽÄkeAø€›ÂG9”¬™C:¶œ<_}9TïrTÒ^%M…íŒC,[E
+tÓÎ@½*¯g :_‹»o]Ÿ°’cü‰·ÑcM
+}­+^ÂÂí¯e‚³é)À+-[‚fß7 j5$‡=á›®bÖ;tZs<u%/é*¶Èø²EÌèÁþRå´6*Fõ0N纄Z Ä4÷€4rð¿_ÓktV{zd¨%Î`n »Ú3NrÁ'ÉHŠ¡Q1Â\®©9à
+$2ÊÓ‰Ÿ (¹
++ä—JEšÇ—éáJÝËÅGq­¥½oP—Z{@LŠõÈ_
+L„³”%$6$n”%  I1YÈcó³:Áì/÷HÅ
+uÎÂüÕÏÍ{1T¨—t+jªNìpC4ç@ÖîÅfÙä:)0ýôðt<P‹b¥7ŠÔÒ·š‚ù(23¬õÙMö+&c Ól.^85^Z£ Luü‰
+EªÊqÓëTéCòâ¯yÇõ•+«ûv©FZpÇZòU1ì´‚îâD¨4ùÓ£Bªg9Œ¤ÁÆ{¾Púé™S›vÑ$ ‡¾\ñxllË5çÍiéõ$éTlFÚ—}GÈØf<ü È -ü%ë2bh{açògôCÿ£ÜïW{e1¯éF¾'GŠ)Æa.¨³BG=(”ˆüªCÞÛjHk_×iêPtkºé7ïze›¶ý“tå9¬)U1M¯ž6¾¬ 4*k?¦‘<ꮢ±²àN|×P’.n¹||£ÜU+¶3F”MhÆœ ¡¦9Ÿ?hHû›ç—nr Þ-ä0±Å‡ÝÖà’U·¢PA7ÄÜFwæ°'ŽÁìÓÖ‘–º@çPú)B²àFpéœ=ç(®é…àÎÂL„N·Í-þÄYØÒ.ŽF¹ÏîÀ1­ÇN4.ì—{œH¶/ªB¥0¿N­æ%@»&ZëÑ»BhÙœæ¹áí„WèºÑ$Kí[Êit9œßë;*ø¢FÜíƒPk—×xøOyŒüøŠ¼ÂÛ/¯OwÙóp»B"6àl:ˆ›ŠÕ‚U‘eP
+Ç^; áµ³†˜¸ÔÕñXðÞŸÀ»b’¨®k€*G/·O3(|ýhÉ›ÐÅØ%§Yæ6ÈËM‘~OŽ¿Æñÿü ½}»—%Kƒï¦|º9W¼ø+[Xìè¤P˸—úòbhê~ƒÐT¥:J‹ìÛÔ
endobj
-1029 0 obj <<
+1303 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 34
/LastChar 122
-/Widths 2149 0 R
-/BaseFont /RRMWZR+NimbusMonL-ReguObli
-/FontDescriptor 1027 0 R
+/Widths 2714 0 R
+/BaseFont /KALSPG+NimbusMonL-ReguObli
+/FontDescriptor 1301 0 R
>> endobj
-1027 0 obj <<
+1301 0 obj <<
/Ascent 625
/CapHeight 557
/Descent -147
-/FontName /RRMWZR+NimbusMonL-ReguObli
+/FontName /KALSPG+NimbusMonL-ReguObli
/ItalicAngle -12
/StemV 43
/XHeight 426
/FontBBox [-61 -237 774 811]
/Flags 4
-/CharSet (/quotedbl/numbersign/parenleft/parenright/plus/hyphen/period/four/six/colon/B/C/D/F/I/N/O/R/T/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z)
-/FontFile 1028 0 R
+/CharSet (/quotedbl/numbersign/parenleft/parenright/plus/hyphen/period/slash/four/six/colon/B/C/D/F/I/N/O/R/T/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z)
+/FontFile 1302 0 R
>> endobj
-2149 0 obj
-[600 600 0 0 0 0 600 600 0 600 0 600 600 0 0 0 0 0 600 0 600 0 0 0 600 0 0 0 0 0 0 0 600 600 600 0 600 0 0 600 0 0 0 0 600 600 0 0 600 0 600 0 0 0 0 0 0 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ]
+2714 0 obj
+[600 600 0 0 0 0 600 600 0 600 0 600 600 600 0 0 0 0 600 0 600 0 0 0 600 0 0 0 0 0 0 0 600 600 600 0 600 0 0 600 0 0 0 0 600 600 0 0 600 0 600 0 0 0 0 0 0 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ]
endobj
-952 0 obj <<
+1227 0 obj <<
/Length1 1606
-/Length2 17112
+/Length2 17262
/Length3 532
-/Length 18022
-/Filter /FlateDecode
->>
-stream
-xÚ¬µct¦ÝÖ%ÛvîضY1+¶mÛ¶Y±mÛIŶm[õÕsNw¿=Î׿ºß×מ síµÉˆ”è„Œí MÄìlé˜è¹r6†.N²v¶2tÂvÖÆ€¿J622Gg ;[Qgn€š‰1@ÔÄÀÌ `âââ‚!ˆØÙ{8Z˜™;(U~ªQÑÐÐþ—怡Çÿ´ü=édaf ÿûãjbmgocbëüâÿú ’‰ ÀÙÜ`jam‘WДPŠË©
-.†ÖF
-¢bÿÎÓÙÜÀùŸØNÍ
-à gçü7$€òÿŽeúÿ>’ÿ(þo!ø¿…Þÿ7rÿ“£ÿíÿ¿Þçÿ„s±¶–3°ù;
-FzÆ+-œÄ,ÜMŒ,œÌ¦Ö{ô/½Š­±‰£µ…­É_.ÿÕF
-Ð÷ª-KCºæì¢]•ß@e›‡á±Í R©e7ãÝ8æ¥X¼Ý ú^¯bª¿fiWã¦Ç6hé("ôæ?ü…$ØVS̓÷â¹-Àõæ}DJš2½œœ$~T’D™ˆ‡…:Nq®ó#5ßì" 󧈼ˆÎQჶL–­Èµðc“Êç؉/WöýîŸX2ŸÈÈðxª©-“[¿F7žsWÆ{4B
-pÇ€úâLV›‰¨ÛE°¼õ`K«Vá½Öž\ºÍªk:K?>1ÁÆy9ãd™5 @P2ƒ÷Í°]öþ6Í(9Ð`®¦ ~ Ì¢ß +¹9y´Æ¢]’ˆåþJ¿*ú¨ gÒöK“]?e’CÌ(m
-D\ïN¤Ô´|˜Ǧ¡‹Uf¥—øŒÉïÀúÒáè
-ûÙ £)¨Ž&‹"º–Qª86Æ…‡â9xV6jƒxlˆÊù†º’2–^ù
-|Ò Ä;c g¯lt_´û•jP°– ¼ãT³mê=-ŽÙ
- ËÖ /¨é?&§ Ã­¤oø
-%Ñ]µÃ³V‹Éµ‡†#hižrX£2¾K±²Å?²©Ç‹t3V<«×üHl'}µ“œ7ÂnhJ권buKÉ)O^Œ Z5‰OßöÚÖ?ý<ÿs88z™l­; %ÔVæ ËŒõ”ððßEôÌH«íjÚ ~öÖ´Öb}ë­MùñÍê+GÝq’Yµ£[N¢+C1¸Ë¯ö
-RÚ8Ýw>SÓ¯S®A˜Ç©ó-×;%¾À˜úe
-ß$TAÂrü—ÇDUËx,¬mCFË„vh”V¬èæÝod%·Ýͼc‹ò¡R´©kð97Aa¸ö<ër Ñ¿5{ßîRÖÀª—Öì
-(ÙóŸAuÂ)¡¦HŸÞ OØV";M¸’…ܶRýd°2auÒ/3ߘ–¿AjqBGÎÓÙ1\æ›+>€y¥&0•²jmÚqý[„ìÑL6Qb~´+¹PÄ-sÙø¿µ$ÈÑ*ªï ¥ ðÈOÓ…¦JûèY[éýSækŒ¹©[üm}ÿ˜Ð6L÷èO³[²ò½¼ƒëÆÐNOp:„ùHïä7CĬ“ü]½yî´¶ïïÃ>Õ“·aý'×M½®qê äîbà_w– ž]4ðÚÀˆ²öÒøÞó¬n +: § Ìô 8û›cÑJR[2£mXÅw‹}y7ˆ×ÅLeD$ç,?Yh{³ÛÆBÅΙki¿ŽøК¿ Ø1ò°ºŸ;eó‚T›n|˜)94µ9uæÐ¥x´ ƒã½R
->ç³]æoM%„£¬ÎG)³‘4°ký‡ïbZ~ø ¼`_[hã»8ë<¾4²}$.îÁ³Ö
-Œ(iýŽà-º 7~õSLcüýkÅ!.0Yü:7— `hPêoˆÜä¦ójÂlƒG¥v‚j»8Ç«Á¨›ÕäÅÆ6nÂN'éú3ÑX®ÐH¨Ïü%›zl½ ýƒ©´
-)‡¿ ÕÖÏéÛNÄD]*¾ÔŸæ›õ· ­‡.kÙõ£a ü:ræ\e·ûá&ÈÉDŽ¿Œ™%_$$3}9šü• Š8$½¬€È¢þàÎg×™„¿ZuÎÚ8רË=~³a#›L]gŽyiðÎ+.ÐÇå‹6{™jšSksÀ›ø¥qéD¾ ~Èͯõ{Ó·Æm'¤v;?«A%qÐ7ú"úpM°!(ïx[„Ô]Ä,…u‹0~‘—Ý›°ùot…ÿ‘vm¸oŸÓÔ/˜àyÝSÝñ}Ó"‡ÍÿImñ@ü
-åÚ`qÈoa’:Üà}ÒË’àóI¡ Å¡H±`í ¾‹¢R¯u²Í3}›’«˜Œ(-ž ŒßD<Akº z³,¼u˜Kí mÇkûL”4iH!±¡wÅE•Ô›ß¶ÑËf½Ä¯Z8_‚vŸªÙÿMÞW'n%Õ‡óyï+ kpKx®˜XnÝÅçel\¶êaºÆ§#§ˆA³K ES÷éüT¶È
-Œ¾ˆeD;õ›‘ æB,º„5µ³äé
-IEVx[i©ó•û MCá–‚C÷=…ÐÈÏ ½~ÀÕõó)Þ7ƒNòw8>Çîwëôêé‚t­»Ìt«Ã<EÀ ‚†Å5#²üd ¡,º%¯BBç;¦é.lãWœ›ÜûÜÝ<’ÂÚ9a¨Äƒ.vKž
-q›ÅßZV¶¸Œ&®äò®Å©ði¬Ÿa•ÌF/wø†¤°•|ÒÎmyÒd`Í\º¯*ÚßDw§Ìw °)eG8ïÂ5´B¼Hc†µÙt¢ùš^¨3€6ŸoÈ:W¦ z´˜˜éÁéä’*ëÔ£Ÿ@îàâp¯_© ¥ì%Šcga>¯W¹4#UâRwXPƯY“4ìg·FRß vßû<ÔxP>†uÂËe&+
-Dì2Çüߢ¿¢‚IÔnèEYÒÒÇe)ü²:V ùUš>иɚúq:…mɲ¶þUñNžY±B§Ýêƒ&³Ã¼]Rý*ÃŽûý=*n…ѽKv„hf0ó;!ØÅ .&f«RÚ„ Ï‹ë&e¤ãe}|“x$Ó½ââ;£kgž=çyÅg©Þ+a…¶’û.Î)†Ú`NËiߜʼnW«Uäç*i¼/W 6æø>±§“ <?;dPy\Ÿêd汉ä»tóñ#+|þ­1qÕqVø‚¥Éh¢‹P³Á4>t6ó –p2/ÉõÚzî„øÑ=h>±`
-n5TÁšëÑ”’ÐX"GEÉ.4–ú&µ¼ ØØ…'Àú|€PÜLêar ¾0N1fo÷í¼Á¶Uå" ‹*0âù$]s¨>ÓΆ”'â¾ÞÑØèÝf6qì©)¡}mZ€šÍûIÄN§
-Îþ@PD # V{¿Ö%þVõ|3ùÈ”JE3)&Níð{_’ Ê m3™Î1 oåñ S“•/bì~O«¸8/*™Œ²éëíZφä(.Pÿ§žÏdÔö¤¾X<é§îrî9YJÛ)E抰z6Ø/v0 ¡ ªD °¾T㹋˜€7ýP“Ú¡ûµ¿^¶û°iDØF…ṳ̈9Ô\ðØDˆ“Ï%Ë;¥Ø—qëŒà2ß œNý.¶8bWÉI0Uy®ƒÎÈfPw³‘ Õ8ŒÌ" Çsäs
-ZmØFÐÃʶÞïPhzI÷™ð€*qaBrÒ·Ø^ðƒMâÝàí-Õ¨ô¡À˜å®™ÂÞžÑÉö>u¼ ‰ŠÏãonŒ{óæâ<ŠéU¿˜f);›Íp±OË,¾†ª™ŸÔL~‡(ÂJšW
-`þ* ÎŒÔÀh0±ì$(]J+?!uR[LGÓOÁ
->DGÓyØ}—(l ø &‰åSß}fÄ †ù©»7«ôÖÞ •ŸÑ;!)îüP_©cEìì_Ï“Á’TYj¥àê§ïS({ çÑd
-± éÇ¥µ¨ÿ‹0Ò±«ö¡`¢/³I Ph¦€ZhtDįcÅxBkô¹õ¾z힢Uˆ1áû-C^­î@\’ž¶Ê#f„†µ]òOÍÕ5 Ñôh‚˜CGÚc(hƼ<@žðŒe/ºˆ¾]úyèŸãgT —–B„W‹:ƒÅ‹"p+EŒŒûE|ë7p<*6~¾R—”{N f.]Æ&‡•è…MÀNsr'=d/UMzW¿¨8ûÎ=ªŽ´n¸ÚvDôÓM=×ArY8sœ‹ªf(ú²"’å®êvj×;¥ôŠË7/“æÖö¹]Ë\Ù”7Ùë•azgòá¶gÌ)RàÞ%H}!³¡i°Re<Ñ 7¡%ý¿¹a¢d:£gteµIˆ­¨*’
-‡–oü‘éO' °xd"뙂T¯·3z ^‡ø~LËÿ¡IÖBcP/giй.^ÿâ×úÔ¡/jƒX©ÛQÕ ­€ÒÆ-Ô¦4Ê{Ù·hïgZ¼'ªF§ó.²$2ÈÙB Æúž07êÅÌJFØ “|Àmv®å·Ìù´"Ëæn0jª8xB¯QÎïïˆþ”âÞþÐßÙ«À|˜­jiu›¡lQæ5ý%ßzÅŒãÎv¥ú…>GïÀ•Nv.óY‹=Šð ðô"¦k ¿E)û›™,$i{;vÓSë œ†œSW¿BPPúËj…+ýá{ÛÏáûg¬ššLœ/
-¹,6:üâƒ^ÔX'€å9U¿œ‹fkM6¼¿tî˜è^‚(Ò2g¡I›yÕ²˜RôÓ(.ãcÃÿBM¶SaÓv¨‚/uø¹!&jìdR¥ *ÿ!´BSJ‡ã !DË¢FT=B–žýÏm+›ä’…0Ñ
- ’¦ž~o8LÃć4»DÜ϶ÒlÊô‰'´:Y'ϵ:X–¹ȃKKÖr97…ü dé2
-{¡„Fuœ·3žÍÇoÕ‹Ü2C7§jy¸-Í@Šæ,dL//¢„KàôÌ°FYîÊ„³Ýþ9Å™
-*–÷oz ×PýÚúŽÇä–G”30¢ ò ¡€?Žê)^¿)’£Êw8:B-sìFDò±û¹Õ.¯ýaËmwñ¶ÀBUôz8sš3&¥JÎ|ñ$¡9ê
-¿’ƒ½[žBš´¾™Kåd H*ž±yÈ"ýƒß ýzêXê>ªµÌWÕŽ“Ѥi$&N“yu°BIsŒŒÓoLª¸IòD·»ñŸ’ÆãÇ•ÑlèE)÷—¡OŠÌ:˜¶O-h/_cÂ:u* ý ‚(ÖÛõî9ç}y}F)ß×]>9]¾¬šæù%†­Ž8[pµŠ Úˆììˆ4eAäÙoÀÄÜ# Ò¹äY¼I©[ˆˆu÷Ìp•)ÁæDÚøõ l¡ù})¼ºjoÌa %h1•l­õíP”Eöd¡‹#ò!Œí±Y‡q4NaB¢#@÷3ÁÜ´*ìåFÖ‡ù–[>¼üózëþ2‰ØMÌDn…Þ ÜwKØ¢Y(i£X‹ßüƒd¤ú9ò ¯L,ÿì“^^ñëàö­ÂóY%)µ4ÙZ\ÔötôÕW¯ù­i ¢7,qK“ñâ”-Ç?ÑúE@•àë#¼‰&+ƒÄ0¸Ø¡¸04ºœ5Ö–›ÿë“WåÔ/¶fLƉèß‹›¥0³<IíºÛ‹ÉÄ[t>Å¡u±yØ°Ðu:¯Û{®[’ĸ2Ï}’ cu¶Þ÷²' )¦Z`‡`\… c¬—ÖÙ±{OÑØD°Çré ám;€¸LÐl} JÜ„Ž6 ‘nþ‹‚>°§nºxŽPc=‰6pÊè)L[‡+»†%ª}'¿P°aŽ‘45¨lG½>(ÅûE&-#Èkií·jEüÅ×Ö "ŸûmUó˜SvL „„§=ªA2Ÿ¶_5J¶Ôø¿ÒU‹‡_O·V°mîl=
-æ7ÒÁÒq3‚`¦ t.Ó„c‰Nä•×wíÝZKGº¦Ô›.(ðÔà^æÕ—w[.,ÕZåŒ
-cGM}!;4šÍCnœ®2'ÖÊïìù®? Œå¯@9ÖË'Ñ®æp]CÖ-C¼Dû]QPÓ-}yhÎëzqã©Ýcô‚®ËÚ+›ß™A;tocšn’Éæ¤-O‹ÛÃWÓ•ºžÛóÛž:]‚é#Â_fbÈ°g‘øÌÇ õPŠ€Ú†ÑPÅŽO£ªõdU “ï6dÍpŒ‹bçÆ©\¦©Þ÷Œ­;£&{"ÿÚé,–ŒO_»ÔÇÐ9V¼47M=ÍaÍ]:mÎïGAã›P.4”ªþ3€ãd—&•É–è*HfÅ„÷‚¼M:ÞÌk(g
-4–·öÈZýjH sóG··»èV üY).üjcPÌ¥’»nÞÝtïw¼RÓTÔBÇ
-ŠéÑ:kÅÖ ›r}’õéŽVbbérªïHÎ7Õã³ßêí¥‹_©¼“×2[ëAõ°çô­JCRz!»‘<ùq3mÔ¢W[M0hÒ VÊíaL¦3zb¥ÿÐCNãú?O“lVŠšßÍÒ4Øë>Rj•·•ÛéD[÷87ž
-vÚÑKâåÅíÍÓ¿½Í~¬?קS§ÎªôÉžµè6.¤K±“H?R‡yþnv8Âax9™:¯¼&ýµêo<çßb%ðórÿDí;Ú%§1M–UΗUÈÁXÒ6G«NJ"€Ùíì£â%Àì”w¶ðtý—_7×¾`!—
-;ÜÆŠF¸*Cb&Znf]C¡ÈN‹×6Á.þÂÑ, èW91£ðà«iK;m+úbTèSpïGsÊuÊkÏ&ALH^Ö™FV{ð$ ÝkúÝMbxáñå6ÿa˜ƒØÅYå›a¹5°þ¦J0Ëšëö“©¾é™ý¡
-Ó†©"S—Ïz_¥¬Sþ@Î lÀ£ì†D/®¨÷þ¹B­c0ˆb( º
-ƒËsˆŸ.ÍÏxP£þþ\ næèJµõN*·ƒ7A—^…¯f£èïnò˜Øc#ï|<ÐŒ¹a=íÂèœL¹Çt}N9@œí2ò“º¬ð;ŒÔ’`Ÿš瘓gÛ–» “(kw“Hˆ«fz# ü«TU5aQW.;ì§øtÁTK!bñ6Û¨Ú±A2®Èü„è-£þ|âáŒMÍU5j2~áúˆ^]i‘åe-·¨^žÿWeoÙ~äèžÞÊ„×Cô®ïw= ý² {ì}Åï÷šNå)àÒ„½\Š*‹Jò|±WŽMí¡±Òøòo- kÈ“èZ±Õ6"Ù™þ\W7ϧGÂ}VÁc§Úª4ØXoM7ùwÂá›P«cþÕ’Ûl{lY B‰©Ù/šÌÝÖíü¾ì–­˜T¡ÁÜ?ï°êšš+‰¾Å’Ñs­êŠGô†äv5¶ÈÍÌ?ÈÖ§éBÄ<wsÕÆصŸ×ŒD¦¤9 ߥKòã_Ý»›’«á`Ž]} ‰µñnÃáhDÜÀÂ\É&*NNk…¤û0œ†»™¥ ›ýÔº˜Å9}­Q}lêœDª0ŸœÛj2wü“¯µJ÷‹¡œéÃvµvz¬,Æ}úè"öìijƒŠyñý›·î ’±¼cæOˆq¸Ìpãd:3ö¬Õ¹$c¿_W#ò4ºÑ1¬ç¥†Á z,8ÚÈÕD-æ h•’ö5Cº ͧáƒ_%wÒªu¿ â#¤Ç”g!]7¾ô/BŒ]eh©IKôŠ2¦WTŸuÊÊŒk84æÍ¥0Ç‚AÞÈ;b•1b°mÍH;í>nôÏ¢ÖR /#NìqHºà0gÚ…>tí°§Vûa¶ ˜/æöŸñü |¥sçYà¨q³Ý,ÙŽÆ™(®” ¿œ^õÏ‚~¢­Ö>ʧÐÃwHv«;ø´þâÎMÌÿ$ìe ™´´_ÚژтX–KµÆ
-Ú…W¨•fI•M@ï±–KÉ­7‹û)Cc¢ïS`…,8'Îl[stÂ<¡\nc<BU¿Q×ÓãäKüŸþ<¬ÍŽÙ»¯ÅƒúÉM€^ÆÃT»Ì«ÓË4 §¤Š1´\Ï"µÒˆÊ®ˆéâ]x µŒ'ƃÙIÏKXPõ}BÎè‚YÓÝ2Ä6å¶ a«í™TÙÀô&†’–Àiû‰Ÿº¾îpÆ4
-~[ØÝñ°Lå ¸ ¡©Ûa¨Ë=‘yÿn¬%YçYt½¿Ëú7R¬lN%mÄQ$: QŒ²›DµØ†È¨Ð¬)¦ÃºÊìH%Ûß ^>«¡T&8Ñew‹¹ƒã'}'ÅrW÷ ŸMì7#X1nfœ÷ ~¸ŒÓ2Û*¡U§ %›ˆÁÇ:èDMÂ|Ò.Ž«ªˆàc:š®)IËü*ŠÎ¿žê³Â:
-ºâreA5n!Ñ…êì]Œ¨ÁºØ»‚õOWìõHƒ:Ô…—‡uÀÏk2Q:ú†Édf¬š¢ µ‡$EÏÐï8f±æ™€âNØÔ@Gœ¹}\=ñõ°¨öˆ¨‹¼_W/nÀÄbÛíÿ¸¯ß0^8U¤>¾û=O?°g›¾U̧[aý;óþÓSX¦ä”gÚLÁ´·¹‹.võ@/Ò&ÿ”i:dÏk0G£u¨ð“rÏBž7gO‚w üúàü•–”À‰KY&j øœ7¼r 2–á°WNÎxëh“õÒ¿Í7§LŽ„×VC@]ÒÖóºÁ*óë-Å ÃA;}üvñïiCU…—.úZl¬ õå?²ŠcHÕ¸´Ôu½ö!» »†ó±œW‚Ñ/ðó\Hvq•bf€úOÕy3¹;¾Ð¤ ² ÜŒ°š'ÿˆêIܯE|Ÿ¹ š­p:ÔC9èc
-gŽ}“ú£qÍòÛ¨ù›ÂN•¥•îÉ/­„¼Ÿ¿¨ÎwýéN­ъ”⃞êöÉ(ú˜i.ŽJÓY{Ê…ë߃ˆêo&ãX
-Ë|åT¬N!{¶ L•„«a` K=ETBÔSEÐATMb§œ
-Q‡Æ~ËJlQ‹Rü¶×ZB§©{g¯ ^x™‡¾m€ï¨LŽ1p%õïø×ké\¤~}ôO½Ü8Ûu·×çqÏÜV»ì*æGj¸ÙÛ9ýèOâ÷Ž<M×mÆô|UíZ0¥—¶µ™r'·>û’VuûtñCv.¯ÉÞ¯²”ì U=Ú·rèöI3 Í¢¹ØO7( S~ãÈ”‡ «ÒÛšt”š®`½öÈl/ÅY¦37›„Û¦š ;ŠôÑ à<‹ÆN–T‘Z.!`ßêã…”´I¼M%0,(`Y³¡mm¡ §<!È’WÏX®l‘«oÎFž5Ô¥ÕÂYe%13ð}‡yBjú$·¢³-71 \4oà'!¿¾¡Þ­«’[É2@2´F´‚ø„ö€ñг…ǬÜÄ#ºÅ[i©R(|˜.Èm‚F x¼HÃ>&ymr¦-åɽ.§æo·œ¢ŒEŸ¼B91Œâƒ!ÈD4B\\ò.½ Ÿ†‡b.ô¾=ƒq™“s,|Ö?¼´~8£»»³­
-Ñÿž¶l ÷ö" •äjÓ`Zo…hbµÌ}åÏ0—ŸùoÎ*˯µŸÞµöñæ/~ úÕ'Kü@Tƒ¯k5{<‹i»ö—ROBz@-+µyÚª«1èûŒÂ·–µZë¿ÊnòEp7âPi«ú€pV¢;g.Oã­pÈTA3V.ÀÙòV…I’]UAÍÊ&¯æwú{¥,¿f
-ý’OP\h{†!Ë/:9*ÁþNª‘À„y†Ý¢›¼~¸®<rÍ¥Ø.k¹áR\ÄKÀõ=™Ê³ô¤µéšàš)É 
-Ìó¬¤^©êzX-Ta’•éÔUÚjLØ–‡ÁPϲ ‘ Ú €,j%‚‹Bè_|³yŒß]¶to7ɹ¿"Á¡ÒW¾7ÉÔ9NÙbdÌ÷Î2s—O‹D"—MêÓ†l›Ñc,Å=Æ/¿ÎWDk¿þ-ţø¬‰tF%ÿÐjwÕïS;ù^É£ ñšo?ñ
-ÆQ'?ßœ†*×3;ùQhþà“R¿«A±FÌb<\gÜÝ@ƒ×oìfg,ÙS¿´íw*0=a{ æŽ!Ù5"OBŃð4ûbü[ïR«r‰2Ó'VìÖĵv\PjÐÝh «»Œd ­ªÌ'3çÜŸ¬ô£uªü”.ø¡×cšÎO
-DSmÝ÷dU«TòȨr7)z¡mYÅÀX˜Ä5ê¦[Ø÷ËÅŸ"f ‰@êéqD„ç™Õ'~ñHA[€‹Vû¤“õ^C
-ݓ׀-xú€°šNce<Pdc–0`RôA˜‹¬ß”™…r8HXÞú§Ó•~ «÷®tOý08em_¦;nÒB0ÕüYÂð-'y©_‰ôÛº@Á=¬È*ÃE\ŽKδ¿ÅÿØÙ½/™‰HíMâÑÁ8g7m‘ÿ{<Q-u·´å´_;M;S1Dá[ñ7;žŒØ‚†ò”ÎD!m÷í¯`èhpÚh16jä¬Ö’ØŸ¸*¿v/¯`%–ëekáÍ?LhÎ=”v‹…}éƒíý8ÔµÑ89riL&òëcO ý‰„iŽý†àÁ¸¬Go›‹Í²fÂɘz(¸—¡3
-ßÜ}º^hîëgŒÛ·S~¢Y 
-ÄSä–5“˜{'Ë¡esøücl\î½gˆî*š1ŽšÈõ¼3ª¶è:ÃegMvc¦‚Ê癚ËÖ¢&§,€íIš®Ø1¤¯à
-©*É&;jDú`çsÞ#)„Ê4s‡oEcà &ßÙIÉ;qÝ#K¸n›å¯ý´Y|”àŒmãø•6ŒÊÑé>Ÿ[å˥ߺŽ1½é˜Ê®aYÝ«ÀF5PYåaÉ|3ãä¡ïbøM@©Nyav.åh­nî×ņ®ô²¡RŠÅ—ȬŒWyŸ¦Þtƒ7×ÔÀOkB¬œC@ƒž©êo´dÏ “I¿ü“Z©þä}\žÅ’gÎBT…bM+5êõHzJžìfy<p!uš/ÃúZÇÉ vc&Bãž³'˜3{âC"Ã^z| 8m§¥ØÛ#¦ÔjÞ¿øËú½:¡(Èn‡óÐ)˜âq—4Ù¶³dÑåÚ³;AúGòùVQ°!‡®´$ú>®âq
-C¸ÎÞ•¡‡›û/ìë aLãdU±Å,[g¯úWСÖX·V7~æQÈ¢%+ð?éצµ!ùUè³Êk5ãø&Z£Q‚É [äxŽ-b÷uP…#Ïñ¾†E@qIÀ$ä;®ŽVçæ$#ÜíkôëtJ€\¶p5žr„º‘¢€$|H{U¡øæòƒK]N}¬ò†Ÿ€E×D°
-FÏ-¶ 6© †Â ߸ŒçânVä^… ]šMg\Ô<C‰é>KÇ·ä 9·/£‡õü7o¼¾¾Ð¼­ÎÉSö'ž”Q®¬þ´òB†‡Òe|°ià”¸[‹_Ý‘†6ùŒë.'¸cä½M½åÕr\S>‚K䃔t§C稶h5uREæ‹LU§­Òƒ˜Oôz VÇ‹;¬¤'áS™ÇOXñË€¿®›¦™;µWEƒeÔ #:0츜BøUª,ØÞèb
-Òó…2pÈ^Ù†:0|&e¦Õ,?‚HFkJæU'ý!qÆYµwß³HžÿÔ«œ;…ª»ž–3ª[œé@—hžÏuãrnL‘;®ˆ=bªy7¥E>°áíîä=HøŠõzŒ³šâs|Ó߶ª`KA
-Œõ_P-ç'„HS
-Л¨'ÁÚæãy¿ˆ Re†êi[‘¯²2Ê2ýQ%™ÒZâû®žm-c¢‰LPe³o“=ÒÜi:èÑ'Ðr^ùÑ­ßÔ{?z$É&aM%*Æð®iÞ ïÚ‹š%4Üôí#6¼±
-´!;h¾þGáÁj2Á|O¸D ‡?ûµ“îw¹´`ªÓ¢¿¸‚’cçÅò¢†‰‡Î·¤ÌaŸŒÄÆ툗62A»wÆÕ(†“Øs/A'viÙ.Ü]Á‰µ‚7*‹4¥'O ¢ °vŒ÷øF34§¡Æág¢O¿u¬.t¼“®rõ–s}/¸šä”ôÛºö˜#=ÕdrõÔVL­WVŒªÙÄKã‰éS.“ (Õ;ãh"’€}R>•lÏs¯ì³²Ô!¶‹lAËE:ßy&ôœh»Æ2©×Äë2+Ù®HѳÁŸ¨0An´ë‡Lš@°ƒy‡ß[q8^:ZËÄc hjð-¦B _¦–¨ñº€ÛJT§ûš5j9È«>Ú)¢Û»nSÑj=³ÕXër÷Hl_—rß:¯0)]F: ”Ùtë,,pQ£î÷s²•õÒœúåx.Þ!ª±…» šMdÙŽ%󌥢À>­×בtÍýh;ÑN}ÅO™~ìx[ôÒ[ ô)Ò`Ç™[z€Ð¥Ç;ÿµbä¸ ý· ZÛ±ýW=mVùD×®9, «Ÿ³e,ëKj}Ü üï J¼,®bðýÂò3Þ2¼ ­h=Á‰U,jï%
-ìé×¾ Ä92¯kƒG`µÕÂKþ{|*Œ”)ÎêÒˆÁÄRéAîCêD´Ó®ïÒ‰svѬµ>cj
-6müÍpHr£\Ik[xi×$¼šÉH$S<ÂÐ]­H;"þÏ] …h!ÎK Ùç wœÙƒaƒ!Wo§têQ‘21¸¦e}œDó—ýªM¢Ê&ëÅ"þçÍÜ1IpÅQè—{ØAÛ»kJ‡³÷4°6ŒíîO«Ö*“YŒÝ*³A"Õ±«Ì Õ r¤eKãùŒ©$a^Hœ›Œ×ý‰ÞFïNûé)•7µ»‹i?¦: ¤®ý§"×ñ—á
-¦y¼5âéx Î?8€†,ÄÙ%š¼ø*%q$GÐ]È%\íðÀ¸¯±ÆLÆø¤z*­Ë"7›U0ž$¥¨ ×”€ïøq*櫸×\~ghL[ü ¢rñY{âkây9‘ä¹_­-¡„­“ߣ|ÒœZ¿€ë˜û.†zžÜbé><ZwúµžËtÄw/*‘ê}5Tö4[Ï*ùaÅ6y¡W;åRÊØŸ7¦½jJAºjæ”ÅhÜU–Fî¦|ð¥Ûê:]Ù+ärå’ß±¯µíju:Ûdí>1aNÓßø–à—ÒK!5hI¾?K3²< áŸ,ÞÅÁ¸²Ü$j:=úzåmÈ_N4ƒ˜Fäûq
-°’胱«T«þÃ5jíaƒ"¯‹¬Î×Эô'7kˆ]ú†A§òuSà‰epÀƒZ˜%ÆÅ…¹­Â¬¾=úð¤´~¸Pù*€üÕÝ+àŒVd˜¥ódqɈÎEX—dÓJHÁ+°:ƒÊ}Ð)#ôø@ײ!R»ÿ©€£ì–ù
-;\ùˆ¹¥e7ÍHÖx³¡l½ [sÉHù[êƒáëXôËUNÑõ¢i X–Ø«c4ë7û\Aº0«<{ Evg]8xp[lZщ5õè¹r÷ûGâÈm*Nêê:Q+|‡gµ}ÁÞ\d„äO¾>hžDä¡GXnöº +b¸¬óÇ;½<nõ ÄߺƶrEiO8võÞH•kö}aq²2ß5|LÇŽ´Fa
-ÐQk|/Û9¾ÑxÜÜúÙP7˜ªl©¼å© 敱<ý6œÍ¶Â=Ÿù …3ñTI‡@TƒÌ07ƒI`5¼áô‡lcoƒ|áþü]¤ãÏ(^¡¥µºÈÕ6ÿCÞŒ Ú롾—lšÒÚ´ë÷aµ1Óþÿ×Îœÿ3¡
-šþˆ/KnèEKØ(xÆÈìƒww¦\3¥kÔ!›ùÑÆlð›Qe8‚nÛh’8¯tãær|BUw•Q“)€gÏ£ŽWºè¥@Pñ„¥¾‡LZð7×(fÐlç9¬Œ bf r·Ñá·šPæ}p
-øš*›íßyýá“ãûB/1;Aì2ÕÙ3ÕSs±‘woÃñÕ“VÝÝíßv¼¯å¹ÜÆ{¯’XcÇú9'*:ÞÒˆVÂ)BSzŠ)Xý_ƒÓŠÖpm{§z¼¸—±u±)ôc¹ÿÕ)€+H2Qi·'Âڱ׉×b@akÊE¿¢vÉÃBakR‡å:›ñ†‡Fˆ~¨êÈ’Ìm®g4šv~\œI©¸
-^ýì¶<[7Û-ú%çq´Å5mââËÊž¶t“Bdc;|WÝÚú7–xSyåÈ4ØÇÖv´¦×Åõ Q«´˜„2ã¹Rwr\Œ¨ÇÂCÀVD
-­`Ú5øy÷»é@k"¢™5)Ï1·ØRù-DÒH Ö»¼ÍDdM†o3w»5Gv`LÐ2îä¯uÈoêb—r›[ˆv^Ð^P€ó]üQ¨‹ÔS^?¨Ïóè_û³£ 'C2T5ÍyÅ [<;ËÛÜ}‹hLé4mMmÖéҎ/À}"ÑçB0%’éVE~µb(e’ ”峕UòïiN“ýië€ëÜ„{X#Œ=dÓ[娽 ÿÆOƒHð”£Vê ªëvGJMGÚêåÄLX^9ymiZPpù˜B5«¬Âø#…sW+* ¨)¨OñD¾Ë_*Ïøy81¢ÎsY×/NI„8wÖ¦.¶v.rþ÷¥äïûˆÍžá¹ˆ“¤;éë7¤{®ÈEÕîÄìø‘VYƒÉïÌ|ÝWN`ÄþÅW‡Ù¾—›º‚ÔÂâsh™ËúÊIÆ(ˆxó^m¸ƒž²Ê+»O':QGrçÉ×æ[XFRž;j¸±·ùI•šà5A
+/Length 18167
+/Filter /FlateDecode
+>>
+stream
+xÚ¬µc”¦ÍÒ%\¶»Ì»ªË¶mÛ¶m]¶­.vÙ¶mÛ¶ñõsÎ̼³Î7¿fÞ×ZWFDîØ;2“„P^‰FÀØÎÐDÔÎÖ™†–ž kacèâ$cg+M#hgm økd!!r41p¶°³6p6ᨙ„MŒ
+Ú¹¼h˜™
+ÿß­tþFÄÖÈÎøŸ)Qr6°5þ;XÿËðÛÈÅÑñ¯žÿ:ë þŸë¸‰‰»‰Ìê’W°eZfºs FîЄ°V_èPˆ}I½rQ•]·_Ú¯Ž
+ýêÚ†)ίVÅ3ûÏIÊÑtk²î“«|\ŸŸ½È›¤ílT‡tº%ðéçjQ^× ÒÛ`š¬ôª‡»
+Šº¿? ð¦Ú™¡®Ÿ)üºø£?Ù#ø¥ÖÅ¢u 5
+p¼¹'M/&&ˆ”$PÆã`¡Ž’küˆÀ7:~†ù“EœGå¨ð@[&É—çZø±Hæ³mÇ•)û~õŽ/š§§{<V U—Ê®]¡Ϻ+ã>!¸£C}²§ªM‡×Žì ÀòYÞx°¤þQá¾ÒžX¸Éªi8M;:6ÂÂ~>egš1 âCP2ƒ÷M·]òþ2Mÿ½ Áø‡Œò!0‹v'¬tHèúøÁ“zQ<†ó3í²è½*샶_Z¬ÌòØ ƒ,bzLC âZˆ`R u„¦åý´ØMŒ23­øGt~æ§Æ[G˜bCŒ¦8¢:f˜8,Šðjze¨ÂÈ.ŠCFÿ9Xé°ÍÀ#Ãì¯?–@FÒ*^€ë¸§­áì•îŠv>S
+Vs£€·Ý‚ª M½§Ä0š!a9QÛáù5ýGdõ÷u8•ô _ Ä;+·¹V«18önQ±ù-Í“ªT†ã~í-oò„lèq#]Ïè5>ÙI]n'„ç ±š»-¡ØÃF޳ˑ#¨VFFàѶ|Â0§öN=Í}åÌ_$
+t•úÂ2"ÄB=Ž‡Ãýw=ÓS«;vbƒŸ¼5­µX@_»«“E¾˜}e)Û.B2*·µcÊ~êJ“õïðªÝ
+HÅ”7dv“Ÿ¼uAeR§Οµ~·" ‰š~(w·äpÍÂØV±Ð¹ÔškYòV¢¤‹|B>æ¾s²œ¿­m@e¼É¿ý†‰K¯ã+ aØFÁå0~¨¥?V· £f@;ÔK)”wrïÕ3“ÚîdܲDúP(ØÔÔøœ™ Ð]yžv8Pé¿]Ú½ýÚêPÖÀ¨Ôl6À·¿ÔÅ ÷.Îe‘š»¸‡³ÉˆÎà'Ãf9õ›e
+ÿÂøkÄ×\²)1]8ƒ‹h¥OmfÈßaÃé“ÆS“Vò ùëRç«W <³˜&ДÏÖád­y¡¹,˜÷r¢ógoº1Fî×ô ;Ë•˜,ÓÚ»W,¦j?úÑsvÕàÚž.fê"Sp/2²+hÁä.èö ú¤ õ´ÙUÏÕŠ<J@öÜGP`rèº)Ò¾7Ý#‚•ÐvN D!§-„d/ ¬tXzzÔót߆å~à(H5vèÐéA+ºË\ƒcù;0·ä8†RVµM+Ž“€=ªIÝJ´H«’ Yì‡ÿ3IS¼,µ‚úî@r—ÜMhŠ”žµ•ŽÑ·X˜2O}ôuͨõ0ÿL˜îáw£[’òœƒëúÀvWp„ù-H$÷Ä]øŒ“Üm­yïèúAêñë þ£ë†‡^Çe:rg1pæ­eg¼60¢Œ½ž÷s¸Ûü²èIü#-(öÞÆHTŸÒƒä¦ôp fñíBOÞµ âU1C)áÏ3&E&>êîì–‘PÑS~†þjêÏCÔÆ…O(Vô|:ÌΧ¶™¼ Õ†kFr6MmvY4I.m‚à8¯ä‚Yúl—¹SqÁH«³a²þìz$ ¬jÿÁÛè&”—
+]Ké<#
+ç©^–v©K}³ÆëY‡ŠA%E FÉ‹PßƲÍDäÖ›‹ÄÖ¤ÓMÕ"]™¾ÒÀ‘;Z H·Fh ÀÕQK-‡a³ýý¥¬ÝÒŸ%¥1”NTæ¹$Å#¤aîáÅ3Áë•F?Ê·ØcªjÇc_Y0Zì÷–PÒLÕÃ(
+-wã0!sž-,¼‹¦Ò—t]§Xü²Eùh€ˆ
+ñ~–Ä-®ŽÈ$`òôtMÐJS]âÁîâÙö,se, -+©ûцò½Šs`Ü&—lÁ8å²£âDÊVÜ´È”'ãÈŒžTFû"ìçÀp‡LÒýêÒÊl
+Ê^þ¾Œ* Ð,Ú!4\õËs¾‡Vn Ý ‘^gnaž](+P>—[¡õöã¹Z¾Áxš.¼—Gü3“Û\+\™~ó–F]µêß+IU½*7»àd#ØÖbãBî *m‹'g¹D²m)•SA‘X¬0Ñ<HX°‹aXtͤlýaIG™V~¼#) $IœÀÖŸôv"Sóy3¦³NUáÒ0鼯k‚%(jJ0g.3¦JR¿£°ø¡Z€®ûÆÔŠxI t¢J){CXí 9Í^<ß&p3Ü5’¬*|$õ/Š¤³†ÐXjšÁ
+¿ÑÙã]šÑI‹óC’(¸-E\ôHˆ.çÎoBŒT…ž®5:@¬PNkþùò§r¬‹G³ï%馒ü“8™¹/qî1ðBÅWXBÕ½¿ý¢†Ùј©µ?‚\Jík.ê}êS¥Ë€¶‡ÕØâÚL> $©Ärå`\í ww¤ƒ¢¶óŠŸÀe
+p‰ïå¬tpy(¶ÅŽ²Wå+\FEÝÔóG9 _AóÃDYß=N¿×€õÙ]EÒ8çÍŠ£…<M®Ó";\ÿÐæŸÜræ¹”ÏY`¸0oÜ{sêËXsïrìjƒx—d½+øh¯µ%â!\êR-±COÑà9ñ^
+n
+t^B… ’ y‰ÜD·@µ˜¾Ó ÷¡°_z¶2µ$㱘Jó¢a“ÖóƒTp;ÕTšeIM•t¾Õ5Šñº u4¦ù>†ð<î>Õj Úhá:â—À–Ü;Æ¤ß ïáî¶ô„¯²Óyú6±¯ê«¤­—e\>‹.Ò¼Ãz@Š=ü¹v³œ¬àr†¸/„:΂1“³r_ûÖ‰½^oa~sïªÌ(¸dœúvüa$ OÐU¯Õ’
+Œ:¡G=ñ›– æ@,º€5µ³äj²é49èC’Fˆ´d|cp¢ˆC«°'»M~”
+3¤î§Æ¦ÊgZÉSe–¤õÕo0§Œ"N%¢.ZV×¾(ÜÊ1*”ë´Z½Se´™·Jè¢]¦Ûq¾½EÆ.Ó»wÈ N÷§`|Å»x¡ÃEGoVH™à÷˜brÂ$µ=¯m ec¸—Ÿ¥wlÏÓ²æ<-û,ÖzÅ/SwCþĺuŠ¦4˜U…ÇtÚ3grâÖjR\!ŽóãâhÂÂÛ#²3ðtâ‡çe… *‹ÍãQÈ8òù)ñ&Õxô€Ä ŸcŒDTyÔ€ùkÞÒd8ÁE Ñ`Š:›±ŸS°J™ûçÕ
++fÃS뜊”]W¿œŸ_êÓj™#íþkËÏáK±7FMM:Ö—
+ß\ ~á^/r$ŒÀô”¢_ÆAµ¹*ó«·töˆðNœ0Â2g¾I›qŲ˜\øÃ(6ý}Ýÿ\M¦]~Ãv œ'eð©.&räxR¥*ÿ>´BSR‡í
+’†ž~÷/˜ºñwhVñTÞp8Åx–’lò´ñGÔ'ÏÕX¦ÙeÈý KæpRY7ùüsd©R2{øzuì×S®‡/Õß¹Ç$†nN×”rp›šdYÈ6^^„ñÀiaõ2œñ§;½³
+Ó”ͼ“¹hÕ®û\,´§É4.O65%FMuCC\ŸìO·­:›’Ï)_7><›[ü}e‹'\Jöè@Lˆ¨kÜóqY b½âõ~ÙM¹®¬e|IóÎj+”ÏÕcb8-šÎr`FžËÁ
+?“‚ø½›Cäãµ¾Kd¥¡~–?aÒs‘Dûó¿øuÕ0Õ¼ÿÑ2_QW#¡JÕHH˜"ñjc†"”â,à9¢]ŸúPq“à9Øjuã<!ŽÃ‹-¥Z׋Tî-E›šv0mœ×^ºÂ€ujWâ#¡€(ÖÛñî:ã~~y
+AÙF˜/¬³cv ¢
+°adÓ@µl¯b3@³õ5ÈqâÛZÐ…DÜöýø}`OÜtq¡FºlàÐ’6!–wÈ «ög¢ÈcÁ!ÅkjòQØ{½“‹õ
+MX†“VSÛoV ù‹­®áG<>ôÚªæ1&×m›NyüÉxÜz®×ø½©Æû™@ Z<ør²¹Œ‰HoskëQ0·ž–v€“3…¯»‘ê ðCx,§¼¶cïÖü»~¨cR½áœ W-îyN}i§éÜR­YÖ¨P!fØÔ²M£Ñ<äÚé2c|µìÉž7àòàÊXî4Ó±V.‘z%‡ã
+²f â9Êï’Œ’f1èÓCsî\׋Wí¦½tM.Ð^ÙüÖÌÚ¡xÃÃtƒD&'íÈx`iêHÌþM‰ë™=¯í‰Ó˜>"üEº4kÖOŸ¹Ø.r!PÛ0*J ˜± øj]YåȤ;uYÓlcÂX¹±*©§ªw]#kÎ?úÀ=‘3·;û %âÒV/ôÑuŽ. äLSN„󅆘sOó{QA~ÄòŒ+JþùîÃv²ÇM•Ì`Ipå'±b@{FÞ"kä6”5š Ë[{`þóbHsý­ÛÝÙJx£
+þ¤ûër½ŸÌ©‚³fÎÝtw4N©á*r¾‹m€ œ* í³3Íõ±(‘V[‹.[³ïäÙ“ÄƇGhÀÜF~pðmï­ÒÎ ŽCeG±üAÒó¤>ò(wnB#Ñ6±Ø#fV‰è·Ú¸ù0 e/ù:Ò!î^Í­A[£¸ ª ñmD04µ3NDԺɌ-~zÏ_ÔªçõIÈq#"u2íõªîð¸ç…¬Gûó„ZY5ÿs«^ÉpAþqêÆè§ÜÆ œÐÓxwwå£jåhZ3 5Q««Ü‰k«²Ÿ9O8²škVä™Úh˜R¯‹åã *LãBÊP³‘³]OA¡P†´¢ÖŒúK•»ù –É›ýøR ÒÍXäôõ*B ÅCòýÚbŸ.v[¥Þy#½0oÆo}5št+zÀ˜²³JA1-Z_{µè*DBC®O’>Íárt MΟ;#âø³ õ¸ì×Z{©â
+ï¤ÕŒæZP=¬Y}«’änzÈN$OÞzœ Ûyµ¨•f“ytªT¨å2û“©ô®©oZÈ)ß৩Ÿ›§ Âæ·3TuöºäZ¥T^--Ýú£ÛzµI8çu`##Pô9ðQ£¦‰*²J3ŒøoÙÛjûÜ÷øË ¹{ ¥ïÑómÕå}j*$ õž$Ó;¶£B
+·K=‚'h²@ßóh‹•ÊŒ7¯µŽà8X€› šÞÇvÐkÊ]àŸSü=Η]äÖ¥ajË+*¤¾o²ë”¤0K>ûÊV$öåÄgÞ·y[ФÈèYW5")JÍì!h¼¿di|!6]$ÄÕXT}|
+È›`”¸5² å!4/VqT,ù’ºÄ÷·Ýg¡»Ý?€¸Ò?FE£tK´²uÀü,…LÁ‹VoùÅöÔ©:Ë\ݯÓ&§¶*á—sÉB½hšYiÉÐlóƽ"΢N
+ióÜG4ƒ˜Y8åË
+²á²‰Š.²%§:‹™»‰A{okÂÏM›—ßçB/Èñé”ïÓ²fOk¬ù]ìŸá©Ú$UGÏ y›j‰Âx0NùSîg3V8BCúZqœh‘à­ÃÜ8#ìêLÂÃ-]ñ0OŠÕMærÏø¸MÉ“h Z&ÙÒ¬­¦Qõ5eJí"oëÙ¤è ]yƒ³ÏãRÒu?åþ>®Ó(žR‘²LŽA†»vÐnØz²)‰Ä "’xœìd‚W[f¸$àµF]ˆl,1 ‚Y_jžæ$Rå›:ˆGlå)^ÕÈÓ;3ò šã«ÔJ˜+͘ŸVlkˆšu‰ýÍA¼ fO""©íˆ&&L}sjÖü¢|åõI™m)ýïÃkDÒ…~@XpY>+À8cæ¾8©=<VMò­/<@Üš©í½éëõéØS1CöJEï5Öb“QÛ0o·e­árÀ¼ð6Ý)#/ ÎyMð„½%tFhSTD¸ €>_£Öý‘Dbws»÷³KøbíBw§ªi†#sXꇈz¶Óe¹M„[ÎûÑzjÇT¦o𨉱Wr§'Kýeö<¥„v³;¼(§ŠÝ™]
+Gzߦ@ª9L惣}r#f9£¬÷B/o´þç~B3l?9uB¢˜”ìÎé‡v’ëƒó¢²‚»ß02=·2IL./4í ²ã…±>…SùÇÕðý|žO`s}ëë ˆ“yúóŽzè7§@„¹‡ÊòÙ ntæÌYv‹\¡¸Î&Ê™º4¼XObæŽ{´N¢ý)­< ‡¨ï ûß‹TºA|夯¾Ø†ôak×J¥0 SPÆÐ>*®á7—æµTå`ƒ_j¿iþ <ßB
+,«ÁË&^“V—[*%
+LãDÉæú5š³YèûÜw'Dà†<ÖP²?iȯb2‘sÓ'Þ»ÈDcûˈ‹b˜\]ƒgLâ1Ú÷sâÖ³þé|Í+Gæxïô’RÉÝ8V³-ÑiÉJëÑbÄq5¸kr‡¾éÃø}$ªÎaunj”M*qœsÎàFi7pîßp¥ŠF2çØÀOªAŠv’/|(¹ï~ g$dß¼¡ïñâG*†ètÛ*»_xö«|l‡|¤¯<ÒQ’…µ·BÏÒbˆÈçSæ|UX¥¤³ƒö‡kmƒK.¢^>^XK¶Z“–—õ"Ùj‰\O__y¿U2N3•ÆúÁÝùæ²v3©aþêâVùóìM $EÆs^+îÉ%ºœ¶ÉP.LY…Ätï'FøHÜvq¡ÉoV'¬ûˆÇÕÝ3Òm¹Sì¾ÀÌÅEKð'í~Þ*žÓñžÒ­CȶvZÕJ^õA4m²\ƒKýa Ž³7_‰ˆþÚÁvdª®”ÄÇ0=£m"=®b."nÈ_§XŒH/zþóÕ›Uí MígOV,¤yU—.* ±™\QšcÀü˲²>^å„ ÀüÏvÁbÀ ï q[QFÐhXô.q±îõ_=B’¿Bƒ0qù™àú9Ã@ß\1É2Xü¡öaã4réZ¿¬î…ý`$Wü‡ž††˜ño§Iì¹÷ZŠfåmñÕwû‡òk%¥g©Á®j¢´ç¿¢Dù¥ÐÐÈáFyßÄOt‡á¾<1‹©Mq.Ú¼}-æöáA*zw*üË3{È%äè‘x¢¢ÒÉe)õµ–—òð€ÃŒÎ~£'ÜÜ$Ëÿ¾±†å‘?`âÕa+ºéòw¢äp¨3ÒÍVèe=å’vˆó\pSìy÷X²ud;oª7Ím²óù+÷góuÆ'â«‚â´d|ÇÕÝ S>ÿ>\í8âUö¼­´Œ¶G=Ù\ݘîÂqX¢¨
+œ_ðÀ,9°(öhgû¡o¯jÌÖ o4çþ‚‰f…]Ó좙žÅm)ÜUþµÞíQSßïקãW m‚dôåvqMàÙkN‹u¶üû‚‰L£R©i nAÝt]«¬9éT±fNûh}¼#ô ÃHNº *Tñ³WÅ.}*ZùöA0ô‡©Áše¶`v¢ °ªC <Î<š”¯Šì6-MÂÁr¹Èhݾ’ÎHR=­/«ƒ<öí€i"@[®/“pR¯óùwUëz¡••zÌÌ%»Æq
+ÁoP! ~}(™ü5ÌÅ9Æ;Õ±Û´[H.¯Ÿ³ìdÔÑ`“ ÍÙJ¦S1<šH ë¸ÙìÛ ¼°Å˺Ì}Fµó¢¨(*XÎò~¸‚„Ø€gؤqÀìSUhyxZœª.
+YwBæ­‘03ÐÞŒ}NÔ‚‹hÀWºœÌ+wßÑl“1Ë’CQС6]áÐw\‘’¦…Sqpi& â?sv«=ë¨zøÅ£ðí½;Ω\º c=EB/›´™ý‘“5eª~D§ãƒŽ&Þ)^LQézåÚÈ»„` ¼'8ÌçvŠ ÔPææV•Ìz(ÞjrHOZªî,ôÏz­Ã7í,₸ t!>Õ¸¢¯Ò»ûÄ&MÌ6ª!ÛaÏãJñ¼oÖ{aA¡
+XúoLaùÐÚt¦@a³Ð"—„S ½ÍϹÎóSß©×C¬ÞML[IÁÄL¢Jð>¥lg¼‚v›ddÆ0¬Åü!½ÈœKis÷ŽúÃ’bk\¿È†€ŒsF
+ˆ;övû.Õæzi”Áí¹œä`f “s(éA¶R¼¨2á^: Ä!=Žfý¾‰;ŽW§c~µÁïnS¿‡ï9âÉLšß<Úφ¹Rëä0Gc­vѽ I±¦€¥('§q 9õŒË
+ªþ® æ¶Â´]›†fŸÔd:šþ‡|B<ƒ?X2¾6ñIãpËxCCMS?ILÑE[¤Ÿï9 _ýïNòsª¿pÜÜ E²A™µ,¦/ŽAd-ÝÌ¥®T[c—[Œ”ƒAN‘í녻ͅOXUÅÑã¾3ýªõwåߣ ¨çïSR ™¶µTJ]íy©:­ˆÍsÆ[@¥*sÑÓSyKÃOhÏ»E'”ˆÛ?ˆf’‹¶2楄pL’
+»BÕ=Hv1eÛ¦š¤ÎûÂÊt Û>–¶,úÅÌÞ$¬Ü¸éì}-160ŠðÿàÏ“t¶û»i$¶ñ@]¥4‹µyñahïwn
+F×Ë0Gn‹ÄŽÕmâ믔õÜ“T^-ú 9]5pšzxë½!‘ PÊ Ü§`;¿¼TŽÌN®aÒŽà C›½/Qð
+¤}V£×ÑÈv®_`Î…,$ ò£3¶â[ Þ¦¶J,‰Ìߺ‡ÃFŸ°¾ÖÀªÄ‘˜qhíÖ Ö˜5/$æD*ÔU›Þ‹]áÙ´*Ìz6£¹©2Êõs+ÈÓ#'R”±(d…ã½ït"-HúGÏ\!j´çzóPêû7žœF´Áë¼&·æ›Á™\} 6tê¿ØÎ9Ðe4¨Í´ô• ±B’}¿O„,/±²X1Én·ñ8o'’¤¾5Ð-±„'j#^)\ ³¼ÃŠ–Ì?äNªŸ²$+ïц Žñê…‚Ýxš™C>b1¯):ÉÃÐ]|¾ÇÊìóÂý=(eѼmoL=Ë ÈŒžÙíÏÕ*9Jö–à7J’GKé/cLò L>[úHAÆÞª©µÄŒ'°‰i5b¸ «‚ݧß=ˆ†ÅïJŒ"J¥É±K¢>Úûˆ_1]@hünH%|Ñ:²¸ew·ý¸90ôBK&×åw5Bzh¦’æ¸YdÜóæg}D
+V;Ü#R™'Ž5ž%g|!@1žG½Gø†aU!Ðs…R÷+‰µ\[€gÙ]gÑŒ:)
+Ô‘LN¤@ÉÌh"OîD½’(ko]¬cúÔ=Òü¸…&TΨD´mÊE%JƒÉÞ›’~9Dªô˜21xBou×,ÚÔ ™Q
+Z®ËoÛ4ëŠ*s³°ütg†©NeÔú#‡ßìF¹¤¹K¸]C•f/ZЪ}¿@ôFêbM̼¦K´ØËJ®?L›^ëåɼo¬àÜ^Såõš¾qD¬E¨ÁOÙC¦ª†#¢HGd ·ó¡Æ‰APHöʬãÒ_I
+Þ°S, LqÎ*™C •–ëüðÓ¨Ájl>ækøƒó
+þ„ÑŸœ¥*´ƒÃÜ! Àr™27lÛNâøò,% @/üùjÇëf­„@´RÛÛ¹Õ:#Dô­N tAÊ_‹+fQ$'ß“_­9ËW„~cŒ“üŠ¶aÀ-Í<Õçxî~)Bfvd%¦Zýd4Â*Œ^ÓÐÎõ(“nÖ•Á7†Îr{S¦æ”‹ÏF/h8“¤s$ÁN…t´æzi›
+¡â¸0Çø$øÖ;¬šƒyëMŸžü tý LïXºªA- ø]·ö•9£ö˜À[æË#­oÏ}ô<°F—ŸA¤Ì Èúë…¾KUÇÅÎ}Žøv^¸úͺÛá´„W…Qo;,@o˜ùQ@&×_}=. š×Š˜c¯(¬t\™z±g¹8§Ú±ŽŽÞ¦LiR™‘KÇ>\
+
+“;·!iÍ1w4!Iõþˆ÷Ûû¼ïðy¤’2¶
+¼–I㊙•oh†ÿ9œ¡–Îí°Å`û>C¼]ûÖ ãP[iéº5o™òS·ÍÚ¦b¸ùP7xÊp]_x+Rl¥Ã×z/CUO² âRÀ¨lX ;²
+VÍ]êAy³XH±ÔŒèyÒLåýkoù"-Õ6_XŸs(GÕjØwOÎÃIÕÕ\‘›"NÚGvB<dÎ2æUøõÇͨa'nœ"dáõj›K†·…éÀaµ*»Üz^YCOs´’âUerÕ3“®©¿*̶^qèåSømÄ“—´¿Ìm+V#.MïäîuS³°¢º ½7Rz·Ú•DÊ£{ót§UYEzØ”Qù-t²y˜’…[ O[UÜW¨‡³!¨ï5ý ¹yK=n¸±u».5®°Rë¡fð¨,¸V2›è>ÓˆŽ…¤Yô·ØfàÄØ(ßÁx‰!´à‰%žM>¯Z)
+å"UØð;z¯Ãg«Ô«¼L’"¤Ú-Û‚ Ÿ‚xwÒ×~ e]bþL‚¸=V›Ïóð¨-ÁÅû”Cª³;ÓÖoä®Í ¨ÐÒ&CdÊÜÞ<_}9Ížsßú–M©’£ê˜Eä‡S+ø{ðåÅ1Kg¥V£2¾ÒÁ5«È–­eéýê õÏŠ½SÅöÁ…®ÙK¼TùГ®°zc†\wír,Ö™yÆTôfDÇãF^±–ýtÚ|¶«w]’ÂйP
+¿,:Fp\îŽr|0`Ï!ÛÍéy¾.Nïè^(%×½ñ>Ü0Ø]^ÒC ‘$®Çž5~<ðrpÊÃz>ŠPãuÍx{¿šècAÊûß·™ÍZÆ~œe·9^|Ø™ª´:öÛ9½0 *ÿ}ôõW'¼D>½³}=à -zžûcêÈ^‡õsa`ÔúþçBº&¿¯ÈÀ}Ü–#üÝ×õ,¶…ð€5nXœ`KÃ|Úªup´ëqª£¦Ws•³Fþ»‰ûë»ÕnË·+1§!NqM;Ú¦”+1Åôä@2Z œXÞ%ÉŠû:bj
+XãÙS9´½ AÄŠ›˜ì \¿j‹Gq‘ñ YÔ4Ûûª2x"…þ€¦Æ">5IåñOù¼Ðù)þþbZòZj÷Ö›ŒEŒ×©8Œ†–BY‡tç÷]Ü þ×™¢Ë€9£ýd%ut o¥tÃØ_‹Òs¼#Žp9Ä RsˆNóÊ Aα›‘my_êB[öéNU9Wɶ¿~›ê?
endobj
-953 0 obj <<
+1228 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 34
/LastChar 125
-/Widths 2150 0 R
-/BaseFont /BNCTYM+NimbusMonL-Bold
-/FontDescriptor 951 0 R
+/Widths 2715 0 R
+/BaseFont /TENLLE+NimbusMonL-Bold
+/FontDescriptor 1226 0 R
>> endobj
-951 0 obj <<
+1226 0 obj <<
/Ascent 624
/CapHeight 552
/Descent -126
-/FontName /BNCTYM+NimbusMonL-Bold
+/FontName /TENLLE+NimbusMonL-Bold
/ItalicAngle 0
/StemV 101
/XHeight 439
/FontBBox [-43 -278 681 871]
/Flags 4
-/CharSet (/quotedbl/numbersign/plus/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/semicolon/equal/at/A/B/C/D/E/F/G/H/I/K/M/N/O/R/S/T/W/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright)
-/FontFile 952 0 R
+/CharSet (/quotedbl/numbersign/quoteright/plus/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/at/A/B/C/D/E/F/G/H/I/K/M/N/O/R/S/T/W/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright)
+/FontFile 1227 0 R
>> endobj
-2150 0 obj
-[600 600 0 0 0 0 0 0 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 0 0 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 0 0 600 600 600 0 0 600 0 0 600 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ]
+2715 0 obj
+[600 600 0 0 0 600 0 0 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 0 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 0 0 600 600 600 0 0 600 0 0 600 600 0 600 0 0 0 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ]
endobj
-938 0 obj <<
+1207 0 obj <<
/Length1 1612
/Length2 18760
/Length3 532
@@ -11088,7 +13706,7 @@ endobj
>>
stream
xÚ¬·ctåßÖ&›£’Û¶mWœT²cÛ¶m§bÛ¶]±*¶­[ÿsºûíqnß/}ß{Œßšxæ3ç3×c“)ªÐ ÛþŠÛÚ8Ñ1Ñ3räÍ­:;ÊÙÚÈÒ)Mlpdd"@C's[QC' 7@h ˜™L\\\pd
-ŠšRò
+ŠšRò
üªm{|ÓÂv¸* Þk‚駹?ÛÜ—Ní>ö¥©F{1­(zR€—ùøÞ$T}¨›ä4 z%ˆégQžW‹²ÛZìŒê»“JÊzÅïPߧ;X`®ž¨üH\
üÐIí|ŒRëc1:QA¾Õžž‘'?=R Ž õÜ@öíãÑäÄÂ’ñ¸@ ’GúÙçà h©Ux†SA¥7!àÝ´_}jt{êå‘‘â’FX˾*šæ¯Ù´Ë¾'A¦· ð&Ê9H¶îWþÀ¼žŸŽäJœæšËýZw&sÄâmŸ
쿵$ œÉ„®'~
@@ -11169,35 +13787,35 @@ i¿5xÑ@>,Ïu> w?tiÓ¶0ûôIÏä#%(ù‰ö
^hâŒð·¹ œ£“hZ™Í/øÅ_à7œÀ+P¸¸&&êåî$+Nȶp®Ô ~I(–»c¹ÚŸYªÓÅg¶%ø¥p%ö>­’H¾iL¿\ÚõÐß(¦µâ_«8Cƒ—R{‹
Žµrð¦ëØíû‹0Ê{‡˜ÊQê¸2‰«Zœa‰ƒ†*7Äc¹äJî„I›ÏüìÒ]©æÁ 1=Š¡å©òñS€MX¡¥GMøªéþP¢‹:*½ÙOT9†ÜD¨*ÀzÞÃ*Úž“¬ÿ°Ë_hg
‚œ«ê9ŸjˆŠ"J7Þ®(ðhT(ìâ ª¦¼ÜðÊ™§Ä‹V¬áÝq
-oò]ç }£¯9B‘7õ· öœH{È­’ëæi`T&éVÇãs"¹‡‡ªÃßÛçVMo¼iá÷׈â{C„^×;¿_g¿`,·÷þ2 Ún“ R ɫǶ]ÅjÍuib°ƒãÏV!QÏÆ>²¦aO<ö”ñOÁxƒªH²$áófe°§Åû›ê¥úКxÇÑiêÅà>ò$­–Ìy"-Ú-ŵ ôý‰¤Ëq ¸ŠÖˆÕ"™[Ø m¥cA¸¶¹"t8Q+PK¥ìó÷Ñ”¶ëÛãh_“ ®$+ƒº‡¼S¾ÎúÜþµ$áØ™éezv~7EhÅZÞ‚¥ÓªãHÝåûm®Ý‘(ãŸÄ"Þïòwnúê›»ÉÕ”^«¦
+oò]ç }£¯9B‘7õ· öœH{È­’ëæi`T&éVÇãs"¹‡‡ªÃßÛçVMo¼iá÷׈â{C„^×;¿_g¿`,·÷þ2 Ún“ R ɫǶ]ÅjÍuib°ƒãÏV!QÏÆ>²¦aO<ö”ñOÁxƒªH²$áófe°§Åû›ê¥úКxÇÑiêÅà>ò$­–Ìy"-Ú-ŵ ôý‰¤Ëq ¸ŠÖˆÕ"™[Ø m¥cA¸¶¹"t8Q+PK¥ìó÷Ñ”¶ëÛãh_“ ®$+ƒº‡¼S¾ÎúÜþµ$áØ™éezv~7EhÅZÞ‚¥ÓªãHÝåûm®Ý‘(ãŸÄ"Þïòwnúê›»ÉÕ”^«¦
endobj
-939 0 obj <<
+1208 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 33
/LastChar 125
-/Widths 2151 0 R
-/BaseFont /KKBRQL+NimbusMonL-Regu
-/FontDescriptor 937 0 R
+/Widths 2716 0 R
+/BaseFont /WYLIPG+NimbusMonL-Regu
+/FontDescriptor 1206 0 R
>> endobj
-937 0 obj <<
+1206 0 obj <<
/Ascent 625
/CapHeight 557
/Descent -147
-/FontName /KKBRQL+NimbusMonL-Regu
+/FontName /WYLIPG+NimbusMonL-Regu
/ItalicAngle 0
/StemV 41
/XHeight 426
/FontBBox [-12 -237 650 811]
/Flags 4
/CharSet (/exclam/quotedbl/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/underscore/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright)
-/FontFile 938 0 R
+/FontFile 1207 0 R
>> endobj
-2151 0 obj
+2716 0 obj
[600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 ]
endobj
-898 0 obj <<
+1150 0 obj <<
/Length1 1620
/Length2 20127
/Length3 532
@@ -11205,7 +13823,7 @@ endobj
/Filter /FlateDecode
>>
stream
-xÚ¬ºct¤]·.Ûv*I§cul'[£b§bÛ¶mÛ¶­Ží¤cwý¼ï·÷>cŸóëœý£jÜk^s^×Zë5FQ’)ª0›Ø%ìlA ,ŒÌ<
+xÚ¬ºct¤]·.Ûv*I§cul'[£b§bÛ¶mÛ¶­Ží¤cwý¼ï·÷>cŸóëœý£jÜk^s^×Zë5FQ’)ª0›Ø%ìlA ,ŒÌ<
šþô­¯œtGLz¥ÈéQž7K²;P?8˜Õö¦””õJ>`ˆg:Yánžiü(\
ü°¾<Ù£ø§6Äbw¡5aÔž_|M<}~¢î½…î?$¤Ë‰…§äuBþéçC(øC­B¼ªùÕi{Ju ¡glŸÏÏìC(»ƒ¢ÈbÓËZÁçjð§fÌÁpC@¶
¦éÂú”/é„ÐaF)¹ìÉT_Äü AÇDF@’_²– z¿IÂ>^"ò“£œŸpÖj×Ñm¡HNZ¬¹Šù—;Ão{ô«OŠ—©š}¾ŽÈïqM gÀÁõ@‰Î
@@ -11279,136 +13897,130 @@ K› ÀöYt^¬evQ&57Ñ„t9Æ©‘;ØQLV2²ûËI2­U^¹¨%Ô~ŸŒ×ˆzW
p
íSß»bò7+֘ߠáænÍwˆ'£#µE°nx‹¢PšL~|ö4KQ¦–!¯jn£ÕªîØãVBGE”}œœ Žý­Ð{ƒéV³”Vã0¾ô.¶Tv‚Ì|` °SU[¸U!&ýø7 >hI£YÉì0…òÇ*껪¦úݳj€í¨ž¨ß`Ù?8sGx9g3ÎîèñÙt÷:n:—SúluHx‹œ›ÍÉPo·«ÃJAüÕh€ß¾ÅW'ˆÃô´B ¶q…¡Jˆ`“ý kaæ®´bg>–MO”¶æB8uk—ÄþÙ7)Çê®Ü¿5GVQ(ë¿P­m-FG*åTA¸¡WK2z)· Ž×?3Ì›QOl
-¹ƒ%ÔÕÝÙêjý2öáýendstream
+¹ƒ%ÔÕÝÙêjý'óâ
endobj
-899 0 obj <<
+1151 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 2
/LastChar 151
-/Widths 2152 0 R
-/BaseFont /BGSVOO+URWPalladioL-Ital
-/FontDescriptor 897 0 R
+/Widths 2717 0 R
+/BaseFont /FITVGS+URWPalladioL-Ital
+/FontDescriptor 1149 0 R
>> endobj
-897 0 obj <<
+1149 0 obj <<
/Ascent 722
/CapHeight 693
/Descent -261
-/FontName /BGSVOO+URWPalladioL-Ital
+/FontName /FITVGS+URWPalladioL-Ital
/ItalicAngle -9.5
/StemV 78
/XHeight 482
/FontBBox [-170 -305 1010 941]
/Flags 4
/CharSet (/fi/fl/parenleft/parenright/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/b/c/d/e/f/g/h/i/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/emdash)
-/FontFile 898 0 R
+/FontFile 1150 0 R
>> endobj
-2152 0 obj
+2717 0 obj
[528 545 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 333 0 0 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 0 0 0 0 0 0 722 611 667 778 611 556 722 778 333 0 667 556 944 778 778 611 778 667 556 611 778 722 944 722 667 667 0 0 0 0 0 0 444 463 407 500 389 278 500 500 278 0 444 278 778 556 444 500 463 389 389 333 556 500 722 500 500 444 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1000 ]
endobj
-801 0 obj <<
+1017 0 obj <<
/Length1 1630
-/Length2 15892
+/Length2 16214
/Length3 532
-/Length 16775
-/Filter /FlateDecode
->>
-stream
-xÚ¬¹cx¥]³-Ûv¯ØfǶm¯$+6:ìض“Žm;éØè°culãëç}ÏÞû\ûœ_çÛ¿Ö=kTªY£æ¼îûZ”¤ÊjŒ"æ¦@I{WFV&^€†ª–²‰­­‰9ÈAžQÕÁÎð×̉@I)æ 4q9Ø‹›¸yZ@s€8Ð ÀÆ`ýúõ+%@ÌÁÑËdiå
- ùËAKOÏð_–\
-ø›UY\òßuºZ™¸þ“Ûô8Xüõ4w0sûgKÿÂþÒüE]M@ö.
-`abû·Wÿ²kØ›mAöÀ¿šþ«
-™**À)—PHW£B¢ªU³m·WÛÔOrí]VÉ• $«ùqyĤ"õÂzŒf<0ëûë£Îðf}/Ÿí¤>bêFè,VØUd‹ÕƒæÔJlNÍo’©+¬OXÏ1Ï-¼§c-NÂ1ipÝ›í\AÖ
-úêì`uvdé,RHžê$žkK‚>&Y ¤ºÛ”OØ&â„o™kâÆœm§Ù WëÙÉ
-¨œ/û«Ð[BÒó´`Ûtä¯äÍN¿GfáĈHªýmVéDÇÏ“Ÿ”Ä÷¦Y_kÉóÍ+èü1pÇÒ¨åÁ³ñÂjD•jÊ
-Ga1Ã8‘¯YÛ«Ÿãн>½l•ê!¾™Ç”œ±Rš¶?àW'‡Ù_NÄåƒÆY4!aÔ„ø‰¥–
-/ÓLòFºVÕa¥¹òÞ+sTe˜1‘G·G]<ÖlI¯7E³±+’Ò=‚,Cš«OÒØor.¹kÕ /ÁÓŒ’ÍU±Hi~|ŒÖwÚkµqš‡~ƒ¸Ö£7ö³"ÄÇYæ…ÅO k_ã1fo4,ëIoböm5¹‹²O½k‚uÒ¥2ƒÞ¡úd‹j¨7W})“Þ‹¤ÐϾÑdT¥wÇ„{•ü¦ÒfËç«Ø™#K˜€Nƒh çuÏÏ%¢>ÞØXñÿàÛñÝ%rá§_&ωbksà£uÂÑj£«ÓEŸ
-ö:çkØ¥»ãÆðòvÏ5ÅΰÂÜ0p!.ZÍ2§.•`Õé;ûòÒŸ¾´E 'ôòL‹~­'"Bδ •RÛ…ê뚀ÄÌË1ú€Þ‚`0ýzл»-õ®‰ÑÆöø$·«|Â9˜ ühˆô`´6GÞ£h‹º¢:"ÎÙ;¾M¯_­µJ%îo%ÒÌnck—ý'y¾‘ýαšm¡‹¦ƒ”õíÞ*{ iwQ[™¤kžç Ë tîF!cö8äÞŠNßãÇx´ ’Ü!Ä’¥¼Ö¢¦¥Š—Î~_ó©àH¶ýÛ±1%Š–±Ú¹ Ͼº¦á¢Õ>ÝMÐAŸdZ˜Ê51Ýb1ܤɬUð/
-‡Ø
- օݧ{ÌæßÖRáï›I“¬ïØÃ4†ºéd`ðe'¢ò›KþÈé•ëÀ0 xö¯´ØQ¤Î]åhÓJ;ZL½"7Ò–ñà|êTñÌãço2R°×%‚¬Xs­üòc–>`pȸÔ¢D…Üo½I[«4uÉG ‡äÇ]F?bo÷ ¦"1I[#– x%‡x‹¹žÆɬ²×Á>Эs*´Ïühd&Cîx3Ôà9‹œkMŒ™"SàÈÕÍŠL€''ƒ™C¦eòœÿ@ËÞÀ4:%½BÔ‡?Ö´OH6c{h¦5/çÕ
-5’QÄ„Qƒœqó™0=l­\αç
-¥×$á_~Т:ò›l
-Û…úMÚ„m>ô‹'Á†ž§MýO³qÎCÄ]´5CXá*\•MN£dtWî
-BJ!•l!~X‡’Õ É•aó’1Ë"/°E©ø!Jü÷™oó§KDMk§Èéw“F±§Ûˆ{¹g,˜6Q4²«lía¤WÈw©4q’7_úU0"¾B` Ï"ø?(±*ë2­³G€ ¡fÓêQXŽŠJ5úºîÚ ñ%èÐäíb¡Ê¡ÓYÉ_c¸p'vÿЮ/]·mÐøD‘ /³îwòŸÙ|&æ>¡®GSÜ° ¯d9{¶£IóJŠK÷9fã¢éŠ ©þäÁõ@ñ¼9xŒi,P¾*=cùüà‰µNm6O—^ E› ªÖž©ÁôЮº
-M2tÉ»bqJCgª`AjI@vr]Ú@Ö *Ó ä½è¼‰_‰ä”/ú¼æ/
-¨á"R’´‰öÆ$ä ÚU W=ŽgY·'æýÕ ±M‘‚‡{}•ÜÿöA®ô5±ò½U<b´Iïqç·3Áì\³ù«çsÿ^«Qº×I?^s2XÉOzG÷6vïáæàæiðŠáãAûÍ6ü‘îav-œ2æ¯Krʃzs_4/“íBào[çç3r„¸)_&x†·¦3‘ÂÓeX’9iÏiëxêל-9ˆ‡sA\U Û=$˘¹¦G ÐñSÅ¿%ÂßR2õ«&öòôtÈZ¡EÇ£ÚùÌ.êòhnSm»Ä³=£Dý”Çõ6àÆœêk0¼îSF£4pºJÆßú „c¦…QØÉG‹Ìû,\…RXÒ<5µ[ŽwÂ×ó é ‰ªš Rš,¯þþ’\™mÄT0쪃ó‚×sõ`ÃO4â„W…¾lï‹Ãë"Z2µ0lÁ¬{¦'( zñ.9_ÄzÎãБ²þãbîÂÑëwS*ú[­FspÛúÛߤ_é~} ‹s\±š“fÿ{ô÷ÁÑ#ŽÊ‡/°² V LlQ9áŽ%Ã¥€T… h(£Œ"Îå
-Þ_#þÍ:ÑdŒ´r@SÓ^É2çQ›¨ô]´à8UY¦âq¿½Ÿžj_'åm~²˜O±ö òà –,®ùé‹‘c^·Úû…ç C)¾ Êt%E—fã$‘P9¼žˆã4yo(¢‘d9mšjW˜/¢qge>KмÎf6ÞÎ'2¦g¯,5ƒŽh­óçü¨6à«ÈÇ
-g!ò)#îLI•eÇO~,EbÛà ¢.ÈÁî=íõÙL(Bćơ=²a~¡Ž LÌjSȤk²5ž€ŸH½ºFŒ§WiWམXøwÖýï… \#A†%ñ³‘Ë2‘j Ç´½Û¡õ´„P2’åíC¶²‹’³o K,\QÛ²ÔŽ‹¼Ü3WÚ ‰SÁ™Û3èF#ëšlËñ°ÁºÌ¬§T{ô?êu5DZ—b!⺂Æn9Š#M‘y^Qi$ë\Êo#£ :“ÐÇÏq`{‹!ˆC%oÝË|°¢’N½`^¾VÄ:z´ßÂØÚ˜Å,Žž”\uyFÌOàø6ëÞÀ…?z†t+A×ÜéEî>VµÝ´çröt'ˇÅ<Ë9¶]ÄöýÞCðò—|fŒK¨ª£µ®ß( ­Â‹%SrÜ3ÀðYÙ%ŸT<RÎm*ˆæ“SÞÑ-ÏaŠC!)wȨÊ;ý&NÀêpêüôÈtöÅ;ÉÈ]¶ÇŒQÉŽ_@q²Óa–Û÷Ý n}ù‘Ûü¤ŸZù“íÓúY»hy5}îê]5P×*»a$G(®‹uý"»ÊÏc9‹z›”­
-Qm®­.
-_ Hf³ÚU;ì­^º~ÁÀÝ3µ5é øÚ¡ºø[\Ù¡&÷Ú;Mo9E*Ûí¬ E Õm¹lê·šÒqd‹¸þýà¡xZ¯ïvô£æQ¤䨟JêÅcFv£1Xc:bv´æQ43ÜËg¡ã6jÄK¸ú¡|R¹š“øÃ÷N7œô±°ÆDL³ ÒYTmN`ÄÔŠÓi
-öYˆ=~åÇk8¨ehúRZ^±V<£‘x–@#”"s•ýÇÚdÔIðP…®÷­•úz8*uÝKœdÕY…®Ùð.Ó©¬á.‚ºuÆTaˆVÇñŸC—nXЫç«j”«žŠçµS¹ Í[džN–üèÇæz ôÛ¶IµWV€A¶šéÝØNQõÆ6W
-ÿ·^]Ä“†[#"‡6]”ý¬…Xí=ïóñhé¼ÜmÄ%ýÖF¢WÛþª†Úû—tµdý
-á;¬/¨`>‘DÉF•X8)RŒ(êe+QBöìøYýú$ø𙨗wš4ÉAÑåFç[/Ìï(=Š|ú11ǹÌYfFã–s»Ø'ú[þµwù|¼ŽÇÛ,ë¢39i¯æ¼Žõšm!¸«uEÖê†î .>Pr˜áËóOªbeå£/Ï”£à?cÛ^0ô²³Ë«Lâ9}IÍv#VSgzºŽÙÑ‘ðîàê)˜¶©£p.´ÊI*ðwgÚË&)ƒâ²oUÌäšH€+ßÞÉ¥al‘BéiWŽÎG^ç˜ÀØl8„¬~ÇH/«æ5Àc/ý
-q,‘ô¡ÇúGåKco IÛ³ø©‚Ž Nv#j»£)Ÿ—“Ì·‘¶ý¤C±Œmm§
-ÄáÛì‡VJ@ÂyÜ4A“ß(9,”÷-mZË)é‹ò8ÕªÇ+“lvÕcÊž|:"Ú!ý XjñÕ,NÛO¤y|¯aëŸÚaƒ™z
-ùΦ*-Ír»b3‚Ë1<]#°Õ¤pX%'Lèw²ƒIýohZrI ®ìñõQ„è1šØ—×¾˜I×ì —UHð¢îq‡G[Y(|#8°ˆ ¾«ü Ì¡"@áBÔóѳ{¾¨'™†V æŒþžßˆ)Iª‡ýE«HÞË]~@wt<ª7çqÄEÔË̬´¥!yšj½7§ßÀÛ*«4øÑ?rê9ðgÅ£ŽÈKj…4HÍD}LÂà=™òâ1å7Ü4S¨r/êö,m@Í H΋pø^T*õg´ ²è‚V e™'&¯F€™ámyÛvîÃQŠ€X¿6~pl“È3ÍeôÆ`âå=õïÒ3(¬•éq7¥sšçWÐ)¿Ÿ•µ®K¬1¿!qÄI b^B,Ësb¬@¼ ‰ja¦•0?8ì@?N©¶ôÚo s¬y¡¸TF3ÎRer9IÎÊè7?°0x?Dtebv
-"q‚x”Ad€Äœˆ®wÒ4°ÈJÙ¼­Ì8ø¿Wöwm B\ëê ìáQïÞÌæºÙ2çŠ'=|J¸^Ö{~ %ÒffÞ2*„ÿ¹UU£î[œRnÖûÎ ç äà/︊»æÕµ±úøÖ[²@“¬½¡Í—5NCCOQ~Ù/N»ùÞq¾!ê ‚„ÙHÔÚä5Ôû3õíya÷UTE‡3BŒýóGN½Ü‡ÄlXþÔGõ“) Âå§aow;é5’-Vy3Å„§J%™èvsQ¾ó\¥Æ0wW˜jS4ÂÒlêWbØ9z%ò¶;,_*EéÃŒ¯ïw1wÙ=ò^D%IßïÿèÀ ‘´ÃΉ™ûÆk¸ß‰y(@ÞqH·DêÇÊQsfT+Û©Õ©s>ÁK@BªB¥¦¤¹já»AÙSg(c¯Ì^¹Ÿˆ<H|…vøuMgÌ[¸åßÎ e7wjrò2DüÛ6dlœ H.)=í:{˜;œ5vrUå(è
-«°;‡5Î9ø%ÏçL¿ôw_†hÝ¥‰’ 6°V…
-^”ØD>#û|ïzïÔ>Œ_ƈP‰ÌäFY„“ðÉQ[ÜȾo £zsT¸8ŽZv?=ªÅHAÓB[LÒÒâvl.èÆí“ÚGÆv‹7"E‰†O¥Ojn(`²¯—½Wb°¡vs÷;îù+®{¿ÈýÀX°«§º½[ŽÓì1˜'½Û6ˆUÊYø“÷dÌe`3ºæç³¼6àHÅ©ÜÁ­ ¾ØÅú(n°ƒù‹"uY»¦·[F’¼3  J
-ÓdŠ®ÂlÀZ(”ŸRO¹Œ»“69Û€Ìà†ûŽDQäìUJE5ý*rÍ@
-(§[$$Òè,ŠÕ%%yÔ »´Æ”V°ß{Ó(±3· Z„Ö= (0ÜHnƒ«%1œÍBz;¦ßŽÚsÌ9û=u›UÛþígàÑv±Ú9Ž{â’®0Ý
-ø%IÆãа¬"£H_|B
-DÈôZ¨K~¡ºy±'§«š—˜Â2ZSŸÄ*_Žs°¬¿áüy­•4á’DˆìG„V!3ÆÓä.¦ŸõÒÀ~Yx²ÚQ3æ0ËÉ*À‚äêJÛnïPýúúx ëW11u‚:Ow aA” ^†’ÃÆ„fÚÒRW—Ø(˜¾àBß|d9™eŸÇì x¹|nzç¥üí’]áÍOúåð;={É—êž/Ý„x_ ?à^ÊÃxVòWû‚¼%uÅ ºs+§iTO˜²ýôˆí^êÓqFÆï;ëá[1IÑÇ@ÑIÍEÃÎXq{tUå½ÊZ$ÊÈ/.·Ë3¨-Î ï_ßa?›@ñÅPlTÁLþŒ?iy1s•ÂyK°€[å>su ñ-UXr§m;¨:ª•Kó£*gò¤Åú‰᪠Y&–Ì1Z°ÏÚ¬½ÙQ‘~r"¬JÅÌ`\Š}‰rí&–¡[@²¦Ú»Eû($:¥ºøeÖÌÈ|½C¾Ö(ß~™„¡
-ö99'(ÜÛG(#?‚iÎä²q
-[(†ºÍ öt bÚ[·ö-
-HÉU
-’7ø“’ðüÅšŽ,<ëÀ¢ Ò½è ¥;KY±7¨n’7qÍþL3Œ8Œ@×SÿCŠtv‰jáY²Ž¶bb»¸iS
-ÕL;&ÜÚ社Q²;»UjNN{)òèÈù¥@Ã:è0>nOG"ýya,.ÉàÙ zi™TÄë:q!$*nK\Â)÷.¬’í8>‹ –Éîu¾J~&Õ†»M[oȳ©žJ´2Ëxy˜3Ÿ‰“ýÖ.¿”©tü.ó–5”Ï8Až «Z¦´´òÏn‘Kœ'‘[àõ•úV‡54›»Ü,eW~o§5X9mó‹jœkÑ$'<àYœ@ªùA-G-_ÚmVó ` «ú„£ù”Ó¹×”Šó“$È»²™©CÕr1¹"ÄÃ$AŠíŽ)й¦?¤Í0HÝÅŸàcËÉ&<j ©C@×Þ¶ÃtH.‰ŸkèA™ÎÿÎ!á
-u­WfH´‰6çÈPG
-.g4“Mâ'M¦ï(ŠMÑ|éÖˆð…õ²›ÓĘ#5Ç´=È•ò~u¦5Vê£R¯/®£­óHÄ®f§ŒŠN¿:¿lŒTmoú_ ˆ[O»1Â̤§ké&èIN†‹v@‹þH,€tŒt¦á>Õ'R¥•K.zgóJ˜ë(+Á5¯2ìkÚ Ý϶¨Â[ú3Änè^ þ^×ÌæQ¡T d`v+f<ñ'yжj~›q)ž\k,°ý”škQí—½`µ‰OÒ«cìÔ\,& šîJ
-íiW‡ fÈ“$#Ò±"÷qHÀŠJ\èWxZ'dô•ÿ
-'î»ìØ•Ë#>¼ºê£Z*¶ ?fôÑ1sm%$¥ž
-aþ2rž¯Y"`¿
-E¢Ì®_Q²HL‰@Zá~fNS^ÿœí^®<+9;ÚyÜúMtéÔtßæN9ïJAñÀئ{½ùMÌJXQ—DÎ+vûÔÕ†|bs”F-Ë•§EJ òó8}]ÕzÙeRéÀd.Ly’ö|ÿDl>Åõ]Ãh­W[®!ûÄT‡‡ÞuýÝ!"ƒgúˆ.’FHD•‘õÝÖÚšgì$Ð6MNâjpx#2ì,y]®“ê™ _ŽwrÀ% Oqp¶,Ô†´}–úy.Ì0ØÖ³pßãOS*³ã‡ïwâE †ó0m‘¨ü…YiEµ ‹X‚EiyÂ’“ F/ɪô¶­‚´J´ž—‡@%aHøèÕ?7ôÝŽ¨Â'’J‡ˆ2LäÍÝDœŒŸh¸Ì¢±·,Žh¶è„CYö]Ñß´­úgmkôfÆ#ÔíÈä¡J¸Umßý¶ªæö1ãïÕâ•Æ»Å†-eQCÕsoŸ½Ø‰ Í™ªLlmwÓšÞ—Jš¶9¾!&5#é»~kÃÓ•±9wX§Mk‘ŠHg¥éÌÐ6ÓÂx̱Ùõr>%Cçñ#ñ“(ž¢Rm|™$×B\µÉ AvV7Áû¯…00À(ä1˵ÕÝÝK¦Ü¹Ù~éo»T9z˜~Yã{òÑ=Mq0ûJA «ø}/£1Äí«e—Ѧn/*ómF¿Äxù q¬äyJS*\€d­-†:¯Ø]yÜÔåTƒ‡¿øƒØE@ÍfvTü6íÁ2~lW=_xãSeþ<ùBÐÊÒm"¿‹g|£žŽ/>¡„ïn‡œ0'OK_5b«F¾ìؽ°`‚ýÔš´ú&¯Ï¸?`;ãõð æzâŠ×=k-"c ª)k¡@2×Ül SÕs'tÜ«f€p!Ó«‡¢¤H|ö‘¾×Á[ú 4ô‹ê9_¹ªÒSGUPâI%¸5–
-qQ)[‡ŸäW=Òлe~ÙŒB‘»ëó´#âý mω;y»Š%üŽ@D$zfªéA%OÕtØ9ø»«óu 6’RáÞŠxƒ„ï”
-2:RÒ]š¡¸\•´²DÊ™º´^-;nðÇY~þ0Ÿ1Í»PÒø¤0«¬}¦“?f0­úÙq†cŒ¶[ú¾;¶96Ø/
-P„ é*Ë~fûiöðÐÁ± y;§‹¸Ãà’ßÐpù<3A,
-HG€BÊ!´q<6õûœp—-HM¶Ýu'¯ýôhË)
-Ûs'&ÞHË¥Á§õŒñ¾QNç—‰Ÿ8[/»'ÚýtÐMs¾Z!Å7ÃFjA¡;Pì;ÎÓ<Ø:ô‹hX[ÇñxWÓ·MéxWÕòћӼaç~ݯJürÎÇû®³`ù²ÏÉF™m¨1£áú§U, Å€ÎÌ÷;:ÖÇ9½èyÄÂ1žìPUºÝS‹QRUib3íWëA(W×â“ÙÅ€µ†„äõ6ú¡Q{I–àÆ/Š†#¿I¨
-RW¥Ï
-Òd<—ñ*õ/^›žˆu“ ”Ö†´06f¾Dx>É3ÓÐ6 $cºŽ~{V
-´.ÎlTÖ±ð`­çÐÖátžë¾±ÉŸÜÖR)z’ºª^ Å}bû»Îd7
-Á~‡+Ò«‡´¬©Bcá#šUQˆµ»ž2ßÓ5:a]C>+×­ 7ø×B
-lwÏÍ ¤Á;e£“/~Å©ô6€bDPö€Àì5 ßhàdÓ'±1ãŽÔH®—äI¯Ãz£íFR… R꿧ù‰´Ôö~ZB‹µü|†šïs>vŽ(B¯)ˆä<µ¢+þ‰>wÓ*>‰v»P°ÈÒÕìn݇32B‰;¾}0ñ\d3í•©Þlýöu>Ø5¹¿ å'Všµ«7ŽìòÂn@ÐŒ_÷ u,c!Üy&iÏ6I¿ÓpǾ
-I3qn»#q.¢+j¨lx¥šÏw$àmE8L/ëÄŸ4
-i}ü8c©+V\‚ØH}Hȧ¿`$¾³O4Waˆ©þ«ùůµbâbõê¿Þ™þz[›aó¬^QÅç¿o¹59ô>Ÿ%{q‡óx§òêÕ/ ìŸ)¨1£7i-ɉ<ô–Îy×`áÌ~)/B,ÔŒÄ ’$¯üÈà‡Š} Ðqƒq\­¸Ôä9XÇÊ&Y Ä~ÛÙ?FÑ«âÖ7AhnzräÍç$"wÅ:XÞ#uq^ß>\xb1Ò»Ïtá6J•ßOõ;‹ŽÉ–a¨Ûß„f {âe# zP$ü®)И'´³ýyòÓûÕn&såÚd´‘ôòh0×Qš>™ÒsA”>2Ì„8¹º—£q}ªé·Lm¯‚Ódx¯N›GQðLÚþ‡Yô2V÷«½ 1±ÅµXè*ýõ ÷q¦69+ÛÞ¥Ÿá0ë8õ¯Ü§Xî´ÏÚæs>Þ¡v5js+¹¢ˆ´Qaïe÷
-á°âÐÑÄÕ—bJŽãû—"oRc¸°€~:ƃKÚX^ªðTp—£™#›2¾&úÑj±7ÊLåzm-5?ø± %;7Ü'GÈav&³}.uƒîãÑ-ÏAmixûÞ ¢²c
-MIª\ÂuTØjGI-gýÂÓ–GâydføæÅxÃÃ,oÛ.رÌ*_ùSÕúƒóØCkëÚ™­¨·>]ÙrÿÅ:K¥ÓS%œx
-æ¨5-lçÖwŠ?v¹Í“!‰P£C´é¹2üÇ6$í.ªM¬—¿òÔöž8ü¨=Cî<:6¤Ò*À8€Ëi¾‚’¬ˆ§eœxÁ7gSL¥]ü÷MÁl϶É_LÎ[¯>7‘~KÔC¿ bÖ¡ùMÙDSG„l,Ô±ÿ…ô4¨·ÕõvOój˜ývXÚ‹>N]'#èØÌ×!óþÇ7îð*xîG™õñÌþÀ!%aóЦ_èõ\{¸®qf__ÌjävU“j3ùêEo/ž4 16ìž-AXðIŸsþã¹ßZI‚–>ÛýNA¸­s´Kp‹²ê˜"ÏGx ™?þ³Kl\jß»¬“aÒۗ샜+€uÊtC—hÇîá•
-¿n$rÝ XðD˜t ÎõÓ…”2§—n„sÞmOÆ„ ˆ;²ÃßshuåU9ñÖ&;y-sõP~K*ªÅz4rnp´}ª÷œõ)RB—+«å—>¢cI£Ž¹w× éhz€Ì\mm £MúHþ×<×|Ìï­&‰ Ÿw³s£Üë+\?VË´<=yò‹ØH»M'²ñÑ67Cøoí+A5x5½·x¯'_Ë
-c!vÜ~óÓ4¶bIpµP]ãH^ŒúÀnkLßYßÙ„æÀ,•‰)tCœrÀ‘ Çi†Ï±m$hýÈn.ÿ¶»öO¿ªWÂ[–{OFChÓ'žWùÆ*6L‡1±’g^H]u Ââa3ð¸g@—TÕL_1@d7¾ùÁ“†µ‹Œ:…‘XF.ÿ§Òfb1\ÄñSÙ£Ö®TÁIS ÒŽã{9.´ v´ôPš_$ ƒºÃ™.T€Áj”¤RÚ.zàÂiXÎ^;-”ûkwå0HMKyÃûSc-‘tkâôk'a.*bí Û¶4ŠdÇ&ž*qÉŸX‡ÒÝÓä"c°4 *+9‚3£
-cáE¢Lg%ãŸïÁó§KíÚï©=ëg‡~Q)œu‘Še7@ô`­¥¡c˜„s2¬ìe/ï´Ã÷5ØI*·[ÔrHîD4;"«hntRÉ´c¬¥ŸýÝ„u å{ÿÁØ }hë …
-¯41¶{ºQµÚâl·Pãg;‹($@QQ~:ú4¥ /麞e„¼æª't“Ê>~œÍÆTÂ={š÷ÈcW ä­ë6Å͆ÇIjË‚¶{Al ¸¸ ²œís è¹”Lª £ÈàýÞùqœöÇ=*Y€þK
+/Length 17112
+/Filter /FlateDecode
+>>
+stream
+xÚ¬¹eTœm“-Œ»kðÆÝ‚{pw×Æ¥qwwwBpwwwwn‚÷/Ïûž™9kÎùu¾ùÕ÷U»jW]µë®^½š’TI•QÄÌÁÄ\ÒÁÄÈÊÄÂPWÑT2¶µ56:È1ª8Øþš9()ÅœÍA@{qc9@ÓÜ nn
+`c°òòò"PÄ=–V
+R
+ššÛ»˜Ó,œ¶ÿ>
+üfîajîøÄ
+hjcÿOó9ÿ ™Û›ý÷úÿÊô¯ê™åU¤eµ5èÿ½Ê¨jûw¾ Y¹¸ÿ¡ôw@jžŽæ€ÿ•NSÞÁì?ÿð‰Š:x
+2¶7û;nÿiø6uuvþ«ò¿6ÀßëÿÇù_ƒonîanŠ°¾â`Êb‘ ªÃÍ™×èc… u,mT+* ¨qèõψØå­4z« ejšáûh÷\>s|?üFw4Ö‡cKÝ›f~ùЗœ¶¿ý'U'7ýQ³A)ræ¹fŒ÷Õ’Ü”‹ÆÑÞ”²ŠAÉ ÑL'»3ÜÕ#m
+‰ªV¶ý^]n?É÷oŠ üÐìæÇÕQÿÑŠ´Këñ¯0AÙ¬ŒÚ#Ûõ½ü¶Sz_“Ò¶Âæ°Â¯£Z¬4¦×âÚpj~¿H]c}jÇyŒ{ì|yz0Òä$·‘×ù³›'È úKåWµ0wïèåóä»÷ ¦¤†®ßëÓôäNg@«ÔËfR~7øX3X¯§º<†ž‡:;D݇Y‹’‡±ÇƲ ¾qv"©Î.嶱8Á[Ö†¸gÛyŽ
+‡Ø
+œQdÓžˆo¥j›*÷ú*yèõA®È›ŠØùÞ*9Ö¤û¸·ÂÃmÈŒ¿Åû ×táú9ÂÌ¿×jŒîuÊOà7¬ä'½£[»÷HsHs¢4xÅÈé ývÞh÷»&N™3ï²,ä¯òàÞ¼«»PøÛÖ……Ì\!nÊ—Iž‘Ýù™,dsa‹™2,ÉÜïéÏé›_Ôn8Zr烹ªv{ˆW1óLN¡¦‹JD¼¥"eéUMäãëj“µB‹ND·ó›^ÖåÓܦÙv‰çxD‹ú)MènÁ Œ;Õ×`xÞý¤ŒAhàI%Üú áG`¦‡SØÉň,ø,^‡QXÒ<5µ[OtÂ×{ù…Žö„F×Ï+N•W¾¤Tær U Œ€´q^¾tÆ^?Ø|%uÂŽ¯B_µ÷Åás-™^±`Ö¹Ðü|ñ.ù½„õœÏ¡-eýËÅÌ…£×ïO©èOÕRÁ]k¯þ)¿ÒÃú çøbU'þ÷˜ÀÁ±CŽÊ|Øo‹VÀ,÷QYáŽeƒTÅ€4ù`hõhÃÌ"ÎÕ
+¾•Qÿfí2FZ Ys“^É2ç1›èŒ}´x•oøLÅ~êú¼Sr6Ã,f“Å$ÖÁ~¸!’Åu£Ã¾¹fu[¨½$|8GŠ XP&k©:Ä0[gIJõ„ç)C‘ ŒÄ«é3TûÂü‘ë8‹( Ù‚.àu6s v>ñ±=ei™t„à cþ9
+ËžŸÜxªÄ®»~dÿ|°ƒÝ{ú볩P¤ˆC{TÃÂb ~3˜˜ Ô¶q-ÖTkþWBµRè1
+œ^Å}÷b"áŸÙ÷?'q ‰–Å/F?®ÊD¨%·ŽÐrm‡6ÓÃȈWw[ ØÊ.K.¼€–X¸¢¶ei—ùy¦ ÚI‰sÁÙÛ èFCëšˉ°Áº¬Âì§4{ô_ju5§qWb¡â:‚F®¹‘
+£MQùžÑéÄ›—\Jo£c ÚSAЧÏñ`K¡ˆC%oÝ«ü°¢’N½`ž¾VDÚº‘´^álmÌb'OŠ žQS‚sxCþíº7pážÄ!Jà wF‘›UíG7íoY{º³ÕãbžÕ\Û."{Š~ï!x¹Î+~SÆeT•±ZЯÆ7
+«ˆbÉ4‡\·L0<Vö†GÉ'e÷Ôß6ˆ'„ )©oè–¿aŠC!*uȨÈ9ý$JÄêpêütÏröýr–™·j«œ'“°ˆâd§Í,=~è»EÔúò#¯ùI/­r˜íÓúY«hu=}þú]%HÇ*»a4W(¾‹uó2§ÊÏ}5›z—”í»¹8NÒ7“;ðѨ
+›ˆu61j&všQÌ/‚·bénx;Á8G̾
+Xþ®qp…rÆm`‘ /Iï¨ë‚‘;ýR¨•å)’Ô`m ^f©>¬OÛÎ3[~½›ÍÄŠ
+x¯°&ù.±óh|-ö¤² K¶ÉÉ6 N¿È¿ð.·ÐøSýAH×ú¤ÅÌÞ°—‘,ŠeV®D’R¹ÏÎ_ƒ¢‡):?¨\)Ì/
+ásÆ#ûÝaØü¾C-(^Ÿ¼,•}3Ûð–VG¼:Žˆpöø ‡~fê"¡€«ËöDñqšû„\ãL={,Y6èsÓö&ÿRžéã ÎvøüÆ’ ©—2[<Â]*ŽUÍö~Fº*Äe¤A¬
+‰&$_׉<%@v©Ç1‰4~å¢få¶_±Eû´½ó*`,ÇÂÍ“)‡D7^[#¨eNÄî]›Ä|ccÌ.g‰æRuõ~êP„¨ö­þ²øwâ¯Ú ¬9ˆÆo Dà{éøk JPÔ箫¾<àØ¡{ÒŽƒ£H ˆš9Û¾>,v§ßÚˆ37ïegiZØÃÎ’~92ïc¾q`¼„¹WËmÞ/ŸªÈ"Ëùtþù¡Î T¼ 1¨3
+ŸáG®o4± ÖQÓo$øµì;ÑbV!ûykAžÔ^¶ª¡/©ƒÁ7ÙÈS÷ƒœÔdíMèSAˆ2xî^vΨÊXdºo{g@½ËZǃ¤ÃMp¦|€…¤}øí«š
+¹˜%AÇ©OOûØ+VÄ‹~{HŠ¹l…¥mß,+?(òÖÜþòHaöjZ<Dgº¢(ˆSN÷jÖI€µž„*m÷5eÉ ø;ë'{ª´äú\U·®¿nâ8¬÷Ó‘àfä
+,"õRbzR_'Ï4\ÎG-M
+ælSŒNÃ Ëù}ì3½ÿÚ»~¾-ÇÓ]–Í
+ÑÙÜôW3>Çz¶P\üõº"kw5·D
+(ÙüՅ'•±²ò±—gÊ1HðḶ Ýœœò*ãN_RÓýÈõ´Ùž®Svt¤/wpõL;AÔÑ8—šåÄx{K³íeS”Áñ9UMe›ŽˆÍ×ßÉ¥al‘Âèi×N~¾Î3±ÙpYbdÕŽðéa/å…8•H þÐeý%‚BÒØdÎö¬/~.¯mŒ“Óø5­ÝÑ„ßÓIÆk´í0ùX,ãHKKÙ©qä6ç¡•ø;~¿Éo Šœç”÷-mzË9é‹.òÕºû+Ó·œª7ÆÔ¹ D´!úÅA±´âë9œ¶a¤<Ïë­á_í°Á‚L=€@°ù¶NM¹•íô™gFNó®äìS!à{ù²gâA}*ßZ¬¾"L;¡!&{SºGÚõvÿáIt˜h<Êo`Ð W•˜÷¨º=áp¬ ]3#"ŒBŸtª”‚¥‡˜QðëÿDŸ°Xüù§—K`!6ïH©/ôyþËZ»ùc¥ÏÇÖ™„ÚÝ"ØÑ6Ølšä–ãNdn>‘W¨f4Ý…ÊðB÷=Iâ¹²ÞDŠ¡éóñL—eMåu/÷r5ÒÄØù?¶ßíž;> #ØŸ#J¬ïíýwÅ\á0NJ]þî\wL‰ËW) á«jû콪:‚ÄŒq˾t/eÖ’Ÿn…‡þàObë·¶tóÅ@Ý—†v9p%Z§ P4n¦khÛ%ý®äÇ=v±¯l8E45)ÂcŸfÕ‡³QùâïsÊ9 YbÜ„ƒlï^ë)ý—$ÕŽþ9%AÊf|(—À»‚††î^müu¹ƒŸŽC©¢p°°ð(3ïû{TªÓýᓘï,îÍÔ}»ŸÇ4¼ékv× Ð·5™\Å«ñNKå'®ÌhüMÁüúîVµü~¦@Œ1ÙYЯx¹éœI¶ä¹O¹˜ N‡6õqéà/ð¸7^–@€OÜslDåÓîjßËVS!V6U%áÇÔaDšò“£u»7Z3c‚8p€È3˜£Iº¾œˆ²#>‘¿ŒRý­Š˜–—œ-¤®ÐáZhOÑŒfuð4± wCóÀ:t²YÆ
+àé nرn¢YoIêŸ<vIS Y°ÆÒŽ5G­æå0Mö½Aˆß„«ÿ/kZâ üÂz×bAdð)9Å’6Îö‘Ðk¿Ý§Ä7#ÀjhD(ÅêùÒÓ|[Cªé¶w€áàrÏxéÈsCptE’÷$eŸ‘ƒcö2o¬ÝœSaTS¹/]v¶Ag`æÆ¡¦Á§GlÀ¢?væͶuŽ+¨Î_¸¤ k1¡v=œ°úš§¼›:ܵÍ2¯·^&,ˆ(:˜Kw²´.Ðf‚fr:=P]_ðµW2Vƒ4‹"úCñSðåÙâ­°¬Ø «õÏR ,{zvþÉ ûÕ™€”{uuVœ¬už‡ìNŸûâˆl,
+_… Q×G×züù²žxZ5„3&° S&áŠT›D«HÎÓMn@gl"º7÷qÔEÔÓÔ´´¥!e†j³7·_ßÛ*
+«4èÑ?jú9‘`¸âQ[è)µF¬j,>.¡ÿžByù˜únŸ‚)L©uwŽ6 f
+(ëI0r/*•6#ˆ,º¨YCYæɧàIfðcWζ{À`Œ" ίí+¸6¶qÔ…Æ*zcÑêZ ô,
+keFüŸÒù
+d§'¬ö ¬Âõ=¹»+¢Ûžß›-°6Ç´mQ@hbQîÀ@¾<˜õJšBHçJÑ#ëµmVi¸×0®*YEáœ
+ÒÇ™¼ïw±w9=rž„%É÷¿´á …ˆÛaçE„Ì|ÔÝîÄOÜå!ƒî8$á[¢ôbIe©93«•ìƒUëÔ8Ÿà% !U ÒRÓAšx®PöÔ™JØkóÇ×ng"¼Ð+7tF|…;þí|PvùçÆg/CD?Aæ`CFF9€”’Ò󮋇ùã9#H…Kà{p”¦§ó×XzƒÐhÃƧ ×´;{ØÉ…OÅY“óç"÷
+ãÊÅF_ÕXƒÖw_¡ØKèJVDËXcïEhÛ‹Ô— –ÙR¡pŠÔ€V§éêÆÎ~'%œjeö¯´!ç˜ö: cf f(æ’"äËèÁØ\ûÖôùiÁ<„îvÔÏ:¥•F²,ÎÒ$£ÞzvbsÓÚqÂQ V-/°í-2vŃäƒHì£ ß¬«&ÍÀµÓ©ê^; çÞÇóó~ì/ŒŸ ðþh¿ÂÞ Á†ž^tW÷´]þ¿À·Õw2tIW1‹*íàNk-ûÈȯÃîoÕ8çâ•<ÿfZÑÛu1¤u“&LÑßÂZ*4|Qdù ˆêó½ë½Sý0z'D%4•cŠHÆ#Gmqu ÜFu7â¨pq³ì~zS•>¦…¶˜¢¥‡EíØ^þ®Hj×-Þˆ-11e ±%ɾYö^‰Á†ÚÍÝïx௰éý"ûcÑ®žêön=F8^£GônW?&L1wñWþ“—¾Í؆ŸÏêÆ€#§R·¼ÚR룸þæ
+EÚªVMo·Œ$yg@;”¦ñ4] „逵PØWJ]¥0îNÚ”}0ý?ÜwüÄ
+"¯RÊ*×Qú(­À4ö³)FO›’ ‚äêàþ(ÇÀN-ÅBÁÚc·}2«Õëé¢~ÒR¯ÛûÇDã]ÛÁ›75ÑâÛ?}’^¸Ã/T89B"j':up·ýÁÀËuŠwX¨ôN,[œZÕz¡jð^[éÐÒÊB¬ ?ùéˆ&µ_8èè¯\¿T~+¯þzF¹­õ ã+¹6sÕétäïøë÷’ç6é¢MLqý/V‰{k˜ÖtᎭ 5Â3r;þªOé‹-ò°Yüeå‰4Š\uÔ®¾O½ÜlMÀ¢€rº%bABõ΢8ò1âGÝð+kLiyûƒ7õ;3»à%h#üï[)ÍápµÄsÙHObgÐô»ÑŽ¹?§Çe×ĵ{ ì«þ&ÄqKZÖ¦ ¿ðÒ;qÛª47·‘)<´ 2‰Ç-Ò¸6,éó}›‰Êá]Â?…®ù6Çœb„5ÂxÀ ž^èvíÙœþÉ ã…~È’Õ*Epב~솳ŸP§Í!ðœÚ ^*ŽÒ¹\ÝMÙàvu¸2ÈL].ÍàE´”NDJösö–êä*\Ðqeùšß±œ²ƒ¯êrýrxÍ!¸ï%ծΟÖòÄͱœ·qšZ%ªæé»V7äÌ¿%þ_ÿVš*Ý\„ÊÒ$ǬÇ™Va ÖÃVáÙàYú#gXõÜ¿Œ²ÕÞ·èêµÁ),|d œ¢Û¶†ñ;îìSJh"¬t§?ßyiKYLÚ´pØŠG?'â{âÁ:ì&~&¨*Ir‰OŽŠÜô«þaÀäOÀÝ 0ØÔ››Uñ@t°'Âÿ}û¨ÃšA0IùúL{—p.ðZ¦{xyYOÛ–©Äï´+Ü sHuOŒ¨ÎU G£–@¬Èo`ñý"qà‘±îø•¢†>MÅ€žQg¯¦ün(Nß_äz[ òô:ÕK œ­²S—|vîc50ð>rá*˜RLZr§±æ¨F÷ÓËÅRè¯%ùdÏÌnw°GAš¤’€\êÌp½{ë;îÿ©£1ö§¤Z…(Œ£ŸâÓlXzøÓ£g®éË7âE–$M@òŠŒ!‘ø„~!Óm¡.YAuõdOÉP)$0+17`´¦>‹Sºšà`Ù|ÃùõZ+iÌ%‰Õ-Ž­Lf„1®Á]L?ç©Žý²ødµ§jÄaš›ý ’«+}W¸½C…÷ .ìñHÖ¯b sú =l!î‚0Q­ %— ̤¥¥®.©Q0cÑ…2¡ùÄr*Û>ŸÙ8ðrõÜôÎGùÓ%'§Â5æ+)Éñ;wF$ö’/=Ô=†1Ñ¡*^À½”»ÑœäJû¢œ%uÅ,ºs+§ItO¸’ýôí^êÓqVÆ/õø­˜¸èc è¬æ²ao¼¸=¦ªò^y#et…Ëõêj‡sKÆÝ{%&é³ ˜P ÅFU1ÂäÿÈ8Lˇ™§”ÁW‚e¾Sî3_×ÐR…%«~Þ¶‡ª­R¹¼0Ö¡|!GZ¬7™D¡ÂmlÉ« û¬ÅÚ›å'û!ªXÌ Æ¥Ð‡Ÿ$Ûn¬ßi¶cNÖT{·d­ìD§Xw¿§ÄšU ~pÌßíÛ/“8
+—[«R^i52)úIí 8Ž?œðí•(Hù%‚¶§q‹©[&H…U½3È’PǃjÞX¡(ìÁõJ[Ú(y4\9{1¯€kÒ‰X)×'Ùʱiüƒ²{æxŠH.ž?–… Ý®CÚS‹|¦iŸÎ+—^Pcª(¿œ($&:W§||RÏä|ó­„Ñgx^­ˆI4¿,]…ѧ <‘å ãÜ5u@܉Ü Š4
+î~%³€8Áj·ÌÓ¥í©ªf‰¾„ö§Ï‰óçô$zƒ1Ž¤PP9*'+p9øx3T.Œh“öJ™¿Âõæbo¸ó¾4¯íò¯ý ~µbàÜÄÆÅëº
+ÅïBú¦·bF3‘¿Rm«v—¾NhŽµŸSs-©®Ø Vû$ß±:ÆMÏÇa£é¬¥Òžwu¸`†>I2"m)pŸ†¬)LJ-sE¤wBÆ\ûàx¼uÁ ìàà)†ý®?w-þÄÛóS*‡Û×wün>òîº佇1©úìIn\@Áû‚#–ÊI£óþmü€Êå^MåQ5Û†ì+fÌÉ)sm%$¥®2AÁ*r¾¯i`ƒÿë÷/Éf×(’eŽpý
+’EbŠøÒò÷³órrx¿Ùî…Ía"”æ$çÆ:O[½D—ÏMmî”ó¯åŽŒlº7›ßÔÁ¬„dp‰e=ãvÏA6ä“Ûc4ªÙ ž)ÊÏÓŒMëU—)Å#ãùp¥)~Ø߇gºte © wuÃ^-Ù†œ3m6vxÐ.ú»Cd&ÏÌ ]ˆ
+%"ë»­µ 4-ÎøYmº¬<ÄÕàÈVTøEʦl'‡U3ž,3îÔ€K6:á…Á ز0ÒöuXêçùpƒ$ó¶žÅûšR™=?ì¿3OZ0œ‡‹œ$%fÅ5•.," ÅÕIKfL&Ýd«ÒÛ¶
+Ò*Ñz>~|åÄ!á“;Tÿ¼°wc8Â
+Ÿ(*mBÊp‘77cq²¯„#eµˆ½eñ”æ¦KN84e
+þ&mÕõ­1Û™P·£SÓ<òÊVµ}÷Zê§@ÞMë€<€¬åË&ûqÝA_ÁXRz½–¬X;w3ª¹BË?#,d?¥®‹#{œhï1»D‰LÄшÔ]Lª0‹G€~8îK‹žo H]¤äë®ü²þ“’Bö¾w€Ö:8Y2Ÿo¸È£Ç}ÜÕV%$Á½ôK”t³ 15^@$N5k›¿W²àéîJXɺÝh‡ŒqÇ^èð ^—ÛÁîHú¸5<ºL~_ÜOùoÝ#ãP ÷C(oqZo~„Øq}·wy™søÈ
+Îs!V •ãrMLñ<'šP¾ÔŸ@¸WYÒ‘wçÿò¾Òç–Ö–V.wÚº7qËw ¾y2obW}ËÐë£ ~W·Àg¸sbj„ȳBMt èi(\­ùê“í&×ÙzzÁð4#C®­x@åHCK‚[ÐÚ¤[Þ#Ç©rÖ{°“ÈÕ84S’cmáË“áôÚ¤È*§6MM*sËY$:_Îñ¤C“Ø“›Ó¬ªc¾ìi'õs1z³vØhæ:¬—µ¼ÙùÆLå†Ò–³i]¨W@†–M˶ڧ‰I܉U¡€G‡•
+ª'>Ûf4C¸MvtrZnàyTÉZÕ$KËýaGåEìÝ¿krÀ‡~fµŽúî„ÙGé¦éåGa5ÜÓ1ƒÌZ[\ U¶…\Ðר·ü¥ÀæêÛ‚Rèmà>ñº4ëµ÷VyG~ü½m4ø0QÍÏ<5&6,Å*Ô" €öºàÏ`]M$¥¹¼$ûË«>Sîy
+i¢§£ !㺲”ÐÙmPžY1áÈU—¬h…øƒß'p¿X²0«Åû×N¿”UVÀzÔvƒÜšýâ„å®ðÕæjæ–Ä9Þr`òٷ…Zî¢ôÃ5†Q¯„ÿÖež&Zç:€âÜ3ùO7î•r+B«(ô]gþÒ¦ÈÑH=Fˆez u±!DÓÆQfl³C%q§Kõ¯ÏÖZ®^®¹Nˆ;–¤ßÀ¨ZÕS¡…ÄñÎ_\‘닼‹óDo®Fø>¦R°ÝÍj‘~É÷¯[÷oìÄæò n?[Œá)m’@©—‘Œ1´bÖ9Í­n8-MŠÝšá_jÂå­êÀ:BÝ{8J4 4q†ea: ý>F‘-¼ªø¬Oð…àŽóMA1bÒvBŽ0{«i~n"É(ãUeAqò`Z(سRl8ì|–½v:øŸ”‚'Š’^ÄÏlÇ7…·}¡…4íKœç:©ú,X…¥­­¡bt‡~Wî¥öÕcE«ÃÝS‹†=@å ´Ê×æåóÞ=hj3áRe*ý¸
+Cà ê8ÎÉ]Özá·}6ù\ø*ø1B%[3DŽG
+ŸH¡ó5q¤Ã·i±‚”p³×S“š¡¬p£“ ¿ EûÙc¡ó,ßlÁ5Á²È¬íŽÏl©-fͿ궘SOpø¼5Sy˃øú¶(û
+.3Ÿ– §ï¢Uí,?H-ýÖÒzÆ¥¨>#uQ4ŸÕÃJE,°NN•SONãó‚©;0ãb°^‰Uåª<& ²Nåð I[•Æ«çº´ÉQì\ïåºÞïñ8+ìNH‰\¶¥S‰)½0@ÌJ,yßÙ ?3FçÐi®“©
+X%Ž…¾‡¸ÝëÄìk|ßâðmbØ|¶®¶LïÄì†Ùû¸ä¡›¿å4žUt§Í-Ú'ÏxñwÓƒhÜ£¬N¦ú€·$:–©<©?æÌ"7{•åQιv – YRÀ¯Téœ'Ob­²)7_ùÖÊ$ùÐGDËky—Ý·¢ÉŠ†Ý¡í¸ sx¸ ìqŽ#cßê©Ê±•góf©õÏ)mé¼³_«´`—¦„j?ùÁ“³Û)„„)F'ÏÔJL%%›«Éw‚¦¤‰¡g¸ ¢̪Bé±¢W>"BYÉ:VS=e=X|ùÁ±¨Þw ö¼Ž”ò°=èäÚD¢z*•(J":“–ÝæÜ\ÒËâ¦òUàñ+º¡îîñ,XbAeL¼Ásg]ÔPŠûÕ!‘I´+SdDÞÀð®¼b–ŠÇêqüÆŽ·ß0º¯¬÷Y®M»®¡J±˜|‡à6RBÃðšÍØøæU÷¹¨E— 9Ò­êÿ„l™– ÅÚÎÔƒ™­GÝê™ "âX[zq3H³Üé[‹ãq»©¦-ÚÞ,ÈŒ3:I{r¼â:Ü?#©+²÷%g² X6F~“K0'Òöé½0r=ŸËH“¢“éÞiŒúR7a´Böj»å¸’CêOm‹FE „m&V”'TKõœ
+
+¿*,‰Hç[`öR{w…ÝƸ5¹¾ŠÇŸÉz¼ÃWDgãX°+>BÃ]‹BámƒéIÜ_<©œ+V§UžÌGT Æ‚(ø‡Þv9N{ Óü
+Óúš"ýSz×âת 2\Ö´ÝõØŽHhKÌ´¥sšùíio=¶ïÇ·‡¾Ü⪧–AL!¾ëø ãt¾tblkMÀé¹7AÑ|e·šáfa$|”?²Å0ËvœÁ×°(Õ‚î)=í†þ ±T1ß<” î³ PÔÚƒÞzçäu™»Óƶ»]÷so›w~ª°äƒ]ÛG…,¡ñó!XúÆ‘ŽÝo-*d~}áóÖö2 §Cv¿*ìiëÕÎøˆIXrg]é‡ ³Yèîã`"ùÞW×·sÔ¿A^nÒÕùIÖÇZˆ‹ÕúMºpnc1à€ôC…M¯³ùmlU”Ø—Xz ­ìS;ÒÁ’½yXžMÈð›’]h|¹ ˆü¬a^6ÕévH£ÊšÈØDuöGÑwdp7™õñàéÖd“ó?¢Ñ>;ô¥:žu ôÍáS>3ÞÒ÷“ÉU·ák&½þ½e|‘ÝÛZuFÒ0  ¬±üÕ¸¢
+iÑ$Œ.ÞoŠárò"~ÖùôÕ³zUF•=GÉÝ©‚~éRÜ×h4ÖÀeiâw±žRü/dRÁŒTkÍ#wƒ0&§šžh,Gë±Ãñ°`¿pLsî'úm¯=±çɱe—~–¯#\‡zó,ªÊÃã•ì9»^Bü¹“ÿC=u°cDk þD8œ/'V¶4¥? a¶d»Ø\ñQ­mÓõ:F,ÇÇÔ²\ñÎ<šr9oâ\è‰ñÓ­b]Å»¦f;Uˆ#e2S> xV¥˜ÃŽ­ˆ†ê§—jŠP™­¸¡.!‘#È÷©voÔ`ÒSº’ûþž}°S
+T S!õ\¶ZãÒJ)¡#¢:sÌæÀŽ_îR·è¢#Ô¦Bò
+êOqÚô¡9U¤ $Ö=6Ððü|Hò‹°s%nS,{¨üˆ&õÊ’—8$²cå’6¿p[Žx7íj£\k@?®ð¶ "Ü<4s=3Ña½BÚ_Z¼–âç0h^×IÓ¡gÀDFÌû"O,v}V%t ïæûüH¦¼¯¸Êi¹ò¢Œ
+Vº<3ÿiúü`+zв±ƒõ¤âBy¿e5m¨á^[ÄyaS©aŠ€()ÞŸíÆÜ=7w3ÔV³Md& ðÑÈå’½Teöä´þe¢QŽh¬õ äØîαÿ”øg´>»6¹”¼g´(>\PóÔkºßo†‘vÝ8‹¥‡HZR¯±˜(rÔs•Ì7R¶s×»LíªøŠæüz!ÁÈ U[–Õ²69§QŽƒ.[¿’6çÏhüS—Wse®÷±dßbfïyîI‡dÁFbNþ%ÕgÔÆGœ¢,bœrü(šÙÂ%+'‹ Òl£g"îuªrC`Wro¦1€5ÇCÈ…çpû¶šÍÄ]sG¹ÑOnäàrqœìZI=…M}…)äCQÊ~ ê!µŸ¾Dz9·%eÞ!­û©ÆÁ”,Ý,>׿¿âb‰lGûrs RøV0' uV·ƒÔ) É ²;^%!#úㆹå"à÷È“µ‚i4Í p#Öo·¤_Œä%±!¥Óæ`…(`¢ix¸ü={Pìr {[£3þÝɶ*\ÔvµvÈÆe~0{zŠJ"É®Ñc
+µÄÀ‹í_~ …U¢÷íýwõœÅ6o¸JÚè¨OÊÿ7E®Õ?ÿm]~»úàD¾?œñŽ¹,à¾$ôƒc2‹™‹ãé¸æß‹M|&ìšp{³×Ó\Ì «e •Œ¤·Æý:®s”CrªÞr±[G^…_x[´?ÒØæå'®Öܬž ¥Škv5‰GlŸ뽺>QÄè5ó†…¼~šÒÙŽÝ  ÙvnÂ|*ÑÐaòÝ¥ÉÿÞ^á=tønÚÖ•_ÎïxPðdòùCß•b­RæwWbgÖJ?~årοþC¬[BýädƯ{ñ h§úÍwÓ‰Ï'}2~Ñ]Ø6å°âÙŒ9û ²&ÜÔîNÖñûö¡î±`luî‹)G2O=ßùEßCùä”Õùù[
+¹ÓÏ™wŸ˜sìÇÆâ@•»¯M·åöMXvºóEÿÿu9~Û¤k²¹¶…ê¼ ª?yÉg“º”òÌÜ{ç;OÛ«YŸ$3iÕæ#ÛÏn•8²oväóŽ7¯ã}ËÏëÕýÜá?÷þ¹ësÿ„æÕäÈ©Ù÷pö.Õ`¹fýO©a›K<­ÛNîêè=|ˆuÖïD©â¹µßýÝ^Ú(šDªM?T¹CÂxÝ;)ñ´g¥ÙENÓ/Û¾}õ%×ÊÛJ®Q†…É9©‰E%ù¹‰EÙ\
endobj
-802 0 obj <<
+1018 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
-/FirstChar 40
+/Encoding 2705 0 R
+/FirstChar 35
/LastChar 90
-/Widths 2153 0 R
-/BaseFont /XYWDPB+URWPalladioL-Roma-Slant_167
-/FontDescriptor 800 0 R
+/Widths 2718 0 R
+/BaseFont /MRHKYV+URWPalladioL-Roma-Slant_167
+/FontDescriptor 1016 0 R
>> endobj
-800 0 obj <<
+1016 0 obj <<
/Ascent 715
/CapHeight 680
/Descent -282
-/FontName /XYWDPB+URWPalladioL-Roma-Slant_167
+/FontName /MRHKYV+URWPalladioL-Roma-Slant_167
/ItalicAngle -9
/StemV 84
/XHeight 469
/FontBBox [-166 -283 1021 943]
/Flags 4
-/CharSet (/parenleft/parenright/hyphen/period/zero/one/two/three/four/five/six/seven/eight/nine/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/X/Y/Z)
-/FontFile 801 0 R
+/CharSet (/numbersign/parenleft/parenright/comma/hyphen/period/zero/one/two/three/four/five/six/seven/eight/nine/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/X/Y/Z)
+/FontFile 1017 0 R
>> endobj
-2153 0 obj
-[333 333 0 0 0 333 250 0 500 500 500 500 500 500 500 500 500 500 0 0 0 0 0 0 0 778 611 709 774 611 556 763 832 337 0 726 611 946 831 786 604 786 668 525 613 778 722 0 667 667 667 ]
+2718 0 obj
+[500 0 0 0 0 333 333 0 0 250 333 250 0 500 500 500 500 500 500 500 500 500 500 0 0 0 0 0 0 0 778 611 709 774 611 556 763 832 337 333 726 611 946 831 786 604 786 668 525 613 778 722 0 667 667 667 ]
endobj
-739 0 obj <<
+955 0 obj <<
/Length1 862
/Length2 1251
/Length3 532
@@ -11417,889 +14029,1331 @@ endobj
>>
stream
xÚíUkTgnõJÀ+Å€€¸
-æ2@ Š,Ë%€
-‚T†dBI& (—
-A@0¨P¹TZ)­`åb°¢àY#BAn¬\uÝôØ¥?wíÙ™?ó>Ïó½ß3Ïûó™™0½ Nl$vA„bHi€³›÷a €D2ÎÌÌ…!1îÄ0
-…•çˆSË=•ò˜>{~½Gz“¿ô©qªiŠÙóVïréLZ¬aôo·Â4ñwSÇ2Šg¾öÐÂ5ӯܑ'ÝP’2ã÷6»µ=²æ¾ÚÜfå.û$˜<h½êÒH­A{ÈヿT)oTš›Ëb_”C¡5¹Æ{žF…_¿sî >#†øeõéÃÏJëåÚÝõz î®{½Î™/ µÜ;4Ò(n’«³²Zî‰1~xܦ£ûÎÞÒGñ‚t ¾ûÚ3 —á¹¼ÖÈh<~=Œ¢e*ë²32ÿêÐ+Æêòµ¢‹M¢’Kñc‰´þc`ÕÍÎ.ðj<ãHN,c’‘¦—|-Æ‘ãí«,›7ÊêôzjÎÊä}:Æšýʬ(=…‰¬RÈãœÑžÍLÏ`¸{ú~©w¤9/)À#à¹ZÝ÷¢âYrvÇØ–„1u2ãDëËÁ «)Ѹ·6íRW©oŠ¡y$|©ÁÑf¦@Ó©üìzCä´ß¤û^<ÐÅ-LÎæFM¥žû‡é˸Áß'¿ßXBø)ÚrhB¹µ/{&nÄÍàd÷¹Ò£Î¡ºÌØ„Øk?n—ÔsDeIíÊ5Oñ7­;ýö= ‡Çe 3ajèz”Ë®8h'$Ô\×-”…ÌîЉМV*¦…­FÔO™àšÞ­;öL~¬}¹ÀkäÔŽŸÔKIëw5ئ«nz“yèy]?÷“пéÎúª_…çÍVWyÈúä—qæ7Jüþ—¡ÒÉðõù×nɯɉ.„Ö‰Öþ[E¶Tű‡“Êë•7Æ$ 7Ìe$åmÊÁ„3YlÿÒ<Ÿ‹?ª="YWT«š{êæSE aÐ=EÕ§´y”óÌe¼Âa²²ÔŸö¹÷¾_ã¨bÎI§?Ez“ØýB£®UjTæC¯J™š.Ñj}³•™Õ>ä1¨'›³²¤Sª×Hö5€4ûÝý†;öpæ.ü&µoY7î£HŒ¶×ñ
-ntÆY~¬óôç»Í»_sóŸ׈N‘Ññ‰ëüï«V©Ô§Âh÷åcĺ´ ¿ºï*T¦$ÏGlɺÞX±ëP£Ù»å¡Ýñ ³M¯-TßfV1MW÷-”TômÃÅê‚Hâíenáú„Qkâ󢄆ŽpæÀ\—$§!7!Ç]~%Šœù¤)ömµÑ)Ç÷D_uo€£ŒÚjîü5ÕñX׺™»÷àÔúBÙ˜«jU´fŸîÝN—²QÝÖ…Zöî–Û£Ž!CN×´$Aü6ÍŸd~M ÁÏ'/]sÆfC"b’“0Þ]°]ßp]¶Ñ^‡ïkšÇ?¡>œÝê9h;>•MsÊo:Â(žGŸ7ùñ›¨£ªÿµá£¿ôµè«êꎞîìJö‰u5k—¦œQNmÜÙÞM8±+Ûã1ãdß~ºëþ9¹Öê¤òXvGH½ wXÒ“í¥Ñ+㬠ìÍ­à| CþÜÿüO4À®n# Åý ¥]þjendstream
+æ2@ ŠMË© É„’ L P. (‚€`P¡r¨´RZ/ÀËÅÄŠ‚g¹iL@°rÕtÐc—þÜýµggþÌû<Ï÷~Ï<ïwÎgfâéCpb!Á° "@"HœÝ|d
+å†pD€…óg‹";À‰£\&$
+B
+Õ€PŠÂa'«¨@ p,XÀÌ1‰(@DØ
+¬Åez@.¯52[‡_§h™J»ìŒÌ¿ò}ÅX]±VXj±IXz)a,‰Ö ¬¾ÙÙ>PgÉcL2ÒõòB®%Â8r‚}µeËFi½^OíY©¬OÇX³_™­§0‘V‰‚¸ì3Ú³Y™žî^þ_jÄiÉOô|®V÷½¨|VŽœÝ1¶%qÌOÂ8!98a5%÷Ѧ]ê*óO54‚/5:ÚÌj:Uœ]¯b(Üö›tÿ‹º8E)9œè©´sÿ0}?øûä÷‹C ?ÅXMh ·öçÌĸœ,ç<WzÔ;Ô”›{íÇí’{B#qŽ¨4¹]¹æ)þ¦uPçáý(ÆñÙG#ÆL<5t=*¤W´ùjŽëÊBVwØDXî?«Ó¹õSÏLpMïÖ{&?Ö¾\è=rjÇOjŠ¥Xþ]íVЃ隃›Þdù>ï ëç}ö7ÝYõ«ˆüù£Ãêã*iŸì2îÂ&Éüßÿ2T6±¾àÚ-Ù5Ñ… Ÿ÷ß*¶¥*Ž=œT^¯º1&n¼é`.%)oS&žÉf”åû]üQíż¢²x\ÝÜÔS?Ÿ4(\‡î)ª?¥Í£ìg.ã•“Ue´Ï}öÿO±O:½øû)Ò›¤îõr‰Q¹½:ujºTKþf«gvûÇ žtÎÊ’N©Y#ÞßB
+§Ý—VŽë‹Ò/ü꾫H™š2¹¥`èzSå.ß|F‹OëC»ãf›_%Y¨¾Íªö4]m\Ò·PZз —¨ >"‰¶—¸EèFỉϋ;"<æºÄ¹y‰¹î²+Ñä¬'eH‰¿ÜF§_ÒsYؽŽ6j«m ¼ó×4Çc]ëfîÞƒÓŠ¤c®ªU1š}ºw;]ÊGuå u¬Ý­·GC‡œ®i‰ƒymš?/H7‚„Ã~ùš36’“ÜŒÀñîÂíú†ërŒö‘ؼ
endobj
-740 0 obj <<
+956 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2154 0 R
+/Encoding 2719 0 R
/FirstChar 13
/LastChar 110
-/Widths 2155 0 R
-/BaseFont /JMBPRZ+CMSY10
-/FontDescriptor 738 0 R
+/Widths 2720 0 R
+/BaseFont /VXRNEQ+CMSY10
+/FontDescriptor 954 0 R
>> endobj
-738 0 obj <<
+954 0 obj <<
/Ascent 750
/CapHeight 683
/Descent -194
-/FontName /JMBPRZ+CMSY10
+/FontName /VXRNEQ+CMSY10
/ItalicAngle -14.035
/StemV 85
/XHeight 431
/FontBBox [-29 -960 1116 775]
/Flags 4
/CharSet (/circlecopyrt/bullet/braceleft/braceright/bar/backslash)
-/FontFile 739 0 R
+/FontFile 955 0 R
>> endobj
-2155 0 obj
+2720 0 obj
[1000 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 500 0 0 278 0 0 0 500 ]
endobj
-2154 0 obj <<
+2719 0 obj <<
/Type /Encoding
/Differences [ 0 /.notdef 13/circlecopyrt 14/.notdef 15/bullet 16/.notdef 102/braceleft/braceright 104/.notdef 106/bar 107/.notdef 110/backslash 111/.notdef]
>> endobj
-736 0 obj <<
+952 0 obj <<
/Length1 1616
-/Length2 25334
+/Length2 25435
/Length3 532
-/Length 26225
-/Filter /FlateDecode
->>
-stream
-xÚ¬ºc”¤]°%\]î²,Û¶mÛvuÙ¶mÛ¶m£ËU]¶í¯ß÷Î;ëÎüšo~äZωˆ³cGìsb­'3Iä•hŒí MDílhhé9*ŠjòÖÖÆvÒ4Šv6€¿f(!' ;[a'N€š‰1@ØÄÀÈ`ààà€"ÙÙ»;X˜™;ÈÿbPPQQÿ—埀¡ûzþît´0³þ}p1±¶³·1±uú ñ½QÉÄàdn0µ°6ÉÉkHÈŠÈÅdU
-üPˆŸìá|ŒRbQ»š€ê
-ÏÎIOžŸÈ†ÆGG†{oÁú°©rb’p¹€Â’FúýÊÁæÓT©©jUmÛëÕb3ô]ÿ””sÂ
-Îl~^õ­H¹²çŸÈôÿbاÑÙ®ï岞ÒæNHÙ ™C ½‰h1R^iC«ÙÂ{»AùÖˆqwÛÁxyÒWcÁ·ÿ¡y÷'‡—ÁOéTñ´šŸ­wôêuòÓsPMTUËçýNÀ(5±†ÅÄ ö¶‘ÛMüc,‚¨×]EI[™Y… ¸îˆ0^ ÆMÏm}™× Ë 3ž@óÉ ª0öGƺ°>KÛyE‡“åÜTh6þÁØŸøÐJ¢w¢§æ_[c ³öB8xÕ¾Vk”Ô‚—I¯¿ä„÷gÞk‰òŒ+(}‘²Å+åýdä„P9Œ,U•äD¡&w("Z·´U¾D£|yÛ)Õ‚þ0ŽÖ)¹` Á6l¬NÒµ½žŒÍ&²˜ W
-€gÍý¬ÌV” C†û3æèºnMp»-˜…Z‘˜æj¤¯gÜ\}–ʈ}—}ÍšP«¤{}ò#U/ÉXÑ…€¼ðk¬¾ëÜV­Ð<´eÁºµýt.<Á0œ7Íw©~‹A“1²Ù°¢%îßD?âÝjÑä¤[,È4ý©
-ÔI™Èüíç‘,ª!Û^ó&I|ú,~C¼ð O¯JëŽs/)'UgL—æªöÛ'ŒŸKnõætÉËÁ!;ÙÜ\õýâÚõþ#ˆ%æÈMµB”j!ˆªÎŒ o¢†PU&ø’¿ß¹PÃ$Þ;Ž‘»w©*t!Šꌄ|Õj”1íw-¡LÕÙ—›ö‚ߎ…>ßË>#ÈQƒ›a"¦´Ú×5ù“97Û
-Ïþu¿^ù5cÔÃ[î˜4mô–CÌb^Ûe m¦Ýìž88ç}gõi.Ó 6Û²¡{ÇÙº[·:±’‚~s¼r^®µ{×y"j¾À`UŠ2f5?+ún ¸ ¼â@œî׿…@“%5£shàî‚Œš¶{++¬#ÂЙH¼GH–T l™!Ñ+PH­ÞPË9­«·Ä[ZYIçi\eyr*–¨Ö{Gnðx*yçK ’„èD2JG«L¸Vä±èG6<… †Žçð9‡X¹;‹X‡ã$]Hñ8ÇR™¿}t%بêŸZ¥
-´êÄÐÓ
-Þkvßèåà?`Hdò8Ÿáz„û%u•$õAºu™\<bxÂ0×í°–h¹ÚU\£ÑÈÖ{¥ß\«E²È²æx,3wר•Ù.$UÚr¸kÀrJ“»Ü$œ)»
-'Þõ¹TÒktÊ1 ÊYµœóý–,‚Å w†Åáù.Ûå•OسÐ-Ž^ö}ÃÊÔ§4¼°…ï¿•U;hŒIv@™È8Too?â.i¾NFNû²O *¿‹Ÿ9áäu7é8ã›
-|V뛚¢”ø±W’\úyëªb™=)ÎþWà öûI¢¥Í|ûBŸx§/i¾Úæ3“"¬ì!óYº&4«?©eL:ˆ˜¨^lHëž|´XÁSº)7x}:Z=n¸Ö‚žäQÊü˜‚>›+Gr*|wݨWÔÐæ>zuÚÐÜHq…ȃŠ0?‰Ù“]¢¨=+ûfUˆb9TV¶54ç,Te5®Åj
-–€íÖ—ݯUÛˆ¢¿ß$»Zµg-SÃ]‚.(#º™‡`¿ Ât´Üæ 6¿mà¯ò™9M}§’ˆù'WÃÙð´£ÜNæÜ‚é§$# ÁIÀq¯¹
-ýl…;œë‚$#¥Rј'ûBYâSö JLj N·—“\ð“ë¨zå0y¥~Сª{úë#Òsa¢¸²ÆfÙà´ñéöªðc~ßâ} ]˜ V42lï
-T ›+=Ý"N¸F{VwÜ«Ýê'O¼o3Mk¹‘)& Y)‘-ÍÇaÊgþÆ®
-˜r ]w9jr‡šØ[O§ÎéåMÍÏÞ@Í?éÀ0ÕíµDJF„rFhS[ͺ.ÆŠz¤9dR’XL
-fÎ$Ë\nÞq94e#q0r±MnJïù» 1ç5Gö>
-ª *Aº\Õ@^¿>V1Ö†ÑîçhµäÀɱ~°ìj-ýflâÉL8D¼ÈV©§p¤‡Ekc4²îþÝc=´BªÔ"–¹² + „›šíwp ‹ÚjOI­{4°ؘ…‹VxáOR¡®TÈGA ì³+ ®À©„”À3ã×ËbÀõøϬ¸»eéj .5ß?.4?‚w1¤ÉÙ,ðà_–yC Qöê¶9›«¾_¼­pJ-G¥™Ñx¨^ð5xŽ“L¼<k -Ÿ>ðh¼D°A€'áO¶0„0²8t³˜¡hÀ~AÛ{ˆ&î)'`Gï^¦‰m ½\‹HBõoW"Þ<y]7}rÈ“!Vý, U4.Ð"‹¹ Üw9… ÆžîôÀjìS›•ó™…)å’æøUOí›|XÚr
-j«ˆ•Úý¶”À´.u-EaAB´=?`Š)/ æúÂÆ=šöÌé×K¼xX¯·ÎŸÙ5½È}áÍŠ•ÛìŸZñf6nŸÛ2£‚õ¥­¥gÕv/ð^€ ax e¦÷Êcé…|Q*íÎÅ>t.Äñ˜êò[Ê&G>¬šX>­|¶F‹ÿF9ÈG:
-}ˆÀu‰‡FëOðѾÒ`g!ë˶’Si™Ûs„×dŒìΈ”’G‹ŒÒ÷¤úPXŸ‘ÊX*òp¾š£µô†;pšX ¯»Õ䄾ÐÐÅ·.ÊÆ™³õK· ó§r±çÌg<¢åûœs§0œRÁãýËdò3‹Lqø%$ØDë=+¶X—¥ˆÚHï´m%¾”+pÔg­2œÐSíÛ&ÛÆ’ú
-ˆ!Ýkk»†“×ÉÇ.¾á®ì6Ëq_6…áNÝ«—6™T¶Sµ–F¦›–‰0;4Kÿ½26aþ2+Ai};bŸÀ‰ŒIu)I£YÅï“y¨)õ‹—­VïEeõ–œ+e"ÑèËF ÏèwéV¹Õ> ^;"ZÀÌ}¯å®I„
-ÚŒW?ð9ÉšjgÄO¤¨Ê£%Oy-¨Ê¾ÆÃt­ŠÉ2¶”êy (6eÅF~!²×9ÞÕ=¨NdÔ_Èí]Þ[‰+£øþþ>»`.‡`ÔŠk™½¼CæêU¬ùôÃÅN²3Ë
-Ú¬wî‘ê"¹¼|=’4v§Ù:¬)ÈÝ%¿Ÿë°yÔÅ)aÆÃ=Ax•qÊ8úçUûƒòM[iñÊŽBËE7ø·džŒ¿_SMé)7ç \=aY„2Ǹ,DôÝØÌ¿ðÿtöÒãž¿â K‚7Ö–ªëÏ«wV÷ž®a@¡ §¶¦Û£;4É™ÕÖYYøuzD×/e£*)£‘ò9fS$ 6úÀ÷ÒlE;ûrðã`Û¸ËCë*‰{•mÖƒºàÊ–Mx¥PJÇn7ß7Á±^m©Þ®;±ùM6ÂqN;Me.”·k–ü¸¿mF²jkÁÒ⥠êv„,Î8½Õ­Mþk´«Á5­ ÜªUô æ^NÁ&ºg3w‘²X4YeWn)•#~…¼qòõh¯jH¨Åö¤Tpû÷ؾö|]–öÎ…¸GxÖÀ´K<$L
-ÔUñ`•5Þ
-¶¾¨1&µwÉù|ì9UÛ39TQ÷䆹í| ¡Ã(=̨º; GLâ§6ÿãì¸Ì¡"¾Ž•w…B|(iïˆ'Å'º¬ú[7ô ¹r+£²*iÌÆä;¹E}—ûOþÊF\]¦l{YåAF=AD
-»÷I¦aôIãÔ'§»ÞÄû✨œùZzñ
-´afÓ´s!(ˆ)§é‡¸˜Š  Mí0Âß<_°7;3s]˜(ª¬Þ)JÁsTæû°€½F’§Ò“_íç#¹ÏïЉ¯"#(àÖ!È¢‹ù£áõDóòöÔfÆë"S§ÔtN'Þf~¥ê:#Ï¡Ú®“×5¬'9/ŠŲ
-1«¬Ù]͊¼аŽÎžl_ø)J%r˜#sŽ-Àë÷­Ýà,Ó’µÿV¨ðyºoèLLe·rÝLû—‚ f{ûc†lî %Gä·Ú÷<{­ëk†¯¹­ey4X«Þ>¹×¢ìØÀª"¬‰åLóp å4I»{lî5<o„îÌû4%s‹_?Y sP[ϱ0Êh5è²ÀEÎÀ—B] X´sd«3*8w†çñOSDŸkâHÅkd/t$æÕû9ÃÝpš®²èwm·Ù`×E¦mSû™ªf.þÝ‘¤ÐjõmïòïË`m•œyò§oURl»î*8
-©~ó lP}EH¦à%ÄM¼·¾t›t‡¥âÐ{cöÞBÑP ,Ì6@–0®ª7ëSB¢sÐãiÃ]î“
-á¹×»­còh¹ÂY!Ä÷­Kο™x¤õbVÑÄŠéw‘q¢†BŸíú·\¦å!ÎïÖt–N´AGsƒaÃ6ö¥¬0%˜Y—½ãX*íUϼ.;ÆëÚBØåŸÕ$’a’ÉÅ/KáKv2zQü ÜIDîÔ”´Ö# ­w±Bl*sA™vœFûô¹êH¨ËWŠeÍ6«T¬GK¨´gÙ¯Æ#&¤'E¶ÞèÛƒbmAФMÞùpþÀx¼(³L½†^PÅ”‡¤•ã°Ò'_ÊsGÈxh4ÒçÝ06‰½`}‡­¹Gî‡)U¦5u†=¹‰€®qäXZ`”…*ƒ}^­Ý›ZÆËYÝ…Ô ÀüF0j ÉؽoÑuo·àd¶lŠôæ¦|•À|ÒM ÒÐ$<tÒ;¹–®ö¿¾Þ~<€·j4uuþe»ñW¥”ñƒ£D9ovˆ<Õ¹çp¶Ö\g‡=–ã;`×_LtZ±É'òãó2MiBE‹À¿×jö
-rÂWf¯(¾ Ê.Tsûœ$rG~‡ÌR)G…-ú²O2cl?ÂBüX CÇäd"iXćÏà÷ÈÏ:ŽDN
-ä¶Ôñ{mƸM¯ýœîdßË
-‹¬)Ì Ÿž6Ö=jÖdÃ;í¡Ô¶„µ¼n:_>;y""¸ü,߸藵’ðȲd Ëd¨Q TÇëìÙÚÏÜ­•ïØ`.ø|Mõíº$õ´#É*šö7 ´¢Z•—Ã^SúëVa=žBžk#UõuƒKVQVQJÕÞL§Q¶Å¡ïºÜöÞÖøMØ¥b]k®Ûý7>ݳd«,B?.ÿ@uÏD®3uçæM ‰0).WòòÉÈhW' Vws˜‡×ˆ¢ƒ•\
-=;3؇ZÑíx§fÇu1{©‚qnˆé%Ñ)(Û+Ë*jóºpd±NãÎH¶›áóú E‹´Ø*ë_ªŒ®MuL¡Q°­èlq±ô¦‡³ý4ýCÂ4Š
-õgðeµ™ ýÙabÎbg›iÏRZkaPC+ˆrÖƒŒF&õ*4¥vè°½4ü`o²O¹Û•{6oŽ;ǧ5M²*ËË»mýæAd/œvH&TvןŠ•×èë§fè"W"Ô ˜_©§D´ß-ê{IU#\Ôw€18_1mGwÃI&Ùj™6j%µΑ4»o»R.*Z¼Ê…jº…i7“—n+2{'oœnó„É^*½mp`6id¢ýU•DoPþO z¯@@W7Q!˜ã¯º| —qu ËNƒò,ÖÆ8þÉòê’xÅ“œ-LÂæ“š¤Ö,Q‘ݾŠY]ò:ú©s¸÷8UsÞ ð„Œ)ü<²oD¹B2Â
-Q9ÁïÕ@[E£©ë|å»Þ¡–åq¡¢ pȫУá'¨h æl¥ËˆxKw,Š–Z=S÷z ë‹TgÔèŸ)¸ yXɶÚj"С~Ù·©y¾Wjǵ­
-)˜Y?þÄô‰H;§#ËaY‹zv,„krÇ)Æ-¼›è™«Ÿg\VÆAÜ®ô ×f-²”x éH9ØM±·‘úÕ¿)ÇDEðHÅ#Àë-WΈbe8Ôç˜y•ÛaÈÓ¶#„ŠB€s¨Ô[¿Ñ¬å=%*žÞ$ŠÞµmu|6$)!¨z°ŸøǸô†áîÊMÌ]Ê„hf⃕ðH!
-Z_!ÎØÏ™P°‚ž§TÙ s§ÌÛ ˆo{V®!(H”4o|ؤvIÒ†¹./ÔPÒùä³L6ŠH±ÞNÛ¯9s=N­ âkûrë¡¡ #Ž™.|eìÀ‡Ú½ìðâ+}(|ô’‹Ñ<w–ãÇûpÌ'ä çEFeÆZ
-O>´?ˆw]°÷¨Ãæ'²€n]*¼½ZX6ÏvJgv’‚¶Á =£;–ðO ½‘*-ŸâÝx>G( †Væ3ÀamÔ­{b|¥ %D~!Ù;'½Xï×>Å{2\ôsA¢›åÖOUiCYxm]¦ý,+“+ÎLïûôcK”¿´ãOn¶Ó†2pÖh¿EßµWê¼Ý†a#’Á°ImǨÐ5<,”ç'—ÇI$º¬ªêßbŒ>"1^ÓZ-âáÛÝ-ƺ%·£¹¤“—Í¥’IÙ ÕÛzbÑéš}¶~Ä©âLÄ6 ãaÕÁqðP2´6GðâPx,ro½sayjñ¥\Mó8Ë49öÑ~q|¾^þZ:@MSAÜÓÕ}$\æý¸ú†
-ÔSßõ}FÆúcþ„"Ã\|¯*)ÕI ÓÔ–,õ†˜¥I"
-n½ü.ñø*ì AÆtþØãR‰øæåUçÙ +KùMg”m{·Hn-dðƒ­
-'´ ‡úÃi©šTâ¦a4ÛÀór4C{$ÐI™}ø¢Ù>a‘Z(žxSomgìY/àOêÛ–·Go<Ü;œö£~NCbŸPT{ŸíþBÎÞ×pR½P¤ä¹ÃV‹»MÿpžíÜ*¨‚]”Yè=¡zéêÛCœ£LŸ3t7_>&IZoômG‘f~•¤Ôóþ{àMßq;:Š»Åu ¦€©ÓZOk˜ˆ<´XmümŸãT`»u6J+kŽ¦‡+Ö3ê~ªdô›™Ò]þAO†ðq†Â…“”ÈH®è$#c*ÿ1^ïÉ’^‹ÍR¹aéc‚ç'JžÂF°úÝŽH18LVÙë`¨çòö«;nQRGí\vß]"zÊ°¼~Ë *¬‰@ÔàÀ°··¹K
-ª`Ί‹šXN”ÀU?Ž¢®ºëÈ5ËXrB0n9½âà!§æ®»u*PSçoiyµÚÒLNöolU®/'²ºNl¾+
-z·ô̇oŠ%ž}Áwiô[ªÙ׶K¸pWâ^­níåÛiíèf.\«™CÐ f¤: l©N}Vâk¿3 Ê[‹æ+>C²W97û&Î_lûnú6±pÎÈè?9+Ì^?…ö z×û±·ÝIÉ*ð¸ãEu…nÄsA´Ç×ñ^dŒ–kC2^FvBñ§ Ó¬Yƒ¸†|óIÔµ%y$¥Í•Èƒ’¬¿BPÞƒúuÓ?fÒrJZÔø¯e¢ú
-WL©,ãõ®<ò ¼z8ØAÚBeåŽýAf!Òç.P£MX“mtŠž¼ßZ‰^`«-Þè|‘ ª<:´N†„¥,ûP£—ærÌö)ìÆFSuê‘Ù-Qà‘×®
-õó"KŒŸIF€¥%(³–_@k°„
-j-éù•_"R§‡7D.àúœµÁK`RŠcàÅRÓ¶µËê‘V¡€Â‚¾±Ð ‡‰ŸV':–ðê$íôÃDgènº¾Í·ìM‡k/‡&ŽNYúÞVÆ3‚tӾݭæ;["Û‰`Ëk•¬‡~bŒók-<ÓLÄHsH‡X®¡Ê%¨};É„ÞÌ“Äo·ç™HV²[]û:ûýã÷ön±Út‹©¯¼€ x-0å­ ¤ò3(×|–¤á#¸Úª$xœ£“µ[=~©øwBˆ¢ÞЦîx´-«’Â@iaéLß
-–qÇÙ¶â(ŽÇwû',»_eßùÈvôÕÝU]wùd}ðy0=˜$IyO›ÍÈ€œ=»U9e~5ÉŒœ¼uo{´Ñä¬nEhÕkPía˺OoÑQ2úˆ9Ôì&\`}ÕGÈÔ³ktð´bÖ¬5‰\5 °ÀÃbC“
-8×Ù¾]“’h·À¯6æâYn%«çŒò2Ã>¾õúŒP?$8uŽÁp
- ™ðˆfd;®"¤¹dA¾£B·KµAPùsF_óuª†. áŠD*Aü¨ÊiðÔ•Çð—3+¥]ª„kyÕ£dfÕp¥ß†ÜŒ&è tÝøgXÕ€Š¢ ãŸ6MªE×ôR¦™–/œÅOtÞÖôÝýÙbE€(àºè±GÑ@…¸A¦½¹ûÆŽJÉìÁÚ ˜‘êæ§p„¼a¦ÎïbH—@$ÕflÕ?îTù×7íÛ|¯œ1¿T({i•ò¡Òj[T b>J°ÿ܃>Ž.èh‹æ
-v¡=å ze׶)ö\à˜¯y€Š|É) Àµêú<`I@Nw¦éŠHræ­Ôóºƒuy.)ø·Û‰Ýê‚í\üèG®øÜè 8tÏ»ôanퟒJRo╨,ëE…cc!U!ž¤ºõN±“¤×[zçQ¤QC"5ä ã‚Ê|7ù9s0˜L½I½\ðî §¼õq·aø‹_®sÅ$Ö꩜Ė]dyé=t°P‚Ö¦—3YoÝçÒ2Ëp•ç]Lò2†ÎïOñfÊäNªQJUfî‰8¶÷$ý›°‰¯öOv¢8ÉæòLvViÊZã¬à¥Wf¥
-<”â׭Ҫܹçò3¼+çÓ2> $´‰G£éœ'¹’Ž¼ˆÔ
-ªwQå\T1‡`ï–*!7Ñb¬§¤ƒÌ%©©Â+¨÷|¸M·äv×·vã„z²Žç§ñN4És÷ôq€ÔüY ÐW<o9tƦ7°6UL¡y¶s-ýsŒ,ÓÁDHHZiÝwà¾8›5‘ÊK×>8­-²¼
-!STlÕȇ=f¿lOtÀGF­FTØÌ]¾Žr»j€¨7mÞ±Ï[Üû)ѢÈõ|ÿ`yzŠöÒé±<‡‡a^!½Ì=UÆø×ÈÂúa¤Î†¯=Æ%L€®"¿ý%âwQ˜H_éwõ#"ÜH„-»Ö0PõºÞ¥@°lÛt´+Ã=¼~•¬Z>ñ~)E‚®8¿’…@ Å²!tiv6diü•â¨n© J@u˜$íoá}ÝÉ–i3Áñ§EÊ®äK„o«9 ‘9Px¶:lrÔpÊÕ²²`¸uÓ/µo­î’h±†™º¤Õá¤Üôƒa30 ?GÝf× k!{h¢Ræ×;ì]OËÄ(«‹ž<üÓÎÃijW$Ä,= B‘Å)HS†b@‚ÕIw´«–¨;¬Ùlͨn³]]CþÃzÃÅH4¯9¦d˜«çï¡~¬ˆÊ \ES ·Â>VjPÈ7³ßtë™LËYýUå€(ÉxpЋØÁß`›¿ÃTdߢ}éøO Éñ¬1°y°‰¼wx;l¦"–SH{ïÚË“°ØéÆÛ'µ‚ ‰œõO
-‘xÑ6@·î“ü <SË~m!¾áº™Àƒøu’°ag¥Þ¼ÃæÚ ñŠw­“ë•Î2z­B•CÜ.7 `˜Uy̨²Bzx’qê/›ä?º—d¾¨¢ ѧcŠA×<38æª"<ž ‚õÆ—½
-;i÷¤ð =¨?³F‰%dr,¯Ô=wxŽ$Ì„½‹eÐQ˜ } èax>,¢RÔ÷ÕüMoÖ+&Dù ={ùfs9 µ¨<|ó\¡Ð’0së·§!Æì¡K^j1®!çóã7ƒÂF!2ùš/ÞQ ýW…!dHc±g±Ä{«£Pa,†S™"GÂd¯Íçe䶬ÍöáÇþ°ËV¼Èˆ€CaDÜøçf:*ºXþÉÁŽ)2Å·áV׫ÂPHLVz륚íä«Ÿ96? Í2åÈÕZrÍ­Í »È»Tn¢"Öhd T3‡½:¬&™t0M ;Éà¡?„R„ùHÌ÷ŽlߪeÌ—cN^Žaî[¦|©"ÏP%]Éúí9F{ ,R˜,wÃy'kÊ?Ázï×J#ů§¼¶7èÑf[ØÖ¸Ü8m>é,Õ£ñgsöèîǼ–Ÿ >¢’mƒ»šz¶‡–œµýdïŽf[¹öEódd@â?õ–ûn±áH¬‘YÄ.·äÈ"R½¨³® ®c41V8;MmàZË¢ò·ÝHu0”`QMĦ‹Â‘.;¢¯|í/âcbÇóŽ—GÛR>BŒÛb}7krê«<Hú€·Ïg†Îq¯Kîý \—|XY¿k˜ôÆñÚ.ŠÖ§ rõy£çu‚dàlríÝ‚KWe >À¡꓃ BÓwè‰)YXP›Ålè•1«€KDà©)ÎýâÌ2~eœM=¤®%Õ3– Cu^yQ ä7ô£¿˜ e*²»ž¬js»¯ù‘1'¡Û~POœÓü T™æ·UFaØ­ŸsA?Áè¼³Þïê/Ã×›Ý/ˆ' xû:ï+#™>ãàiýƒžþˆ¶ âh1CJi•ÅĨ 0+íˆ ªä›Ò¼fÓjæ®3„":b^¿’ž¾>œ ÒGßzHűI ŠÍ2‚W<—ø­î±aj4Dµ“ 5«\6†3Ÿ‚ c½Fbá¯8çÒIzTp…!‡ˆ­W@Ö…•Le2ˆm¿MߨC8Žžç¾|à̤ÞBÂîÞÄx˜1=WUTw.ÒB²è¾Ôç+Sïj©zx¡Ê-iSŒÌ¥ŠvÔ¼+ù$zÁÏ™FK0&}–ã㪼¬Y‡~9M+Ã¥SÐ%Ì.äÛ¼­=éšâÒá™>uMÎWÐ_Jú±Å("3²8Bwú÷7Ôm´pJ°B4¥”Nƒk[‰urÙÍù¤†sH÷Ö°aÍúFŒÆ]bføÓy<;X†4Ò²RÖ:’êa“‘qXL¢e9G膥`ÓC®%…›ëTÕ“PnòDXup­<§Û­Èž¤ODZ‹ø5­¦/»#øí>¹Ý¨€º ~'–®y×âSï2ˆÊ²„´` l—Ú-|Us¡o(ШUó4¶ƒ¼&‘níüÅçcè¯7Lçdk~Üæî…MTx€iÊL1ĺŠœŽõ‰4Ábͯ†Á¬R=ÐFÿ‡ hC(íú6IÙÇ0”¬ aúÊBJiÞþv£¬zh7ùp¢wÉ×é–WŠ|WXva,qkOæê¸ü¢AÂLR¿i9ßv«!Uno¿¾Ó7…­EýØé2CGÊHß soo¹°®âîç´ÃÓ.·ü‰XÝ[ä
-sŽ[ò¯ÆºŽÏ ZªT˜Fu醭aw;ôfI´ª|fÜÚâñ‚ÑîB5ç:ô›C]Åt)´¨ [³')Öá(Ö²Xý” ©A8çŒFŠƒ9'™ûkóm Áh%žºË!]Çqf°pPŠpÛh T€[LœPv?çM4™£nÓMZw ×Ð]ÚUå)nÆ<DíÃÐ0ŸJç!pº­µB‡#_JÔ&bƒfç×M2ÇjH@§ùåAßÄt
-Ópd½Ô[`çCDîãY`=O¨ã<IÅÿò‹I‡ªF< óPZä„N|£Ñkÿh!Jž¾”Ú§x¼¬ÃÇ`3´üµj¥mÛ*õ·ÒÝ“$Á³a†£òÑ*ààw¥+}ü[=5êÔ;ºžiþÜÉzÇS^ dSuœÏóÿüÿ,.Ä2lsŽ¸@î³ñÀH²Ç¦¸c;däýHŽˆEpcæ2®ªÉ'ýœ²( HñíÀfº6¢~ãÍè’6yÏØlêÖ¿Œ·ð‘®ª_0°—j†BƒLgxN†N¼¸4tãr&ð$Òá“×⳦\׬#RdBÚsdz/¬Ôü(Lš]ÓÄ>º
-Á¸ç‡ÂúIo>¢ž Y†¬ƒ;¢+A²neçΚ[czýMµm/p5@?¶~t€pð’ºF°‹[Ç
- }W—ÔÖ¤í®dÏê3Æ­­Ò‡¿$ºÕVP› øÅVc%3¥@¡íä&žH˜.ÀýÁ6vÀáõ£…z…BqÛNÉš›2•TûD:½õ®àxü\Æ/(tùDѦ$C‹%Ð}B–ÌCÀèçQÅÞ §ŠµHËÅL9Ú~[[f︙¼mZŒ=6% Ù]NÐu¤s0E‚ÿYð»\I'T‹p>̵†ƒ"H= ‘ª-ùQLO*I!P9RÖ° ´
-tE$ úoÜK‚†¥ocÙÙ E/¥ïµ
-žž3¬ªA9^éH_ˆÊ3ìšæدÙnà‹)áâm>À}ÐhàÄšŒ åø3ÓÝŸ•Tw²•ä!l}òrû´žMßÁž}µe¤Ä¨(ÔvÇ µþ«Š ÉpÝ8})Z¯ìfä8»8Iƒ~±žH.<³»k—Ã¥ÌdÕ¹<™Xð’hɤbÕs!÷Müÿ´/$¥nŒñIpƒR{Ä„'âcêRIÙ=\XÌDçl„ñÙ7<²´-œà SæÞ’ÇVûñâ¸bå#É^e‚ÏÙþ*Y¥µ
-÷5bóWŸüÕôt³C9D$š)I®«K$j tR(PPÀ"“‰ìXjÄrÍq=L7Dã`f*n^˜ÑééÍz˜`ÕîÊ_Òºn°u|ù5Öe3Œ?Ä‚! ×J„·LR8“*'²¸¢hŽ•ˆã€AŒe~ô"ž^'Ô®qiÙ&­´fˆÄãow^xvÁoóÏRvÎ?îè†÷ÖlùÑ2ú«4Nc|mOdòpÝ.#8£²#îK²nd¹!6Hßçw¿Mï;ž†‚ìÞ BUuו€‚CTl®´ÔZ¡ØlAi!Lëö.¨N«¬œÏÂðNÕ ÷?õaØÞ&.8ï †‹Gq2x4Sâ@ò~ê–œ%´Æ­j¤«¦³úN‚Ó˜N SˆWVµêYkÇ°¬5²¥áŽ¥ôbûz\séeñ½kQZy¤h*Z–E(ÚRˆ3 Fè~˜;ã|$ªÓÃ[®ÍÖ-˜N]ˆÉáÙP<|Å:³èôFÎõSº6¾Ï,)£Tÿ¨²š
-ÑåêB:­ÃÖŠ Êx$To9@H¸%±.¨Ì~jô&+A 7—ê³Óê®ãO ºQœß ÝÓ¼UëªðKŒGf´Â8Jý?âá~«¦°,i´KRQFÈ:çZÔ²öhÚO>Oɽfx‡2ȪA™`dµjg ÞqÚþæb[{e=?_)ºüDÁêÊl[TÌ37Æ8)Ñn+àAíMõ­¨Š"z´CE'h˜¹BÅQqzïªö0|#aÄ—loàÊ—v’³XfŒ´xè@—zÁÄJ/Ÿa‰¹­2ŸÝ¥1%~¬uÂ…ÚÐ63íè4(ÖOHv´Éã‡6ø‚æ *ñ;yŸÄp+íKÈG?üþúI‹À7 \sNw%Ø’‰î;J¸To•Ö!NÉSenéN†£²p¬î“‹
-4­úWM‹~©¡CÏßÊÿU-Ÿ}ìŽY¾†¢á_±@Yh€íu›øbÔnW,ø”=ízt<îKfp¥]“ŸqæÅÞ-3Æn’aZ|ìŠï|=AW?~†ŠŠ¬‘-šë\ïb;üšsî¶j÷Žmùé4§xßîh&ô¥ü"{kƒ³é|‡l#g nl+Ï7#R±´Ö>õŒ™Y©âeë:@³Í¿xçc…/}RÖ¸g´µõIßârÎëýM•4yþ^Ú'ȇ·ø§–ýͬ&‘^×Á7È:6'ó'r2!LÇ1¤Abw>ñg²*¯Ž¾O‚Gk(9ïu
-%¶íV,ÜQòQÛÆtäf‡ÅuZý~J´A{3’ÀJ™‰&Ð0M\ý\¶XÀö1S¤³ô;5¯EaÏôJ0·/›Í4j³}
-eOLÌq3©¶Ô}ÅÂù„×
-³ÝMB®Oá÷£…ˆ¾b4Ûm5Ðo{\ˆciÿ™ÇWáÿ3Î%üg©çŽŒ¸Û¹J…QÒ‚Q ]¢À›ÿБ:™¾††4§VõÏ_$2}Y뤩ØÝððÙ ÿ¶cÚ¨"yog2ÃŽ‘} º8SJ)ì"Ko™†øžJ/ Æ´“+b<7H @,U¸)‹}ȼŒë§ü`J†g¹÷ûŠ¡tm
-…™¡é*®ïÏZžx;À-Ïåìƒ"ïÚ†ùòù·)*¤¥3ËÚ^ý=äÜúP~Ø.†ÜT Ë ‹ùæ(Õ¯ ^þkΛ±¢é ¤TrÌ°íåZãÒm5Xî3·#xæÓÄ·¼+»b{ÿÃ0œ}-å1˜Ë¾•áQÎÁz‰Â¬ÊÞ¹tEpyIêY`à7¢K KÀ½1«Òâ
-+aëØ “)¯[L’ïµ' ò+Ÿ°Ÿl‘\ñ™ÛtôÍ<ÌÖëwÊ¢bð59Ð*ßCdŠã•Q¦T¹/®¬“¯}%%§º/»ï³t.fÌ fMÚ˜Õ]Õ4}/ ÃÆѾ9ÿ5$ÉýÓ\úP/eë1WÞ³…Óv`ÓHT»Š@NùÛèjÔø«Â2¬ËXì^â{ËÆmô«—Ä 3¥è)Ç UGø:ÿ‚|…o?W6Á~ÇÈ!]ØâgÆ®±ê3_áoxFP²¾Nµ¢CŸs|’u(ÙR«ãòâü)ÞNcZöÒ¼°nPF›‘úâP‰6úÓ(1êv¾o*ï›”|QÐù#$!4SzâS#Ž·uþI6Då%3פx{ˆé´¯KKÁçÌ®CÌ|HuæË‚Þ
-mèLj¿I¼Äyê4¢“xC‹´¾}í_dšÈb‡a¼Ð˜,ÇÁ”jÿ»¡|
-ôÏ™¶ôúû¿
-h?IOø¿{EÁk–X4~Ôåqp „DuNLi’ã¨L’¸œKŒ}ƒ—Öxåp·UÚ¡e=.L,¾uêÀ±Ó>Ø6¶Ëh ¾­I ©¥2ÈæýkæYל2oíˆ6KîØà|ž °
-4£|í 4öî #a`ãåƱÂcJN¿$DÁäÊ:ß÷”¶Sù¿š0'x\n)|”"<jÈàlZñL|ìó “ ¨EëhÈ`TdÈægòㄲ'{°›ö…`*ÌñN¦ÈKìí111—Q'ÁX¢‡^¡8fŽ$°}d+xÑW_Ìñ÷õ•Â  Rö>ü?ëáˆò$ƒ‚EÍ›z`…Ó.´ïîÞ9C˜Lö*¸`b@åMlå½/O‹EW9
-¦?Ä›Q‰ìó
-€u“¶o-ռζÈFE£ð.åƒÊŠë>{‰*¨òwµš°s÷ãÁ±A
-Ä¡gK°–jྤvÖ?”lMöV([®™4úÊáD3p½$V¶Å,t‰#”ò·k¼Í_y´©¡4A{;D9"š;ó;ée$X|9T7N®åüok½µÏÝ3äñ= àŠŸœó ,çPzìýªk,AUóÚd¢`VX¬@a!G»¸¬³^„žÍdSïÄâzy’_W}T kÓˆ}¯µj,BMðî´¥{¦XS~§aN·¶®žc“£Ô‘«8³s&ëÊ‹·Å &èñÜ”?äý«>ÀÞ×]Q´®óP™Øk`ßäÕÝf û®‹Y×Z«ruì=È3€1\&ÀHCNXùlu[80ëFÝŨïØìNÄ]©
-˜%0œÒAJ^ý´¼%¤w}/ ö‡î²òAæìQæãžûnúéùÎÕŽÙPÒòçÌÃzÈ/Z;ž)\x‘ÚìëÖÞ9”U.‰Ó_>ò_øá5Uûc-­@6 QEæ*D}X2a/GúGc1§OMc-Œ¾2å\¶ý„ÆP¶ó2¥‡`1”{݆àYšU!²TQŒywµÄB´¶BSÒhឤ2šA1±3_oyPüTIŠ¼û«õ[»TW”—¡6ŠÅ~u‘#·ëõpmðI„#³ZÕY$Øóyø2XõþÇ0†¸-{ñÍ·¾ªå¼2ñåÐèœ/ûY-T !ÓXÈ`lgÀðß‹Ù§¦ß
-_ÃýS‡µ )1ŒÊOesLQ²
-Ôqµwˆlød {ŽÞ‹t¢ Þâ+ïí[^.\1} )ÃÌÚtú¢à›%×ùRO|cÇŠˆ?ô€L]£µúem˜m…pRn7+o“Þ«¶›4s·Í –çë:yÊtôÒ² ê+ã\æ—‹HöɈD#|q™eѺTÀ?È6@å¦}Òú”¶¢§†ñ®ÐJÛ?ûÝ(
-!N™<‘cÞšó¬1¬
-Jµ¸Q
-¸* ÞNK
-Ä'Εo äNïçÊòHª,—üw*»ú.|¶0ÚIÐ ž4[Vƒç›-Gy2½ û{(b'óXèŽïÝÕˆYzåeø’ºkSoðÕzN
-…Ï\{¥?!݈¿Q 圲,é“Ó{Ü™Óó½%·‡ƒR™ØKY,áëÎú¤ÌLŠšàßÎÐc+t_5ñ‡^€ ¨aà¹3n<‰¨ t6.ôÌö›Šûƒì-w\£ÐZÆ.ž(¯íôúDÀëôèT!þYÑPêÒ•m‘Q•ôƒMƒhØ›‹Öš– Z¿,ÃCó
-ËÝ@Á¢gßqìöD€¶þ¸µÿO™ë&Ñsu€r“·NŽ¸¬¸Ü/½à=Nº&F¼«F_ L-C§ˆ}yï=]Ií˵¦² †¤Ä,Õmza­®4@Aĺ@q‘s “†D(7–Øuç´qçGªw=cP Ïú#ÆÅ·¹ªËPl²Uø¾d¤GË^ôë/mŠ¯,¾RÁ
-¶Èãé©t²„4å¼н”n_0gþZXßåì…×bKÀ!È*Š¢Só±[¸ùq]²Q¨ù
-R㻯ÙQôÏŽ}Ô Z—7“Á ¬¤jžé ñ"FOiŠ>?ÎyÛ!änQT)Æd§ Õ©Jü[—p1}àn‹߯¶ñˆ#ªU{¹SV}¿W†yT¼"~,*0W‰™ý.ÜXxäݾw‚”ÕÏ#hïyª ?N8,¬Ÿ¢Ò‚÷†—ó]ÅŒPpFÅKÕ~G‹kýj Ý¿þKIÕ$õºÁÞº©‰uVé¡OýC±ÉåMìi ž2C´gyƒ?’ËvH4åËÌŠJ ÂCéØK!ÄÕãþIêf|ÐÝþs/ô³@Ä:÷8=]׆ËlÙím1qGoi{tÒ-3î.¡¡¡)òË“–š1®”9c¿X;È:Œ5ð4‘t# `bK)qA¢ ©˜æš ›c´­5ÁzZ1ŠÞÖª)\“²1ì×±u27Õ@}}·f RÙáÝoW9Ç\P¦0»EÆ}UB%×/y×—¶¤^â¡26ýù,bÍŽóPI2ƒM<¦éË:ª‚ »û­h¡1¢Yâl8.ì4„ãGóqj#ÊÑY
-bJÁœ>ZÔ¶X-wJÂp²u©âÆ0S§±sª3KÅæóì“#‹yžÇ­¶÷ âÙØn¼ú}åÔ\C"…}ñõkRO‘"ÆÉصCŸ°Ç&î—»ýl#˜LV¢n÷‘¡ÈÀ)5~ÁrioΟeÓH²ƒ'¨ŠÒc~1GÙÏVÛÔ&¶b®Æz†­(óÞçy]µu9Û³·ºSß<ñ‘¨¥ÔÆúµ•†Š·ý]n>+`½÷£¯´¢w¬lŤŸÊPh;w#7Ž®vUs Ë0 ÒÕ1©HÖW¦Bü0%Ï x4î/ƤúEGû ¤y+Ë(§ÛH·ïv²x¹1= ›uBCpƒÉŒ5¾ÂÇ™Ò{A•0žÑ5'†:]+³ lYô9²Ÿo Û;O%í§æe½;ió]…J.Å*¸½ÚWféë]šÆ¨’IFD>’!(š 9$˜Õ{è{W»‰êå|rg,fi©†Yœž›V™êkS3ððŠ³Œê£s(h"ñÞJÚ¹‚ërG×ȃ®Ÿ¦Ô\ãûö! ]aX
-=ÄWDe1ˆ¦H”L9ʳ‹Šâ(ÉLU~f 3Š^ùž©DÃUBAB´m0Ap ÿØÁ÷4@-ð³ÅÌO­‰D^¯-;<BÖ6÷¨qs LâãÔ#½×ÄoQ ,Lñ¹½
-A™âõ2ѶŠŸÓ¶Äøí÷w6Ê+–IºÓœnµq×oúWïkN)ï‡mÖ8/1aÀÈ[­ø'! ´ŒÄPxÉ¢rB<–ðœØEÔ?Pr|7°™2­²3Dá ÄWUOš9¬hÓÄ5@)NI´°›s0ÇÖnŸ[fö½U¹fHɸ>›»|¾¸¬{ü*ÄØ*X‰À¤ø‹Ã’mdñ„]8Î̱r¯éúë$Ÿ5îyôÅ 1™ú&àv(WØáñªLŽe½pò‰õTàb{´ŠÄB!ð¸YRE!ɾdä\ÁÔ|
-Äôò} 0á·Ï<ðx­×³5(©²ÓÇXõ̼‰h8L©m¢Í°]ºÓŒx$“
-­u|Ðí8t^ˆš/€‹MÝp­_’<{*ñ>Jn ÐÅ—6¹s²R¯aÆ‹úr×€]9ä¯:²(`\‰áÉlA7¾ĦK”ž·†9z8nb64Ë¢jE¢$µ1V|·ZBËÐöX#Y»ͪföWßqYûlf/ö»­8Fj…›ë_X1¡ÁèínÕ (N1©þ¢CÑð´ýÆ9(AÄEêÞ–«ôáÃÉ€ÖÜÑf}_¢£J¾:¤ íéJ$<ÂBÿˆSUÅöìMø›Yr¤˜¾ÃÈ×`Qíå?›Ù±VƒÝŽˆ½¸ÂˆÚÖñhÃÙƒXÔ‡7Ó¶,Í!Á•FÿÁEè^F ¸¯xÀÁ¦ÿàB*·ÛvªR&¤N<•ê`¢µ+çN¼é¬
-g¤£Ê¾2f~mû„m}…i
-'óP4I×¥ŸÐ?`b¬FH. ÷R}ÿÀ#] «iÀAñ7FÌÐ5øùq6O‰ Ç/êúWbõÑFåq-¢´ð §]xžök%˜Ã–td˜¯‘ŒÎ¼r¿
-ä&oH[œ¯A•9f
-endobj
-737 0 obj <<
+/Length 26323
+/Filter /FlateDecode
+>>
+stream
+xÚ¬ºc”¤]°%\]î²,Û¶mÛvuÙ¶mÛ¶»lW—mÛúú}ïܹ³î̯ùæG®õœˆ8;vÄ>'Öz2“„@^‰FÀØÎÐDÔÎÖ‰†–ž ¢¨&o`mm`la'M£hgc
+áàUûZ­RR Ž_&½þ’ÞŸfx¯%Ê3® ôEþsÈC®” ô“‘Bå0²TU’?…šÜ¡ˆhÍÒVùòýåm»T úÃ8Z§ä‚Û°ý ³:I?Ôöz"6›Èbœ^%
+yá×h}×¹­Z  ypÓ‚u=jëé 3\xœa(74nŠïRýƒ&cx£aYKÜ¿‰~ػբÉI·XiêS¨“2ø ú›G²¨†lkÕ›$ñé³øI ñƒ<½*­;:̽¤PœT1]š«ÚowŽ0~,A¸ÕO˜Ó%/‡ìdccÅ÷‹k×{GKÌ‘›j™(+ÔBUÞD# ¡6ª:Mð%¿s¾†I¼;v #wïRUèB&%Ô øªÕ(cÊïZB™ª³/7í¿ '|8¾—}Z£6Ã*DLi´¯kâ'/rn¶èXÐ60µ!~Èaïގا*\Dxc(uè³?^NWù ±CVØñ Áá´ÅÚQ[´¬5üŠvȈ0Kïø^•vµÚ*V¦°cœ (p3“¸µMÖiÒ|#Óƒ}5ãByE¦Ç•yÖÌÞ¢º<^×<;>3ý
+ÎÈ;V<g5j‡ùôIH›C„ÿæaTÓ€
+úÍòÊix¹Öî]牨ùƒU)ʘÕü¬è»à&ðŠqº_Eþ>Mv–ԌΡ» :0jÚê­¬°ŽCgþ!ñ!YBRÕ¿i†D¯@!µrC!,ç´¦Üoieq$wj¤q•M4räMÈ©X¢Z_ì¹Îãi¨ä/JF y Ètp(¬2îZ‘Ç¢Ùð‚:–ÃOxäb=ê:äH@,bŽ“t!ÅãKMdþöÑ•`£ªj•*ЪC[L+x¯Ù}£C”‚ÿ€!‘Éã|†ëuî—ÔU’ÔézÔerðˆá Ã\·ÍZ åjWqFW [ï•~s­É"Ëšã±ÄÜ]£Vf;ŸTiËá®
+X z‚G)gàcúl¶É©ðÝu½^QC˜ûèÕi]s]°?Å"*Âü$fOv‘¢ö¬ì› T!ŠåPXÙÖÐœ³P•Õ¸« "è ƒ7käþkÂ[ŸŠÐâÓn¥% „¸rñƒ‹3!ö†¿wqŠ+÷-×}ñ¨C}3X¶[G\v¿Vl=Šþ~ƒìBjÅžµ@L wº Œèf‚ý.ÓÐr›'<Òü¶Ž¿Âfæ4ùJ äŸt^ gÃÓŒr;‘s ¦ŸVhŒ@€'ǽêdòÉ,·œ
+lô³î@p® ’Œ”JEcžì e‰;LÙƒ*#.P8Ý^NrÁO®w¢êåÃPäåú‡ªî©¯HÏùñâÊ›%ƒÓÆ{¤Û«Â¹}‹÷þta2XÑ`È°½W(Pl®ôt‹8áníÝ1¯v«Ÿ<ñ¾Í4­åF¦˜4d¤Dr´4J„)Ÿùë¸L²µ% ç?·ëÚUA§tkݱxèL ë…3kà N,ˆÛ3«QÉĸǹ‰–B´‚7’ûÄL³_ËgƒÕ ñŽ1Ü
+˜šæ}›Û}}<‘3°2èRÍp´$ðʧFu(#6A<x•)Ÿö·QÜ´Ç
+å,´,œ6ˆå|ëÒtлå$3ÊŽ¢¨'‚±×ÄŠé›v#c5ÉÇâÔǤwÐÛµ0ÁoãiÙíà°Añòœ¥µ¢Ã® DSêá ©ó,zé6A²”VèFšxzGˆâJæls¬>ìFÏÊ2/ÕÐ:C
+Ífg4ÎS" >ˆö—H¨äµ>8h¡Š¡3lÒ
+{%ྼ¿#‡«BÈ,>‚^@Ò¬Ç0nÓCížU½šÂZ ^u»éên®p% À#d_Ðby¾ÅéZDzl€÷„R%ìS¢Ù+L}êPS«‰$1Ád8Ç2cæÃJœ¸Lx™ Š¬3µ”êR'1ãø
+ø—I›&ÃX9!«<O |è¥5©ÓÑ
+ÕMêÔž5…ÅÉmW¶Ä!ßCXéží´*m¤ÈjÏCB€5BŒÏ)Õ‡d"ZÕጼ B^moJ ¡ì‘×Y±øRAD%HX—«Èë·ÀÇ*ÆÚ0Úýé –ì?9Ö–]©e¢ßÄŒB<ÙÁ„CdÀ‹l•z
+GzX°ö0F!ëþ½{¬‡VH•ZÄ2[t”€pS³õ.aQ[í)©u3Ñ
+/üI*Ô•ª"ù(T€}vÄ8™xfüzY X¥û™w·$]-aÁ¥æ»ãBó!xCšœÍþe‰7Ä…`¯n‹³¹êûÅÛ
+§ÔrDš‡ê_ƒç8ÉÈ˳f^‘±Ðòé£ÆK$xþdC#‹C7‹Úˆì´½‡hâžrvôîešxÐÖðà˵ˆ$Ôï­JÄ›'¯ë¡¦¯Cy2äÀªŸå‚¡ŠÆZd1”ûÎçÐ"ÁØSX}j3r>“¢0¥\Ò;QõԾɇ¥-§ ¶ŠX©Ýo‹ LëèR×R$A[sã¦ø—òÂ`®/lÜ#ùhŸÁœŽq½Ä 'õzkü™]sÑ ÜÞ¬(Q¹Íþ©iv`cöù¸-Óz X_ÑZzVm÷ïȆ·ÐQfúq¯<–^È¥Òî\èƒçB©.ô lräê‰åÓÊgj´øod‘ƒ|¤ˆ¡Ð \yh´v‚öµ:ãY_¶”œJË”(Øž#¼&bd·‡¥”<Xd”¾×!}ÔÃúŒT†‰ÀR‘‡òÕ­¥×Ý“ÐÄJxÝ­&Æõ…/¾uQ~4NŸ­]º›?•‹=gæ8ã +ßçœ;…!à<
+>î]&“ŸYdŠÃ/"Á&ZïY±Åº,nGÔ®Gz§õk+ñ¥\£>k•á„žjß6Ù6–Ô8tµÄO§&¢„œ´bú‰|uTè@ ê^[Û5œ¼N<vñ•we·!XŽù²) uê^½´É¤²ªµ42Ý´Œç€Ù¡Yú ó—Y Jë Ø ûŽgL¨KqHÍ(~ŸÌAMª_¼lkµz/(«·ä´X)‰F_6JxF¿K·Ê­ôñÚѦï{-wM"TШ`¼~Ÿ“¬ªvFüÔAŠª<Zô”ׂªìk<Lתø˜(cK©ž³€bSVlä"{å]Ùó€ZïDFý…ÜÐå½™¸<‚ïïï³{
+„,Î8½Õ­Mþk¤«Á5­ ÜªUô æ^NÁ&ºg#w²X4YeWn1•#~™¼qâõh¯jP¨Åö¤TpëÏè¾ö\]–öö<…¸GxVÿ”K<$L
+ÔUñ@•5Þ"
+¶¾¨1&µwÉù\ì9UÛ39TQ÷亹í\ ¡Ã=̈º; GLâ§6ÿãì˜Ì¡"¾Ž•w…B|(iïˆ'Å'º¬ú[7ô ¹r+£²*iÌÆÄ;¹E}—ûOþÊF\]¦l{YåF=AD
+»÷ ¦!ô ãÔ'§»ÞÄû✨œ¹Zzñ
+‡™r@ŸZo_ß±¼AÚ
+êú<V{VIÚÝLná_ïÞ‡¾’õ™”÷Õ.
+óBÂ:2s²uá§(•ÈaŽÌ9:¯Ü·2tƒ³DKÖ<ôG¡Âç龡31•ÝÊt#íg\
+.˜íu6îi²ÙJŽÈoµïxöZ×× _s ZËòh°V5¼}r¯ÙÑþ3DXÿ8Ëé6æQàÊ)’v÷ØÜkxÞÝé÷)Jæ¿ßd%ÌAm=ÇÂ(#Õ KY8ý_
+u1`ÑΑI¬ÎP¨@àÜžÇ?M}®‰# ¯‘½Ð‘˜W–íg wÃ!hºÊ¢ßµÝf‚]\@˜¶Lyìodªš¹øw‡“>B«Õ·¼Ë¿/K€µUræÈŸ¾UI±íº«à
+g…ß·.:ÿaâ5’Ö‹AZiD+¦ßuFƉ }¶û½é2™¸ (ùp~·ª³x¢ :’3 ¶¾/e…)ÁÌ
+¼äÇRi¯z>ïuÙ1VÏм ÿ¬&‘ 3ŸL.~Y
+_²©Ð‹âOàvH"r§¦$ µé
+º'7$c²ÐˆÐ!•ÎݧC½¬ç$Ê?bï¨þìl"OâŽK±¾'˜w
+bx—‰Üêüj¹£O@ÿÙ,s[»6ýªícávÑY¹hd_æ“,VŒ œb¨
+‰ð#"^ÆÃg¶µ¸!ÿÉ#i/“ªñd—ÁÐRD4ìŒ-%…·#àrþvf"I(&!QƒÑCG¨swEe`Ff÷Ëڌ札RC†×Ëîï+ZsÃãØHz–Xf--¦¼…”N)±;±shs{£•aVXAת]¾b9ï"Áúpœä•Ôm90$j®„ÎxLYxCÀ8ÏB¿Ãí¼ìùìéÒeEá…i˜U ê#‘ÕA¤’¯ÍŒ’a
+«Ç­´©¾T#$5? éŸè¯¡³präZè<§ ÑM{å«¡x¦¯¡É! ‚)±6¿Up‚Ó¼ÌÑÜŒ0+ü9r×óÕ>ÞYãÃô d3–Ò_`gbת}û
+rÂWf¯(¾ Ê.T³ûœ$rG~‡ÌR)G…-ú²O2£l?ÂBüX CÇäd"iXćÎà÷ÈÏ:ŽçEN
+} ö&Õ>­o´×ã®æ¬Ñ@z-Ã=é÷îÛƒîø»^]bÄËŠ¬N -IýJ€°ÀjDM;©ËœU×ô™Ã|ÁÊȳ5Ã
+¶!yJ6Ü#½ºø5ÒÇ-u ´–Otÿ‹Ê‡ßk§]Ã3¤¬„0¥`áÊ“êí~©/^Cë÷•µp­Éü7scË Oó‹¿£hˆ-Þ€îi î¸[jÄ'Õƒ´§!¶—7žÝÔY¿EΜީÊËi`µêm£¢>TÓñ1Z`NŸ‡ ¤'ü±i“’Jbÿ€‰9XêÊÚ—µp,½ÓW¥ÂÔr×!KšÂÎèü`‡ž„Õà@l®/­Øúæ.z”ÈÙä+ö<7›ƒ\i0zlý£b©UÐ{S›|€h•Yƒ‘æ>…mL0 ‹¾¾„,qÊdnï#çK{êºýÂI_r(®¬µ׉Òõv/ˆÏñó÷†ÙÈBDßÑÑ#…iâ·d‡W¸ˆ½÷šЛ­ðƒ‹_
+ä¶Ôñ{uÚ¸M¯ýœîdßË
+‹¬)Ì Ÿž6Ö=jÆdÝ;í¡Ô¶„µ¼n*_>;y<"¸ü,߸藵’ðð’d ËD¨Q TÇëÌÙêÏÜÍåïØ`.ø|Mõ­ºí$õ´ÃÉ*šö7 ´¢Z•—C^“úkVa=žBž«ÃUõu‹VQVQJÕÞL§Q¶Å¡ïºÜöÞÖøMØ¥b]«®[¿o:}ºûg<$ÈVX„~\î@uOG®1uçæM ‰0). UòòÉÈhW' Vws˜‡×ˆ¢ƒ•\
+=;3؇ZÑm{§fÇu1{©‚q®‹é%Ñ)(Û+Ë*jóºpd±NáNK¶›áóú E‹´Ø*ë_ªŒ®NvL¢Q°-ëlr±ô¦‡³ý4Ý!aA…ÚxYGmfBv_C…³ØÞbšÅ³”ÖšÐÐ
+¢œñ £‘I½…
+M©:l/ ?Xå›èSîvåžÉ›åÎÁñiM„ED“¬Êòòn[»yÙ §” •Ýõ§âCå5úú©:‰È•5
+.¨CAV²­¶šH't¨_ömjAžï•Úqm«B
+fÖ˜>içtd9,kQÏŽùpMî8Åx¢Ew=sõóŒ«ÓjÀ˜#ˆÛ•¾€áꌳE–o!)»)öÒoõoÊQQ<RñðzËå3¢XõYf^åvò´­¡b†à*õÖo4kyO‰Š§7É_#¢wm›Ÿ IJªì'þq .½aø°+rã³—2!š™ø`%<Rˆ‚ÖWˆÓö³&¬ ç)UvCÜ)s6(âÃÂ[ž•«
+%Íë6©]’´a®Kó5”t>ù,bR¬÷„Sö«NÁ\S_+Ç‚øÚ¾‡Üzh(èˆÃA¦ó_Ûð¡v/Û¤¼øAÇJ
+½dcb4Çåøñ¾
+™1ü˜|Þ_"UZ¤l€¹y%N
+ENc­wî ¬ O-¾”+ÉagÙ€ÆAÇ>Ú/ŽÏ×Ë_‹¨i*ˆ{ºº„˼WÐPºb껾ÏÈXÌP@d˜‹ïU%¥:©a:ƒÚ’¥Þ³4IDÁ­•ß%_…=!ȘÎa\*ß¼¼ê<»áae)£éŒð"0£míÉ­¦€ |°Uá„6ÁâPx0-öQ“ŠCÜ4Œdx^Ždh:)³]4Û',P Åoè­noƒ=ë줾mz{ôÆøÃi?ê—á4ô!ö åðA5±÷ÙîÏçì} %Õ EJž;l¶¸Ûü
+³]AQ°ë±€2 ½'T/]y{ˆs”és†îæëqÀÇ$Ië¾í(Ò̯³’”šeÞ¼é4nGGq·¸Ä0uZí‰b óÑ£€‡« ²``ƒ¿ísœ l·ÎF)peÍÑôpÅzFÝO•Œ~3SºË?¨àÉ>î#À€B8 p’Ù)À`¤cLå?Æë'DÒk±G*7,}LðüDÉSXV¿;Â)‡É*{õ\Úz5pÇ-Jêè Íî»KDO²‘×oyAƒ5ȃèòö6w  Q¼RxÜ^ÏGçÊÕÛ·Ì9Ö=øÕ!ކ˶±€ü©¦âù)X“`I:qSŒÄ¸Œ)>]K!@ÌYqQ Á‰¸âÇQÔUw¹jKNFÀ-§W<¬
+<òÚU¡~^d‰ñÓÉ°´eÖòóh –PB­åÃ=¿ò‹BDêôðÉ\Ÿ³Öy LJq ¼X*`Ú6wY=Ò*PØC2À×ç»á0ñÓ
+òDG^d£~‚ÈâÌ
+øZŠ.V«‡§G¯Kb)¤ž†¤Œ,]1ccQ­ÎO2œ…á´ÒåÇh‚ TÓ÷ã φ»™¼u‹gÂö<†¤|d±‚Z5Úd¥ÇøG?fIiÿÑPU=Ý <G þ`GCp”vö©.W¯Ò*³À}%)ÒÓ/“çÀy:P‚N§ÓX&O2ÌœÂ6ç
+êh»c±ƒI%+¸3“-_†éqí¢BfÑ?X¢=¦ú<=U¶ 8hÎA/*Ï ÌI¥ÍÝHÑÐ[ælÄ•éînx™60ª_{tžõš“KFÏ)`¶Ïß*‚Ó±¹‹ë.V˜o—“ñ,C±±7'Š´Œã"œKýóG:ÃJ‹¶;êF'þ-­Ö×RñI±+Æ·êûVÍb|‰(Ñþ£`wœa+ŽâX|G°Â’ûUölG_ÝQÕu—OÖŸ‡Óƒy@’”÷TÀ±Ù´ ÈÙ³[•ãqPæW“ÌðÉ[çñ–GMÎÊf„V½Õ¶¬ûÔ&`¥?£˜CÍnÜÖW}˜L=»FO+fÕZsÈUÉ
+qÎèÁ(/3ìã[¯ÏõC‚Sçü°b¤
+BšKä;*t»Tåà™Ÿ1gô5_§jè’®H¤²Ī<‘&
+:þÙiÓ„ZtM/e*iùüYüxçmMßÝÎú +D×Åo{ TˆdÚ[»o쨔̬u‚i9¡n~p
+GÈfêìð.†t DRmfÀ&Qý3áv•}Ó¾}À÷òóK…²×™V)*­¹Eµ é£ûÏ=è㨡‚€¶h®`ÚS΀Wvm›bÏŽù2‘¨È—œR?\«®Ï–äTgš®ˆ$gÞr=¯;˜QW碂»Øí¡.ØöÅßÈŸë}‡îy—>Ì­}¢à“RIêM¼•e½¨pl,¤3*ÄT·þÑ)0v’ôz‹ïü1Š4jH¤†¼a\P™ï&?§’©7¨—
+Þ=á”7?îÖ ñËu.›ÄZ=•“ز‹,-~ ‡JÐÚôr&ëm û\Zæâo®ð¼‹I^†ÀÐùío¤Ll‡ ¥TeæN"‘ˆc{Oп ›Xñjÿd'ÚŽ“La.Ï4ag•¦¬5ÎÁ
+^|eV
+ ó8BгMðöŽ5·krÌ¡¦É‰†Î*óî˜E”
+}Åó–CglxkSÅšg;×rÑ?ÇÈ8Œ‡„¤•Ö}Y©¼tíƒÓÚ",É«2EÅV€|ÈÑcþ–í‰øȨՈ
+›¾Ë×±BnWMèõ¦Í;öy‹{?%Zp¶þï,OOÑ^:5šçð0Ä+¤‚¹§jÀøÿ™BX?„ÔÙðµÇ¸ˆ ÐUä·¿Dü.
+é+ý®ÞfDäƒ[䉰eתG×»–m»Ñ€Žve¸‡×o òƒUËG#Þ¯3¥HÐçW²Ðh´XÖ….ÍÎ-€¿BÕ 2µA ¨“¤ý­"¼¯;Ùò mf"8vzP¤ìúH¾Iø6[‘#aЙ…gªÃ&F ']-+ †Z7üRûVë^ ‰j˜©KZNÊýA?6~ç¨Û욃áqÍgŽWÊüzǃ½+àIcauÑ“‡Úþ`öŠ„˜¡‡€ A(¡8ÅiÊP H°:)âŽvÕu‡5›„­™±Àíc¶«kèÑXËa¸Žæ5Ç” sõü3øE +¢2WÑÅÈ­°•òÍ,äÃZ&ÓRÖïªr@”ä4¼ 8è ‹EìÀ°?a*²oѾtü§ ÐäxÖØ<ØDÞÛ<Ž6“K)¤½wíåIXìtcíZÁGPŽDÎú'…H¼hë ›ý÷I~žŽ©e¿6ßpÝLàAü:IØ°³ƒŒRoÞasmÐxÅ»ÖÈõJg½V Ê!n—ú1̃*<¦UY!=<É8õ—LòÝK2_TÑéÓ1Å kžsÕ
+OÁúFbáË^€ á–ßô¶Ø<ˆ’*¦®ôÚÚ[ªO@/iMô—±™µÈÕò ¶¹j‡ƒ9GMzOUõ~<m€ÄÊ“ÅÚŸF—ë*ú·¿…¶ˆç%cíЬòré!’½œÎ-'š!ÈJ¥¾±MFÿÕ“úå: ¦©at4g$©\-ið1¤r§å}êëŠëC¡ˆ
+.“Ÿ²l8mdÇÄ×ÕB„¾É•‰ ¿eI¹Q!b'ìž´ô§W)±„LŽå•ºgÏ‘„™°w‘£ :
+3¡= ϧ‘¥QTŠú¾šèÍzÅ„(¿¡gÎ"ßl®3‡ ”‡îoÞƒ+Z¦oáöà4Ę=tÉK-Æ4ä|~üaPX/D&_õÅ;*¡ÿªð!„ i,ö,–xou*Œ…Â0c*SäH˜èµù¼ŒÜ’µÙ:üØr9Њ6p(ŒˆÿÔLGEË?9Ø6E¦ø Cø6ÜìzU ‰ÉJo½TÓ xõ3ÇÂæ´Yæ ¹ZK®ºµdy—ªÀWÄ ÷—Jbæ°W‡Õ$“¤)!`'<ü¡a¾ó=¤#Û·jõ嘕Wqo˜ý–)_¬HÅ3ÔAIW²~{ŽÑÇî/‹&Ëß]wÞÎZƒòO°^åûµÁHñë)¯­ÿ z¤ÙÖ¶5.7N`‹O:KõhìÙœ=ºû1¯å'ˆ¨d[àÀ®¦ží¡¥gío²wG³Í\û¢922 ñŸzK}·Øp$ÖÈ,b—›rd)^ÔYW† ×1š Ëœ¦6p-eÑù[n$„:J°¨&bSEa‡H—‚ÑW¾öqŽ11ÀcyÇK#m)!Æm±¾59õU$}À[çÓƒç¸×‚%÷‚~H®‹>¬¬ß5LzcxíEk“ˆ¹ú¼Ñs:A²óp6¹önÁ¥+²àP õÉA¡‚éÛôÄ”,,¨Íb6ôʘŽUÀ%"ðÔ”ç~qf?2ÎƉRW‹êKС:¯¼(Pò~£¿˜ e*²»ž¬hq»¯ù‘1'¡Û~PŸÓìªLqŒÙ*£0ìÔϺ Ÿ`tÞYïwý.Ã×›Ù/ˆ' xû:ï+#™:ãàiÝAÏDÛ
+ÛÁ@^“H·vîâó1ôצs²5?ns÷ü*<À´eºbME„NÇúDš`¡æWÃ@V©h£ÿÃ8´¡ ”v}‰¤ìcJVÐ}e!¥´ï »QV=´›|8Ñ»äëTË+E¾+,»0–¸µ'su\~Ñ
+ò$7c ¢öázh˜O¥ó 8Ýúæj¡Ã‹‘/%j±A³Àóë™c5$ Óür’ o|*…i(²^j”-°ó!"÷ñ,°ž'Ôqˆ¤âùŤCU#‰†y0-Hr\'¾Ñè5‡¤%O_JíS<^ÖácP°ZþZ5‚Ò¶m…ú[éîI’àÙ0ÃQùÎÇhpð§Ò•>þ‰­žuê]O‰´öd­ã)/P2‚©:Îçùþ– b ¶9G\ 
+,IŒ¿&˜^ý¾"Ï ¦¢Øqr,Íß®Ê>î&x콋Ád@ÜhìÒZtES·Úå«\¹ž@mú
+eî$Âjp¥dJºlw Äì³j
+Ü5Ç+Iö*|Îü®’UZ­p_%6opõÉ_IO7;”Cô@¢™”人D@2¡B'…õ,0™ânN-ÖkƒS[7p,sÍ >­ëÝ]àÚt¶Ÿ¾ÿòM5nڛē ìhT?]ÙÅ+e@Ch@JH$ êÏ&>2ýã°£­ YúDXQÕ¾ŠÈ‰Õ ŠÃÒâ¦Æ\x+¿`2eÉ µ^´ôB|iCEÊ·\=Ùü*7CRLžÜt›x,3¶J%A ~†Ó`®*w‡Zý.¨#WÈáˆêS‹“É*&ÖLL~'Ñ;¶M'&% ê"×[*moº¿ôH^ú‚ nM6)•U«¬¢WVg§Ä&x Kí{Ç¿]zÉ
+¹º˜X£fÜ<#}ôÞœl:\ ö%\á·Ñ–Ôõ<Eña›ýE>WYŠd÷ŒÂ[‹¡Þ äº\œÚ9IxúIÞpÌšäµBÔ:¶—³ìôxÅÚQn¸ÌÄ/„ÂœõÞwŠëÂ\Ó ùÐÈ/ç:køTqjNÅë“j…㜸\—³†g›d8¤¤ŽšÚ’ãLZ¾Ã¸]âì´¶Ï T&¬ï66ªÌ½*|¥0w« vî&‹®l5fÙšEÉÿô̹ñ$\wñ£O*9ÑÔ
+MpÂœ(i¹p—ÂMœ;Uk>$×,>c§ˆa&¼(öBŽ“,Ÿe£Ü
+ýG±ýN;ã8ñsø¨ï牑1 \°Q“âæZbgxÁqÚŸ¦)1â­Ûw!hK{…Ñh­¯\¾ò–§¢,ˆOÀ°h|ÎÞØéjn‰‘£#ÍúÅ4|ÑÓ²qÔÑÁ¹õ1³Gï¶&dðb<àËVOÇW­R‰<­¦*›¸!ôøP_1[,±Œv÷~Î Š¾rŠ€¹³¶fúÎÒ6Ð…i„ €ƒC#ÂuÃè÷Ê­¢‘i˜=ÒL\™¼æÕÙ¢'¯Æ’•Â835PòîL±ÇSÌÍQýí–Ór& €cÛ¶9±&¶mÛ¶mÛ¶&úbÛ¶mÛÉþï°w[ÛÐ7]§ê´sÐç eˆ%Ó29§b²øǦ+îäò3ÎøÅ/åÚ¬¿ÛŒS¾\æDéH¶ÎÇhyvÿ9ž^¹þS”s9õsꔜ\ÊP[ ãÇcƺîÄJ¡Cr‰ŠÂéå»N,à] 5ý…–
+ý¿'¾-ØGŸs¶Ö¶
+48§4î²Gá0>¾Wlx{O..ʼn6mD¸—ÚµQ¤]ä]Ž.†Ø0k–:3ê‘M}úf¸âH]*Ñ|ïâ |@…Òï‡H ™ÂÖ„ Æ;¾晜åâÈÑ¥¹Ìx0»°WäîÎ{Þ~
+ƒÐ ñ2×"ËOÿi"4§^¦"ˆËoå<ð­áÏ'¸ä[ÓÄõ* wX¼ê `؆ ÅuŒÕ×´$¦0o±ƒ¢ã ÿnlkÄ=³÷0ú@TÓ~"Ó,àçÜñOÞ\à}ü½ mxTÀÈ ²?+Ÿðwíxª¬ò“ÞcÄ1¨+EâyT;°O
+”¼´„Ì•4YHU†Ûî: À’´6c§ŸL<ôwÐvbif”” èAÆ1`Ï”yþ–b“àÂ…–WƒÌà.šžîý˜ìãObéFv©rüh€ÕÌ} §¾ FUStŽüõ¥¶£ŽÆÝAï¥i’h Õj=úè@ÂÅðÂÅþ°•¼Sá"ŸÎîÓb¸®"úáÀT°îJƒôúïë&n‹™Ë‚'ÊøOIµé„o„œrÃîä8й+óu¯é¬¦ÎuܬȔ
+ AˆÄÒŒS€w¢3"cöèF‘þH™ÿU¬þ›€ªb;6ý@>œãžÊß7)Sz'Ìä­Cs"Oõ«—$Ö‡Xž|ê#ϳ݀¸®3Éþ¸x0±Ý¾Æ@ÁJ&íæ×jJ¨µjÃ[ä-ÙL˜N`žFšxóMCÜÞ ›³R_Óf·âéÛßVç v¡>  $àdã<#OG1Û¢F7û™m@`ƒ“rº”®½C><ªˆF[·ŽI<.f$#Ðüõ‰F¼ úóÓZ—zð}‚4JÚ‡©‚­oI†yjø[xWûêJ¢rédªM.<T¬¬š–âà˜.LVÙÓÔ¸û‘P·ïëÂ1ÌfŸ@@¯1yO~CnÅŸædçn$»2âç
+J’8±ûüÙM’æ”[¼®Á'Á„SbS
+¸âÆ°ŸË_¯h jŸ*5Îþ¤.D#gÃQ‡wÏEœ l,›^BŠLg<$¼]àÂñõøzGÖÀùš>£ é¤+ÿÖÁHc4àÎ’» KA(‰ÔÎH$<!%È…ë5 ªÇ„÷ØÑ
+ü}«Ò@ÕAšêïÚX²aÒ
+˜=–ú™ˆ©hi$BnÛÕYoÊcFTNŸûìèÍ2õë”™Ûøà§{¢Ið§!U/M眼ԴŒÈRgªÛOCº2Èz –æÅ/ñŠvqü0kZÎ$‘T.R©fÇ­Ðêƒ
+MhÚÿ„¤BMsß{€ðÕí,UtËm YÅk¦X—|Žª…Ò/M½l=¸0Ó-R1ˆ¯
+f_iz,©”›6]% ¼5¦D–Së:I™›&ziŠ…D¦>ƆÑåϨÓ})mŒ=TmñyDÊö7©ÏîEx×$Ž¾—6êñUÙªû®'.•ÁÛ|uKuË 5y¢¼qžYàΈf'«|~ÁÅ Þ°Mœ6Qï¥ùTú‹­K¸«ÿ*èžø’ªq7
+ìÎ[ ¶ ÿøVfÄX#Û;Á7å‰
+SCsìtLÑp|† _VçuÞEª¡ôx7?Ž ëDäMvŽCÛp—àŒCˆ~xeÇè ñ„E ©Vš‡Ûé¥ÀÜpŒc1C xnÏÛppÔnÆÀŒ:ݨ¬}tS4ÎÕº´ÐûKÜ^ÅÝbh6˜,•áNfÊm×A˜ªŠ ·×鶠™‚mƒpÞÄÄ%å˜swÃÕö)
+5n V¨~vu²H§<mUv€[A„!‘#%2‹ä
+Lø9Ñ{ýœË å¦ÑMj]3þ
+ƒÄ(}®™˜/—BÅeUx
+Sêò Uµ°W¦+­¨SÒÇp§-ÿDjë3Ž sneé6O¾ÍlY¡¸;ãß¿Ç5ú˜Lý:àÑ0Š[5´q!‹:Ms<”ýñÊ’º?ú„
+›Ü«¨Ö5"sVÚGZò×gkïá.W
+ÈMBU7{:ãKIÐ
+ˆ—ˆw›&(8Ü“æ½Ì±ñ1ÑÔ^Ú¯Ãàrð£0ë[kf÷Õ*}¹ß@„Æäö}7YÃê¨Æz'·KeªÛ$Ó²bI EÙ#ßï{†,’æÕ~ExT.!Ì.ѸqGhý9p2À@Êp_Œ^Šòû»âÑ@Æëøæn ^ãÂÍ’ºñjQ‘ãj韹ԤíÌw/®xáúÄ3@ŽKÑå=µ…T¯à™ªFãõÏ'‹J.ô'¤w£1’ñú8ŠCå#ðóÔ†,éx‘ï6ÓÆ/Hi4’&ÕM~ÿh/ˆGðvâ2•øÃ:jp} ¤gIp;pƒRM1¸ÄÜo¡\
+rGþ@Lrêjhx%8ŸÚ>l«Ý^=é⪲ F+©d€†µ‰¼½¾B`o%冴ržÊ7.Õ…þÓ”.ÓÃOçkÀîöHÐ?šnü\ûÊ—–ò¦þIØcl6_å?2aZòEô‡C8žF~Ôè,KzŒoŒ‡JO*·ÒÄh^–R…{Q '!²·¤äõì‰
+ás(;Í9r£aC¶Ê`:ðY;ÛQ™!¾4Ê——rÌ|¸’¢Î_”àvî‰ÐRëX.üfvÜd¢9=‚Ð]·b>ùÆÿÌÎë'Ãè¢9"¶•†³¡Õ—lS-†ÜZAqªïÙØÕèúD žÓ”5Š•sAŽª¤{ žç?˜X{.ú:„bíò·ëÕÊÝEhâ.ÍúB_ƲÁæSË<hS†–èð¦‚ÅóX0áJ÷¤æoHÖ^'‹¹.W‚…¶‡{¶Éxl‹¶gœJ„fž²Díâ*ÔpÞõ‚Þ3¢3ÿ7v¸œ=¡kÖè6zø+òᶑþhóf …Y>vçô]þŸê7Xà…ÕÒ— Î  UÕD”7¥OªˆÆr#\¿»õe]©ôwÞ#Ê q°ŸuMÙþ›Šü$ÔÍÈͨ­ÎÜ°é´=•qð#çgþÕPäŒÏ´áÏûójb2Žû‡¤S°RY«Ã€…rSðûÁ2ïü‘lãïPi5v\?%•–ì|]‡?jßSšaõæ…à ·ŸâK‹âS7§xÐhît²­ííXÌ÷»øñ½QYM·õÉÛ*02÷—'(~@÷*cx.ag$Ì.6ÊÎ0~zGóÓþZ²¿o­xä²&ËN‰U]œPÄZ/ú~Q¶Îö\[Ö$ñãR[öé–’t—/)$¯h´<¤ŽcéýÃÄð±9>Z|É ˆÞ¨¬ghH€ñj~…îç °QÏšd"ÄÙdž>É×¥‚–ÉsJ¿öãô5BíìÀ½Ã¾DÑYÁß9TFÛiô…H¿=~!µ”_£ÿÕhz Ûé³RÇ=@QXÚ›$ùQŸ2laŽ(ðvºQ„ ]jŠÖ-`ëÇ8öJ•§ä.?N*êh âÚ2T
+êÙ©ï•×`±–¼ì«í‚ú{}Xíl\ER«êb{E,ìêlÁ¨ž¶`Ë eFõÌÔøÜ ¤ó¼ Ú˜Â_‹Ú}L݇yûCö=z´©Å¯ž.ÉÔQ;¨iœ„ 6J†b<YÔþKKv”x–•L@ªžZþä&$'
+ûÛÎ ´*5R]‹ŽÅ^ØÕB¹*ú[wD„¶ù×Wàaͳ®nNo<cÂQÝ~;ž™>j ‘ýÎn¤‘M©l"cÊ9Ѷ›|îÄó¯”ííU}]íbÐn ܮфôK¤‰þ䯸¡§ÚŠ±[ÂãÏ.åð¢X Øm‘yLpÅì•\’ho;¶ÓèïÙ±Zظ¿‘+ÿ¼÷£Ì®Î2é€_zñÌ·^ioůW'<ßf(àÂÏ›¡‹"Ç™·Åô%O™Îr(ÊQzΩDP±pH*u`ب#_çß!×Vê´P2âý/ˆ|ð ‹„oçš>“ÇCü±ð+5ëã(w8ëÉ,4ë1Ù|†U_5Y}6bïü§a…«JhÛà’;îdÁq¤Ÿr(ÂkVU˜U”UH3~Ì cs_lŽ+ä¨<L¦Oy§ÞŸZ6Œ"ès~fûQ6ƒ›™J÷WãIø²ó`ø9„Q3¼j9p¬ð<еó¥ËbÖm–à%»Ã p¸«C’ø|' yܹ·ñyYð'µ
+»°fp¾bDºi7n©•7¶·tišy‚‹Å„ïÕ­i-šyç<á‹™ãžG”2š$M…8†]æœxÝ™+ì—ƒIÂ48
+PÔ3)lmŒ;œ¸—ü“5|—î”+ÀTÅv‰¼Ô_òF^›b QãLT?yÇ¥ðb²èewïA© !ÅdYò]mÝ ÏÈÍ[ŸC9Év%?Ó8|
+\°l{ˆ<­û$\Û5•/—»ì…ñVT~B
+‡)Í1p’}l‹ÈÙ¤û¨¯šð1ônQ“Öü:”ƒ‘96êì(…+õƒ<“4Ã7Q|ÿF1°²¨üñ#\õl1ï,äÝ?7Âeì7®Œ½nØ<É„3ÄÓ›rhNBRòÂÑC
+^[ÜÀ!ÄŠxMcOÝ—ÙPFt>l¿‹JF¢‡ßÂöð1’£†°åïxDÑv hÇÚ
+¥åã—r¢fY—òU·zifÁUÆz*JfU¤ËÞ ½ ýä|ÿ:Ð(Pk<’¥WÝìo*Á]ö…gP³Šþ,ÚFjî¶%™;ɘ¹á9L9.DœÇǦÝ@sOµhòÚ³BãtÑsÒ~ˆ®›×)-ÉA
+ÇГöÞVMýͲ:“®³m›ÓWBÖþü/ùÁÿ ±©¡“‹½­¡“5Ìÿ
+endobj
+953 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 2
/LastChar 216
-/Widths 2156 0 R
-/BaseFont /GEHCPQ+URWPalladioL-Roma
-/FontDescriptor 735 0 R
+/Widths 2721 0 R
+/BaseFont /NGRKNU+URWPalladioL-Roma
+/FontDescriptor 951 0 R
>> endobj
-735 0 obj <<
+951 0 obj <<
/Ascent 715
/CapHeight 680
/Descent -282
-/FontName /GEHCPQ+URWPalladioL-Roma
+/FontName /NGRKNU+URWPalladioL-Roma
/ItalicAngle 0
/StemV 84
/XHeight 469
/FontBBox [-166 -283 1021 943]
/Flags 4
-/CharSet (/fi/fl/exclam/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/circumflex/quotedblright/endash/emdash/Oslash)
-/FontFile 736 0 R
+/CharSet (/fi/fl/exclam/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/equal/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/circumflex/quotedblleft/quotedblright/endash/emdash/Oslash)
+/FontFile 952 0 R
>> endobj
-2156 0 obj
-[605 608 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 500 500 840 0 278 333 333 389 606 250 333 250 606 500 500 500 500 500 500 500 500 500 500 250 250 0 606 0 444 747 778 611 709 774 611 556 763 832 337 333 726 611 946 831 786 604 786 668 525 613 778 722 1000 667 667 667 333 0 333 0 0 278 500 553 444 611 479 333 556 582 291 234 556 291 883 582 546 601 560 395 424 326 603 565 834 516 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 0 500 0 500 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 833 ]
+2721 0 obj
+[605 608 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 500 500 840 0 278 333 333 389 606 250 333 250 606 500 500 500 500 500 500 500 500 500 500 250 250 0 606 0 444 747 778 611 709 774 611 556 763 832 337 333 726 611 946 831 786 604 786 668 525 613 778 722 1000 667 667 667 333 0 333 0 0 278 500 553 444 611 479 333 556 582 291 234 556 291 883 582 546 601 560 395 424 326 603 565 834 516 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 0 0 0 0 500 500 0 500 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 833 ]
endobj
-713 0 obj <<
+929 0 obj <<
/Length1 1614
-/Length2 24766
+/Length2 24903
/Length3 532
-/Length 25647
-/Filter /FlateDecode
->>
-stream
-xÚ¬zSm]³eÙ¶]uʶmÛ¶mÛö)Û¶mÛæ)ó”«ëû¯:n÷S÷}Xkfæ92GÎ{G,RBy%c;CQ;[gZzNE5ykkc ;iA;kc‚3 )©£‰³…­°³ 'š‰1°‰##)½‡£…™¹3ùõYþ !0ôøÏÏN' 3[²ŸWk;{[çˆÿçJ&&Îæ&¦Ö&Brò²bäb²*b&¶&ŽÖò.†ÖFÒF&¶N&¦vŽÖÿ¶ 0²³5¶ø§4'Ú,''{#‹Ÿm&îF&öÿ¸¨ ìMm,œœ~Þ ,œÌ lzàlG`akdíbü»©Ý¿Ù;ÚýDØüø~Àä휜Œ-ì ~²Ê ‹þOgsçr;Yü¸ ìL"íŒ\þ)é_¾˜¯³…­³‰»ó?¹ MŒ-œì­ <~rÿ€Ù;Zü‹†‹“…­Ù1 &p413p4¶6qrúùÁþ§;ÿU'ÁÿV½½½µÇ¿vÛý+ê?9X8;™X›ÒB10þä4rþÉmfa E÷ϨHØšÚ0Ðÿ›ÝØÅþ?|®&Žÿjù?3CñCÂÀØÎÖÚƒÀØÄŠNÖÎù'%ùÿ›Ê´ÿs"ÿHü?"ðÿˆ¼ÿâþwþ·Cüÿ{žÿ;´¨‹µµ¬É¿6üÇC MðÏ%óØXX{üßÂÿ{¤šÉ¿qü¿¡H8ü4BÀÖìG zZú3Z8‰Z¸›Ë[8™˜Xÿté_v[cGk [“5ÿÕHzúÿæS6·0²²ý§í,ÿæ2±5þïÔúq:95uEYªÿóFýWœüòÎÊö?Ôþ½;ãÿ\üƒ"(hçNàEÃÀÂH@ÃDÏðsà~øp0±øü_2þ ˆá¿Ö2ÎŽîZ?eÿìü§øþk¥óß`DlìŒÿ™%g[ãŸñúOÃ?n#GÇUÿuâŠþõ¿ÝÄÄÝÄj}ÅΈ+Ø2ýw†szîÈ”°Ö@ðHˆ}i£rQ]¯_zøG¥þGmmÓ çW»ÇòûÏ#IÊã±>4ë_½©&×ù8>ÄýˆÛdlTÇtº¥°jÑ^7KÒ» š¬ôªÇûS
-Šº%`¸3LŽ7)ü‰] üQHžíá|ÒâP»š
-ÿ\%ý}þ54>:2Ü{Ú„M•IÊå
-KåïƒÍ§©R!RÕDzÝžeÌ}øØ"œ³\ʤ!g?5íµ Îk“T $f}QìŒ}}œ7Ãë–aI­zQ£Ø`{1®ËÊ›¡9sõ‰ór5úË<#¤=ø…ˆ´±36…è4Ó+òŽÇ¾a‘Ïp:‰é"“|:[5P6“Ó<M`IÍÍÍLÕ‘˜‡‰ŠŒDa_gÁ¡Ãœá½]é–§ 9ç8sêÓšÆô e¬bô:miØ*N±«z|+hytHOÛV77Ùa‰
-×Nä&ýâ3­çï²E@\æYzm¾~D9šru] ƒR¢á×0u+»Y}Îî+\·¤èƒ˜`Ixï|P>½«D¡;MMM¬:NNIˆ0þŒÞû+âÝzzÜðà\
-Š—€’»qt‰ÿß)âxô0EBå)¦d4Ôà,Y=2€Ä„ÖÈ=ðK86iÓ·½µS(ç óQôx;”ˆwMÒÝ\]°Ň„ŒŒÄŽ¸¼'Ž‚ŒHè¬|Ûd@I¹²‘E —çê‰xERµÆ[ºª–ØÞ÷6µt×Ûô”Uâ£ÀíÇÏcí—‡²áŠù¥t/ëE½N r…5õƒ‡À}[ÖvÞbO¿öxî3–^üX³~ݱÚtX”·úbÛ»Ze¦B}Dþ¡¥±{dyÉÞâþÝbæZR4ŠR`s§Ú1w p˜aºÃVÒ}ŽÔŠ'X7zÉ(S†Å£À¥AKÝÁÆçr&ì椫û\šì‘F­ÆLu×c¶X‡YÈnT<)—l%WªzÈ
-Ì0Lo”2´“4c×±¢»ò“÷é·%¶œìÔr÷«rOxRæ@oÑ[#OóÐY„ý‹UՈʼn%?¼H»@yÖÞãLùbùÛq÷›c}DNCýŸoì sÑr?áƒÔÝÛóŠJx>æ?¤å‘]ò;ÔHbÓ‘¾tTï¨)Âm"È|Ó\¹¢óCÁ†e`ç'(Ël-zÝÇ.æf ì„©ƒ5 /Â/‘˜ÅÓSþÃEÞW;mdu‘ýêØ®=)À6li»ÙæüÖEÍX»Æn–ç]6
-Ȇ§yð»Ô™6üÏ2Röv•ŽQvvåôTÂ*¦(?ç)m¶5”OVÀ#8”¦Ú•4áîPñ"!Ýa¶é]\yc™··sãAZPU6gbß+:*(¥Þ'V­PÜ…¥Û)+#®¦.ráýô[yÞ]²ÅÕ¦<×µAÅÊ|…ø Ý&Û¦ÖŒß,`ÄÆ
-\w­wñ0‹²R§ËJ†H®oQSÓâ(b½,íµ‚9¹/#Ýýo ¹|Êq3d›p+¯º>2£~ìîšzµ´[=1#„ãW*Ža†Æ4õ
-|\4YÍùô\VŽAò¡iÙœÐV
-'Œ†Ý¥ýrˆøœ]E ‚ˆó(‚ƒ+c[€Éj‹®¦Qíä¼_Þâgˆí44U÷“É;2–×LC
-JOÉÒ4WÑœž:óû\™Ñ™ïÞ! ×yÖ\3Ûø=«/Τ€çÞ¸ ¯æŸ/8ˆÇîc+Š GI1(yBª5ŠÝ
-ˆÐ÷™êq¥@ûÏ|åRøíçÒ¨Zqé1#.²[Â^%â”(:^ŒD”ÚPØ•/ð
-ÐJºN$†¦ædœÆak¯n¡mk5¼{n
-©.׬nà'' 2‘î3ˆ2?g‚Ó<ûeZ‘™a÷­6™'zOÁt­:ñÕBzÚFÑ£AjÅ6©²}Ôq”‹ðü¬fŠ™ðaNõRäm€É€e‰aS—š=ø„PD‹ Å©?Κ-Év“Ü*.ºå„í_óÄpçÂ’EJ-Mn’†´#Îó¿?JýjÌàUàTƒ*
- dªÑ‹ï­M1–7°¤*’±¹+DÞÄZ·íøjâ?å
-”;çÙßëÀÓùÙ—8Ç!‚Kùz.Áøò¯Xñ€¯ÈHêKŠ\M(€Á½µBO8 çXE_æsÃYZ·èp6aaLÞ5f(wS;áKéªOÙÓzôx
-Õ§µ÷YÍÛž—™®Î燸-f: sôqó957ì>\Ç´¶ ¬C½}8$;DPì…eªì¢V¼'­ØíÄ<È“½Ü¾NO(߈]øé¦ÛÅr_[Þ*ʇ¡ÆËÆ<Òx ç˜î®l
-Ä’£×¬÷°zJmp¤0ZgôìuáÜí™ô!F…ªä Œb“Ð.ƒ ‰¢9wØhQÝ+âGùTjx­~wtñ».^jËð‘g&rÖ̹V§#KÚý®Œ¿çqÑHºö”Å~àlsLÓfH9áNjn£W4`oÑ£:»Øš^ÀÅK¥ŽÒúƒòL9ôlÊ0Û‰B˜ÚÔ#k|yË¢\Ÿ=*XˆÕ<d0 ¢‰úJkáÜ«mµuˆ„‘¯H`Ž6彋EÖùñïùBÅ«/hüî#Ô^†§ö¬i(]‘×Z]°&ÈC˜ìö¶ãíöù{Ùj+à€Ú‘ZQ[){¤iZ_Âì“à=Fº(s!:T KØ;XžZÆ#›DÂ,vÌ4ÐüQD~ô¡²ôå *×BêbŠµÊ´è˜:³pu þ§þ9rK28]±„»]Êö]– ÌiŽ rÆf§>Ä óRi× à¦H~&¸·—ϲSz…€ÕhßÝ0Ö/äH—Ì-Z‘m®Ûû <€úQ³Õ0zÒבß8r¨tIÏ'Õ`™@*ØÆ®@fÃ&€IѪ¥v%QÏ:®Á:.s&ŸëF­¤ƒQüʸúW ›_!Ò0sI"A4ªØ¼D×Ä÷¨C!n†Ñðú;+‘Öº{ýŠ÷ÊdÒ”üÝz/176ßÆÊê0l®«ßCヤb£s0 N­÷ä?‰ X! ¦œ´Î`ÿ¾‰$ý:Š¾]‘µß«kw#+‡üåj$P®¶½¬6>žæØñ^70•öKú€ø$ˆ]ïï­óÝo¸@g\³°G
-9ÅùbW<-—Ô9âEjRœáÖÚîö©ÝRËâG^ì sJ¬¾bíÇAÂxÙýeØ­ÒæÊ>•¸jÀ ,WÐs
-ñÝ‹¼I2ˆô|ß{1¦[y#²š‹9ö_ÀSƒæŸ’™fyf+(ý
-K#Îø/÷2ž;¼£§Zç$Êò^Mú½0)íN(ïó‘µ<‘Š6lþ;9ÅуŸ)Ðæ¦óF}»ºÐ=À¸¶V Û˜Å/éGŽIÌYW¯µ=·ŒìŶÑ;˜vìbs¯+YÈý/âwåáNV­&Þ÷¥0óŸ7¯Â$6/ ÈÉa…Ø藺¢ z|£>†²ª
-«Mˆí&/·}Î I Ø%΄%0W¦É·¤¬´{âI\5d§1ÖÙA)£7½¡TDƒÖcÆãM~ÉÛ0l4ÚÔÕÝ„ùäˆ÷)—h7¿d~aùruÖ[l¡F÷è\)ãƒ|<kz?D \]ò7ï2¤ÎÐdåÛTª³ WdDmI!÷Ï€S‚'#Q~ On )vE6ün¡Öi¢ Ó€(IIŠ?´ëôWÞbÚ¼%­ÂbAP­`6D
-–fçÚïC%ÇÎbl·Å$ûÄÒéæÅÇDÙdÿ
-Ÿýpô¯°0TO@,{i`·Î¶ÍÆ¢ãÚâ×Kܬ ¾yOàï–<ÀQ–
-ðÕ Ž£èÈp¬­°"M¸p‘)š!(´Æ[É⯻¹ÑòsŸûùWÅʨBP¨h Ù'“¨¿ ÞÞÀOԫøŠ½â{Ë eÊdëô¹Kx5QªÎ™6!â–­a˦½ë}2 ¨Ýˆð+0ö|3k³Ÿr™eÈ[A˜ýl\ÊŠ}óÃ\&Ñ[Ããóqt“´ú8ûy :µlõUñ®¥"„KЯ¬’Cpeªb•^¶¨¦oÀªs'ª¹þ¯cÙKñ]ùw+VuN|äáù s.…¸¦Ÿn ª4—&Ðøš{«î‹½±é
-uW–ÿðžZ—â9«ÞËÛråŠi~Û0¿<€G<æÀ›3¦?›(íPÒá“~šGÁqFëÝŽíƽHšJ+3"Ê«F…@™'›ñ‡îIŸŒ‰õ‰ZêÀ7Y
-gìзt@Š™+[Ñ3²/*;œ÷Q¿.ønÐDâ]ñê “R£Þ?*ã]£_×êCék~Á3A¬
-$1üf¡
-‰¾É%|¾Uůx¯¸;%ÒŠƒ}5]åD„¢J›œ)h#?yºâþ-^ø*#G„ Ú”¢‘üÀÄi;IÑÉ2çŽÌ/~é)Ñu 죯ã3noዯ78]P³]nÃ|¾g
-6ψ6o‘PBšP'̧AFæêdf?P0dGC×´rW›çB¼¼6&³SÊr¥Ü •¬SS‰ÓòñÞõT9Žú¼K)Œ\û)°bç¶Õ†3´$ZÞ#&†×ææjsmÂCf‰àS4XäHF Z”ÔzϘ(Pt
-|ÿÖc2›#á¦$'j‡ß|c›xß3ÃlÞ“”3Bm€Ü9ºš?¨
-LÈJ„5(µ
-S|ØHˆGð—Ã=>ôԑʇÞw1®V®Áç€R=äŽK‚uW—e“ 4¤µZ^ öçý†Ï#ÃÎDžâØmwp#ŸT-Œä{Mô§SqêßÑZ!¯È¥û;Åcï¤ág´SƒqÑq/V1aŶõrR€ñùòdfN51©é‹å=túúöp›˜Ùøfqû— áoœ
-#‘%‘Ï+0{—¹Vx³½û³IÏßç@ ›AÖå]d˜± ÜšfÓ 3.ˆ•Lçû^«ªwkFOpªÍm“é éâKL§.ã¬f0æµ2x‘$âGÈÛ~Í…†ÙgpèÙzœlŸTêŸß'Ah7‹#m¢(´â'Z %åÝa&˜P[&W)íýyÝaHÄrÇxg+Ešê»ÎÑû ^äŽ(úÖß `–ºr¶jºù7Yþsß›ûPDS"äÊ"pqšQ¦Mê´šsËÚ‰ÉöR'  )Ú0çöÌzlšºð•`^•¼ßÖ ——úq2‹ãqÙ•ÚüŒmÄàðr²ÉEh
-¤á¾}˜D'N+nš~¯Ðß0’ƒo™¬WOÜs:¡ðwaz;A³cJ©ÚäA çÖûÈ<’+UȯÉCvL¥ºøPô‚Û²sùô* ze-£Šü;2 «ù«#_š¤£s¾þ vêÄ‹úñe‡Î‡CØ“¨Ï>¼»,æñ’peàùhôm2’ÏÝ°MÍ[®¼¬Ý’‹÷ €"_o UÅôh£ ÖB57„ý^æÛT'kiWCEÏr§ó•
-©ØWÚ¿\N[Ž”ÀöŒÍ&nâáµ9vdµÍ¢–£¡!Šã5iAÅ@ñ/*w.¸Ã(:³›Åå×Î6îu1Ü3î᪾ûõW¤®48ð“ã‹KÓ^¥3Tòte:ëù`Ë"‰‹º‚p­,»iAX/†HÛ˜?äµÞ)RR«Y?êxjÒ/½)‚P8ñ“—»C>Är–BŒ!†¬gÝ@¯kîÚ“èNü½?DÆF¹U<þ5”I.:´s¾Ÿj-p“Ã䊰"ŸªcÂ#Œ:B +?/P— wég&åoï²û×!æ9œa pñ|Š®¥Þ²K5lïøŠÑ9„CF †ºž/õ¬;¿G@!íxc|ȹD¤.׎n^H$ßÄÛÂÓq]Èõ+É{¸i™’
-“*ÅûÖ€H-eëpg,eƒ|ÍaJtžŒ/dŒú*Λ¢ 6ºK2;”‹x'.QŸ[å ÌñÚ:ŸÄTß $$¯µ“Í¥¤·4UA
-~:Š0NÇŽŸÂy¨r“Ñ$85¿Aš«`!¨WÄF'*nNÁbt*Ú*¼ëëÂæ;ŠEôû”ÕaÇòõT~ÔÖ“S4Ÿò3<5×Ø\ÛJ´Æß&æ–“O=P©[¨P$“Óµãñ€ èiªš_`Ž.Šó{h/"•"v¥¯CŸ)-FßE¶ÛA<Ýï KF‡é9 ‚'ýøa¢4*$'=ÝèO áequGf0[éÒ´ò¢ïÑÞ7™Ë©4€ÐóØxâ%%Ì:¼ã/º.@ªã#)NˆÈÌaÀSt–k ’»´jˆ5b;¦¿J;÷Ò±C°7·ä°ƒÂKŒwA¹5S‚é%8.nN`ºê9_Žû¡ôÓ;Sæüê\g|¢Häae#§û×çÛu¦;¯ºÖÈÊXšŠäo+7×m4”°‹ª0Ýë#4åâ8hù‚˜RË9«»åì{°S©ã£›ªˆ¿z rª“ÊûýÎœ•VØÖi!z_)õ¸¨VS[i²sõq£Ë%®µe?åw«ìbØ-…97Á |Êš aü’Þ[
-4%Å5k£½02ƒÁw¿b¶8y<•«ápÁÒ*Á–Èp«¯,”&«‚rÃæG€Tëƒç¦£¤å¿”X{Š”ùH;_ÕZ ¼ë/i)ï1Èû£.5n仯ðå9 =)ÂéÌW%^}@|Ѧ{P`Áíea°,pS L§Ü”üÚ®Û7CÖÄbÀtÝzÏ3$rX§5Ø¢Pü–„˜jW~\\{ 7NìySE¼9 ]ºž½"„i5¿ÓúÅXôxBää\„“y”\á¼¼!‡k(MÂÖL]*/öðéžä§FJ{Y<Á&eš¯lõ‰Ïƒï…Ì‚+üŽŠ<Ù@9vOŽ’¤ä[RY·ZßUMZûp4–DagPcZ‚%V_©Þ\;=MåWÛ¾ÖG
-›¶ƒ¯ñ¦¯<¢—h¸E“;Ukê ñ
-J±&éù雈‹˜9›âÆæZue)äG $ LË#[|íÕϬ4ÈÝÕbO
-€£AÚ¤x8mw›þÖµÔ„±ßxèÍ#ºaýªU!˜ù´TßN.ÓÙÇ-É™Q‚«iy@ŒWc²8qá/øç ‹ïåqYw'`:ÓN·ˆ=
-*¥6©!bÆ¥$ž)ÈFå¨3Çx=H3/xR ÎWGzÊt¡Dc€Ê'ÒHD´öXM-®ÁöpáØîÐÌ’!#ŠÅø*ÒÕ Íè/<Ô¢8>§Ð†ó÷‰rŠeÀìåtѦ’ ¾Lñp m… U?ˆ+
-½ŽîÏ>¿ÇrøKKíùƒrÍAfjxy‘ ^W_ª^ø‘UŠäNGReÈ\®v/ÖVö†¶Rú׌hÉýy3˜Œßc¼b'óÑl«ð‘Ä›k,¢°§ƒ.ˆkx„Kªý( 9×^ÅÈ
-…d«…œ#£}þÂÀÑÜÂG( ÑhQ/Um+‹|“·^±OI$ѸÙ0ãÆVèþ )ÆJ3ÍLJ_ñ·ÿÑLÖ÷¥Ÿn­Þo”vÒJáØêqmìíçâ%Á­Ãcœ~ªzVÈ‘søqÕ g%ŽQÌ4³æ`£E–/T““?§púyÂå[uïлJ÷ödhºHÐÈÜlM
-Å s?Òr&Fd¿Ä6ë&>N´.Š ¦¾1:¹rP1ûØ——k¡f)ØdQmŸèÄI BÐä5Mþ¦1T¿`m[;­z!î_µ±=ñp)ä5^Išõ@ÑðÈ š¢žAò'tG<ÞÊÁæa¯šm-mn(Ø
-‰|¿"]ˆnŸ†GhS”C£ãžä.%^=‰Â žš| È%ÿÅ%Ÿ/†5¥ntnt I-¿ÊÍÈ.-ÚŠ
-˜4ƒ¿à†tæ-ws(›¢ü À.}!Ë•™ª^‘ 805D|~ØfÌWŸ½æ°›ã‰Å9ãqÀy[eN ù~TÒ€J…gD›¼à%HõŽN´W¤Vê Ü©&QXS²;^Æ#~o ÄSÙÄòQ¯¹Omº¿kÊ–»{.
-àé%.@”ØÀÄZPÑ}ú¥ÄÝØÇ<†,2xˆá+„P À:І¢€XH‚9É2¯!I‰¥“–mõ놀)ÓLvÒÀªÊŠ‘¤®­‰ŠI¾ž´ÀJ€-um~5SµÏ?¼‘ÞËxXkDZÎS§ꊿʥ'ÿâA“EÈz©Ltª=ø½¿ˆÀ¯’ëÊ›2{@?ï5ºûšõ¨N …&øºòȨŽ3HKãGš‹6hXle¡ïÿ–kMžÍMxßqhìàV…Ú¤ki1IƒË‹ë°ª¶ƒÊ9UFmwY¥YññW>èYM Ð7u
-Ç:êhפ­ߛ֙C9߇¬o“‚/¶z>‡”8Õ"¬pÔ"8f@xk©óí…f¸®söšË‚ý(†'ï »Úƒ½pLjt:1[ɘú‚ËHâûŠK¥Q¹ÞAH)†3W.‡å¬ÉüÖÀU7¹þ"ݨ²_mz$(®$åÔ^ÕìÊÆŸ‡EÄÆvPºÄ¤7/' ìl\du#vتç¾½ììÄ“QP‹qH{Ä$5ƒlíÛóyïd? 2$yá9MLºG%[!/J™Í2an¶ÁœÞOz~ØŠ9@5ꎥ;V7ÎF FsÕàd—ûãת?siÜ5$$éD_j(¯Ü‡ËOÒðBO¿šq€îôN»#.Æ/8ZëùkVŒè‚¹ép›ÆjÕGpéÎØzÇöÛI9´HÓ®"!ÕJˆá«OY¢Úîµ5¤=.J×ø2yØPK0úÍÙÃPI¼ ÌIñ$GÈ^˜ÆºÌ‚cý%úE˜òï„cijñ¼•9‹ž9Ñ’l{ˆ‰$ 0¢w¯¡&jjia>’4\¸ KDÃ{pÊŒ#?ÓA þ0›9 °ñ-D>"ª:c?ܺÚ~†‡^e55¸l
-:kb¾ÉLQÒcèâåSŠÛ€ …l±Ã{Y14¯ŸË#Y‘·IUHš6‰·'&:,q[ÞÀÑçºËÔg+ñA¼dÖ/LŒn”•ÿRÔ
-ˇ—ÕøêMCEýŒw·òÞPðÃ]ï-¼5L-§Ô²%\ðd*]®K¬qtmpMó¹{Â6Dm1Ð[2m¢ºûw*QÝd‹Q“÷\ÒBq¶˜™2<ôÜå `ve¹¿*9GiÐÍ
- .ÓÐ']ÒÀ^Od°â®D—üå„,?#ÞWÖ³bRªv×èSž¼˜Î§ÁØ$ôÊ`mñ 2D=ón“þ´ÁžD㔹=õk½IPïÅvƒJ<¨±ÏÞtݘÍZ´G U^W0äõ¬’”¤¡ÌšÙ=JéSQŠT#’åOµŸ>]žAß÷åʇȆ³Z!“Œ®Íïå>÷Ô‹fÜ.å¾Ó;ö§h gXUãÿ‚yXÛ%…6,˜Ä™T¸«úÊ*1²ö°Ò”"‚ï3Y¶m"ˆ†s¸µÌ· Rþ;ÕõµU§é±8fŠ•ì0A¾Ç¤‘oxZ¼ÒÀá¸+ÊNVkú÷#$ Ë£6\4Štó V·‘D^2'lRw‚ fÈ2Ñ[£Ø߇`Ÿk5Ñs kÜË·g¤Ãs© ÛÂÍÝÍŸ¬B?1 |k6*yf¡3ñÚP‘|Büu+ÁËNõ8XÄôÈä‘¡ù EUQÊFÿµð¥¸ËôiÔ2¼ð`Næ}ïT´?AËÒiÎâ ú[¼5¿«-ŠCLÓÇUY$ÐÀéëh¤®WNÉJB-þ¾ÜaìÚvvÚT¤‡dŽò[µ>Æ–ø|sÔrèCd `¦Ÿü^†ÕÁÊãDÃ*ã%­ã»òýÏŸ‚«ˆ›óñÚ àfX¡6øvçŽÒ]©Â—ñV¤M"BÝèù£=&w>8Kºä*¯+– ¡ oèKᣵ4æx( =¾$h%H
-£VâRÑ
-ï82Ö&)°"¶E;Ü´”ŤUYvƒÜìVZ9M*­µjQSJ­)‡Ÿï@LH§Ò5Èþ¥
-½~ÒoÍdW)(Ö€çÜÀæP»€Zø¦ÂP³¢½OU®æ’mèß´¨§raäÓw@„&7ìVÛÌyå\çøiÃH47+ù׉L
-µQu-W€»×4~Q.£ÎÐ)ÅÈLHQ-Û(èÖü¥> ø|kúÜ„X`Ž×¾®º] #.ëwx+«;.ñml3ÁѪ۰çµs
-:Ê(׸B®Ó'=êû’ýeÅ9,†`óÙ‡{ß%€ª ¢0<ý}õ¬YâÁ}‹
-ˆ¬BÙp:©Ñx”Mî§?ó}¢Ø×4¹„“ùïüGßßaWGÄð«à
-«1,u6AS£áx\|czíR¢€oÀbÐ.P³¦‹Ý=Öö+<µU ZäÍ&zÐÑÅReu–
-[5ÖðÆê_ka‘¢Þ÷£ø‘*q¥=¡R4Ð/@™jÂHµ0M’$Ùþz„
-˜É¦p8çˆC¡·š•òÏq0ÞSGD¼ÆSâT2J¹Ôi­¸É½°½äA iÎáDµ9)î“>oâÚàЂ,®DOͺ؀¢À¨&¯¬±ßŸ“ãùí„í½O Ä[¢:&ßQC—Ýåy˜1ŸÜ¨^Nò`ϯȌ)†¬!îÍÓ¤~»,˜7Õ$á/°Ûº¤zé5"™4¾bø–ˆÛM]üè»o~E®5p‰ñðJÌs¨{•moœäÜ%Ö¡A;›<Ñíô¦óñÜý¦¦@=®Ð@ZR¸ôGv Ö}¬ÇàƒO³þ›§—ÙA´|:÷©‡ž™Ï @pmðïÑçñ€R Àw<—a°Ý½7#øSBG8-(v> Û žq<]ùÞÚÖÁPdöÙò @JÞâõ•WÑ2|¥ —Ê„s’¨Ê‘i% Ìî3² °6“NP&0ž>>ÀI2åOø®¾Ój¬ŠÛ¯)ÒÀŠÜÚJ8¯Öß*fzU;.ÏZÜ$Úùd
-×D½í¤»a £ªâ*¶‰ÂÀÜÙš*û(Œõ¤qÁÃåäÌ°[¨.xÔŒHhý {§ú·–æýy澡:ÔuÓçg¦¨÷œ4k ÜÀ=ñïElD+Ž9Ó{û¤Î=£n„ÉÐE:xª»n½†í·ô
-é4NÈŠóv É.Õƒ_Þn$`¬ÓÖ)<ËEŠþê°õç@‘q6I„òÝäŽO¦ù¬R²Ôg-£d–‚îAúô>l¿ 3)VÐñ,ÿ²8Änd2€ø»Ì@צÍ*€]ÉãhsÀž”nä¦(ºÎõ§ÕŸW‘ÉÒî#ÐósD–&ôؤžm<[ã Xp.7ôâ(5%ö‘ì>B8‘'ÇÏÉÄ-ŽM%f+ùo0à8}¤{+Ãþ/®ò ¡‹pp… ‚óìô½ÙW¬ÒCF8fÎÞßòä6ŽÓ‘æBVÎÒP,-{DÞBЪðß“úé,¢îN`:¹ ¾ÔŒ/™t>¯‘¾ÀýÝ«9Ñ>á…‡]`5TæÑ’zûvyWX2FüºþbfO–f§>}al÷¨\ÔMê—´ìù¥ìâVPÇsp¥²oøâÇШ›x¨³N O_Ž»N=𣳧ND˜ÿ«ýzZ¯@(5Ic{Çv³cÛ¶mÛ¶m۶ƶm»Ñ™w8wóÍz€ÿ~eŸYçÞ*D+_—‚#ioÛçT¢{?Ø Ï|Xž!ÃS)Ëb×ß[ñ_ˆ
-ï%,3”1•äœJñÙwG¯üûñšøoeüªyDhéNÁÁϹݎÓRþ ~¯›GßB‚\ÌŽ™;؆r•R-ŸEGT±ùø°ãѶ÷Žz ‡¤/z”Þ‰…3 ¿µf!KÜt[¢áqQ‰(¤Õþˆg§þ¬EÒudV;~_€dr‡çI;17 a £ƒžq”„)b±¿²‡s(…0
-IfLt´&
-¸Õ‰]ª¼ÖÀ·ü´¨ˆúWÓž•N€ÓáÚ îËè ¥·I­Ñ—Øü:k b-F”ÛÈØyŒÔLúcÙY># S·ÿý¢žæãþx5
-ŽsU ? ë{x[òq=4£øŠÉTññbEK'òmç±v§9ˆçì‘È$“CXcþ©\“±>ÊG˜m@>¥¼lX1 ©ô¸dwO AþŠEÒÖ’±Sc¸I/cK+–5>¶V‘+"zg
-*»åMì•¡p_ÐV—+}¤ªÞTžY!æĹ(K§i"üÇ(*wOzŒF®¯’«X`Ž¡ÿ­Š¢É
-™*r[¶Â—n³î+ˆm•€Î êËÜun2qÄi"P6h£.ü·T”•OdÉ_ùüånµ~ ‡q#$i5’2ÍçšuÛOÖL[˱ÙE¶IkQñßå:¢_é²w«®º!É·Õ7ˬÞýóÌlÒλª> ^ØH•€ þfuĶgŽÍÆm4N}Ò
-žº²Üà9UwgÒBkÙãƒËÚž½Gr˜u)Ôë
-èòÔAé›ðöÖ_ß5Xuïwo%~’KG`4÷B9MXÄ—›Ý*¬â=cÉwú¦¶­r±¼§˜½ïÙ ÌèÀXmgsÌ{ná>³.ëÀS±¾ü¾ºÈÙ”¦ŠQ®Ÿ6È4ȤÍzÚ9Ú—¦Å÷K\ ìkCì«›!ê;àú¸èy¢Å
-
-"¿‘©ÜŒ˜%(–PL•„àà}çô—ìd¸A4HVs_™c‚Ò„µÜÅ‘nÜŠ¡Vz*-‰To­”â 7*úï #{y‚íl¤â:n\Æ>‡áos.ø¨ŠsýE×õ©É¡Ã<äm¶ E±¸@ˆx²îkrŸËÁ}G=1ôƒNl.&·´Mf‰2À4îۯ0ö€6Ñð G¥í¤B§R“Bt•¯º%õĪÜ~ç$`XÞ(ÿ¶ˆphíÒ[, ²·wÄ.„ˆØeæÒ$HÃù”±åá<€;]vÛàr Öù›–ÞpuU“J¯ÐœA£½<ÚÓ¤ïõV1r¿Â¥“e8Õè7Þ)h(²¼Eð¥GðЖ„ñ˜WÒMæ _Y£õ‡æÒËfcØŠ¡ÌõCÒ0—£Û²u—§§äùp3¦~ùÌ[yÔ5!Áy˜Ý Ð-¹9¨ÉŠ%Q-} /DšC¦—jn¦%>HLgùh:âî…¶Bldš½üuô݈°½‹IÖ#o½¿ùði9žìtå‰ò2¯̉ê³æÖ®Ê2VÂ^­.îÔ
-ëÿ8±²
-òo·Ä‰è8²{ãqÍED§G×æë±ÆöåÜbùÜß°”\&Ü‘ù­òÏ2qsÈÆ°Ûy¾>bò´ÌOX(oÁYÓ‹Þ"4Ù†w7 «~Lé'ƒ]‰v }Oä8ÝMª)Ž–X’EÀ,3bQ*ÞWAš 0 N5<_8%)FľJVßr”[‰=Wÿ:¯&,o/ÑQƒ+"%N†êémü‡*VtŸ_-’È°”´sPàkX‹'ÙÊ‘FâbMüzyixûŸGG1SÝ(&¦F›Å8'Ç
-mÁR!/¤ïmYz'Úò”¦ÀÀh'¨1I ÌѨõéI¹;b ’@\Öq×Ü[¤µ*ýôF£½™ÃØ»ÚRqõ¶›0ý×nD%ŒãßÉ€¦ ]:bĨvÿŽ“U®ïqî{Ĥ
-Èù#†ð÷†(£ÃÐw¾áR¼­ñ¿ø; h@À‘Ä8~©Lp©™¦¿RÒtª3ª5/0Ò¡S0±nÍ&9=Ó ÷-Áz;¢IrH©3©Òpdl²l[‹}B¿p“šÌN2ùòw Д˜…¥UhpO· 
-FÖ—bowÖç'<{†Ëe/>w¤ìºO Óyf4,%[n‹¦ó<ÑȲ’Dø¯7XQ`õì¹;ðkgýÑt{D¯VC|n$è_
-5±)Ä;À†íkPAs~6wD¦l¹Y²˜'À&>)Ž:•„ΊÙtAʘxñI…Å©Ñ’"Vï·´—Á}“Ôl—Üœ2Ê?«RÙª¦» Ñ2ø¡†LŠ¶Ð*¥ÕùÏ•Õz¢W¯íPO!Zñšâ:¡••3ìv{´3:9¨;8 ~†»Gcã–XÇ*ؾƔrõFÉ×<ͤŸ”WSs¤ù€ûñúóRXÙlN|PLò4ŠÒñ£l8¯´Àøî[ë†4 Àñɽ.zšcF­{ý†ÄT¢¸ˆŽ¾‘Ð[™()ä ‡¦f¾ÆF£ðÝ´Z"gº…´>Ôæ5âµlÏâ,¥÷y”¦Ä“1Êe]#¾{Gš!ÓK±¾„OÍ÷¢ü¤ïï!Œ^{ßðÉ‘F'U0BBo÷LÉ7„ob¨AÏqØ5ƒ£&ÜçîYd5K­ÜeíO%:Ó 6™zD-߹̫\šM0
-¯'l­Õ_‡2›.vèKâÔ€fïø¯âˆÚ\ŸÙÊ¡òËà.¶¸iAìU„‹Åss*’ñªÛ
-ó Ë.ºÞJy'k<¬¾T¨u®rï p¦±2Äéyš˜¾Á0^øÓí ›H v,¥wó!éùž1ÄVûr#Âp_JI´¿4ŽÎ¸6ú˘ì{2{ã• <[—)¾Íj°xÔo~y‘S¿mäó¼—¯ùh§NWp¡Q2¬ð‚‰>÷ËgCX ÀõVUé³½æ·ÝbM†Ðñù6 kh*†4¬† ·ÚTã’#­Ò<÷òwHÜ2ÈAœS¼WR¬v"«¡™Ô1í2•¢¨¡;ŽÞuE@L ±Âà‘Œ”ª^4þÕŒl«áÇü̺-€¾¨“\Z™Òçtä %p´§”î–©ÚËjKûr¦ä¦¥Æ¢[~ÕÇÆ
-eÁ½õiÐGÓ8¿ÙñCÊI´‚¥º]u¯˜Ôjù -JtáBÊk(WI)Í’ˆÇ ¨kFîÈJi…Õ FS„Éãâ…—¹l;£—¬(¯cgHÖ5§ýUj®¦›¤ÞNX*1a"˜…J[å?x¯5Mï@ 7‰íɳ't"Mrmc §Õnœ€rÍÖÔ<.ïo°öÝヲk¶åÎM¾×ÅŸ“p40¶Y¤ÉçŠÀ^s ëµ¬d>Rõ~YîZ_Ä둹v0§Gm‡‡N®3çï7G$*›½th•ëùý¹¡Òg)ˆ, &ƒM€¶ïÎ3«yÔ&o¹Ù›ïu–ž4«ô,öZÎOkÜ÷ªÔD%«†Déz¡v?ò‡/óÀ; Š'?§îºËcšý‹Üè
-µ(à\èaª
-E‰7jŨi¥oòƒŒ:½úþ·cêSJo*>»u+Æ#@Ä«áb\[k!s&D “‹Ãd`È<HØò†T¦EÚdò:±CíkE
-j!H·îà3ÁE.
- ø!{mž/ƒòZú+p%Œ«u–}Fcí¿ èýˆ/ì…Ƶ1>§ÌM)ÔÐ O%Sýù8½î×Ç
-dˆür4îŠ$#œ™/à·Ñw $–+3¸]Ì„5¼T87Å]ý—‰Ø¥–…ZPŽü¢ X¥Ì[šÿ8™XpÉþCi€ó`KpmMƒ*­y¨À&ÕÇ*é\—l¹ïˆü° xr#L?)¨ù¹kvü¯â|V{þ–aÀB$ÇÉÎàj`ñh›Îëæîõ­QUdj5Ë$k>7¦|©™¬âÃöõÚ¾¤,ˆÇSÎbÎ=¯ 6¢ŽIÛž‚2üúð?÷ò)CÎ|æ¡î0)ukt ùþîo#‘Æ$÷s‡³Wgª~„ŸÙñôÀԥ;ºaâlèQÌãæƒhË›ƒÌð`
-Z®§Ñœ8Îeä¾ÏFþ±Ã,ô\5ˆI.èÑaM 4Ž´mÇÕ‹èqWM‘±•î·egcØøí «\[þT
-¿Á…æËU¨—xÙLDÞsäÓš
-Iö×~pºóE¦f}^!˜tQ°Ù’‹ƒEäì>‰ n|'ÆV²5D9_äå‹7â̬FJvõ˜2È­ÛŒ’ý;Û£K¿>Z&ú‰Àš¤þØɉ,-¯,Yت–=–ÏÞáÆX8?¸#…m èÓð¥žçßèðž–u¤<5åÑwÒ6¨´ÍÔ™­×#0±q“²Qý‰±ÀåÙëã=¥—;1Â&<
-| f Ég¬,=‘¥vp‘·xMŒé‰_b¬5
-µœóû¿ µ§öÈ4¿À#è¸?§ß7LíXʳŒ”ñkÌ€Zî»vSLR‡û 4 ƒ?&4 =cwÓ™7mÿ­8 ‡L¡ž~šËmé0Rƒù]N9ÄO:;e0vÈ(©6‘÷ôŒ÷ÃæÓ=ÔèÖ‡7œŠ?­)Í'á ž àÇ38ƬpYBà³Â|ƾC¬D?ÖD‡§-QÊ(6ò˜¤>Œö)€*#£˜òDUdùªé³ÓvU
-[`÷QìÿY¨OÖØJæÒ2‹„a¤.‡yMÙB.½T›.¡
-¥í’bWWž^¿§M?¼ªßªéë;ëš<™áh ±Kñŵž¢¨ÚÆóV1îcÖOÏ "ž³x4tÅ:l¼t@i×uÅ«»‡‹Á0“öë]RϺM'Ü>Á™?#ÉABlž=fÌì…ïé ÚiózõÔ¨¿!…+°2Ô’Ýzôµ¥Îb—B
-y‘üP'càÜ^M#R°·ñÃ4 {LJ B«œ»×ën¾HïŸMc–9|þ*S5ïV®ñKãÁ“üvÚJ¦‰‡’à°áR‹ÁPKw©ä;ÉͳðåH-ºOÖ²ÉâØÉ*Wü—¼éýšö•p…+èó®a7AÔºº;˜âR·~4ÿÕ|S®‘mƒ®W•~ ©Ãâ‡}DL×WF5J‰åéØ|¨i÷>#\2®˜
-šÒ30D”€`Ÿ†§¾ç4}&1xÒ¤Ö¥ ÎdP•Ý‹$ȾCO‡Ù’jÛvëö?`C&W'aÔCJ•I'sŠFðìM˼k©¡¨»°+X ŠcAÐÀ«á¥£ùr!<s%!ÈbˆÀNÑ* d3³Ê6†Ø0´+3ïÍNYÀ8îj•ÛP³7Þ¨VäÎc=$0€Ž9€òõ «£…WCÒ¸1å Ô²9L±ž±~óŸ –äWÚyüInÐäöÀ'¼I3 ú]`+ò7vÃÝ!’ÔËö—k«Zœ–(&4¨j„¸`é+àpôxÿÅë«SüWâ$åM7ƒ[IZÒýš®ê~‚VƒÍ:Ø\é«…Œ€Øy_à£öý
-.ÈëÃ6‹û¯™ÅSßcŽ¾Q&É5 fd
-ön’“,6"”@K;\ÿŸÁüø¯
+/Length 25789
+/Filter /FlateDecode
+>>
+stream
+xÚ¬zcteß³mlÛN:¶“ŽmÛö‰mÛN:¶mÛ¶ŽÙq^ÿþWoÜ÷>½w?ì1öªª5kVÍZkœ3Æ&'VP¦4™Šìœé˜è¹‰T•Ô ml M,2tB
+Ѫ&ðëöÜ(ÞÃÇ‘œåRMyû©i¯MH>c¸¤bq›‹bgÜë㤸>· +Zµ‹¥{ü‹q=v¾ ­™«O¼—«Ñ)X!íÁ/$ä±)$§ÁØ^‘w?í¦‘ù]€§“X.2)§©Êer[¤ .©»¹™ ;þÄýI‰ŽBà A¦¸¯»àÐaÁôÞ®|û³ 5ï8sêÓ†
+"ŸÍëã-ö .TÞ;”Ïè*Yp§«© ‹ÕÀKÀk" !œÑE¾[OžKA3æTv7‰.ѧü™"Ç S"V™bIÆ@Ζӧ
+
+áê¡טÞO¿UæÝ¥šÑ<ÑmËs]T­+¤O˜¶1¸¶ðææ#¶V0BøkÅø‹‡ÙÔ•º]Ö²$ò}‹ZZ–$ëe1¯¥P¬É}éîjÀ(RŽ›¡ÛDZù4 P™ bw×4ªeÜêI™A ¿RñŒ24§iÒƒo•æ7…j,;Ù:Œq«úÑNèHåÊÓBuNí|ÚÌ
+6q!#z~`i# VEô yA ã
+5?Ä…J‰¡?‘–x°Š:p´xî@ŸË*£WƒõNQŠÃómƒË@bÙ‚ÄÛ6=_ïc¨Å¨üÐIûVs/D–)h=[¿°J›ÔðV]èB¨öK6J‰ôÍî=®µ5ðç"YAr1äc¶Ð ô¢.é1ÄéÀy²†_Õ-ÿ)¥º*™ïH €Ò°@¿¿ßå|Ç1SsüîóFXF¢ÙB¤þŽ0¶m粿R‚žPï[#@U4K£»åí8c¨tÜÙÇUmÌ ƒz‘HÌkËKÙœ¨ÈÏC—ÝœÏÈcí¤šö‹›ê
+Ú 1ËÔå
+Éqž— êhËÏFÇ=êO”ù+Š<cÁ·.üIƒF&Tfj%v}Hæ®»º/Þ‹:€…tq>ÆSþRL|žíl}„¨IVâMˆ³¹¬|övW£UEqݲ–^`)d_„¯×aå0áï'
+µãJc 0Οó•wê(á·ŸK£êÅ¥Ç<ÌDø¨n {AVÈSb˜1’Qêg aW¾ ¿á¨À+:Q˜šš“ñ‡m¼º…·mÔ îy©¤»\pºAŸœ,)üE»Ï Êüœ‰Nó í—éEgB†Ý·ÚdŸu5C
+<…:0µo$V éÅŽi•Ú¤ËöÑÇÑ.f ó³X©f‡¹5JQ·&– %CDÌ\jö˜B‘u/‚§~;kµ$&yU]ôʉۿæIÎE¤Š”[šÜ¤ŒèGœç³>JýjˆÌUÔ‚*
+ e«1‹ïmÍ°–7p¤+’qy+EßÄ[·ü5ñŸòÀ^îF „}fá•Iû~c”sÄŸ[&ž¼‚Ÿ?/žaÑvãEÎY\T{‚ëv<ŠtcûpÚ¥AgÒg ]`ÃʉJÛv§ltê- \5©1&딠丯¡¨Mٰ݈?T™ðï.™mëßýߘVý4ÄK/Ññ“ê4„ T²(óìï@
+ŠuüìKœã!¥}=—à|ÖÀ¬B®ÈJH‰^M(B ¼µÂN8`æXG_æó"XÙ´èr6á`MÞ5f¨tÓ:JëiLÙÓ{ôx
+קµ÷YÏÛP–™­Î›ä‡¸-f: ƒrõñò;57ì>\ǵ¶ ®Ã¼}8&;DPí…eªî¢W¼'­
+aèqÁr1t˜9f»+ (*‘³-ÃòèRö£½gè–ß~n)véâlOŠeøÝܨë?PÃ-L¿Ol‚€qäµê=¬ŸR©Ì…×9°­zGB¸w{&=GHÑa*ù£8uÊBâŸèÎ6ZÔöŠ¸ÇÑ>Õ‡žC«ß]ü®A‹—Ú!2|XIœµr®5è (’v¿+ãïùF\4“®=åpß¹ÛÓt8RÎÀàx“š›„ÇÕL9[ôiÎ.¶¦ð Ri£´c=S‚<›1ÍÆv¢§6õÈ™\Þ²©Ôÿª
+Æi2ÐÓB¥·åÒ îÕ±Þ:D!€ÊW"²À˜òÞÅ¡èüxÈ÷|¡á3 2y÷n/D #PÖ2’©Èk­.؇Hd†£Lv{ÛñöûüŠ½lµt@ïH­¨­”;áBÑ2«C¬aCõIð#_”½ª†'î,ÏG¯ û)—DÆ*~Ì2ÐüQDyô¡ºôå &ßBêf†³Ê²è˜:³ tu ñ»þ9rK*8]©„·]ÆîCŽÜiŽJÆf§Ô 0ëRi× ð¦h a&¤·—ϲSz… õhßÝ0ÎÔH—Ì-zÑmžÛû S úQóÕFòב,<yt†¤ç“jˆLU\WóaSà¤hµR$@IÔ³®kð†®ËÅœéçºq+¹¤å`”
+þƒÁUÂæWˆÌ#Ü\Ò€h®&ŸÉ5é=úPȆ›Q4¢ÁÎJG¤Þ^¿Ò½
+…Œµ@w‡þKLàí÷‰ŠÆŸ
+çÈz%ÿjv꡼½ŸY/fyŸ&ž<tj«öÒlò?ÖŸÑqÕMêÕA•Ž—ÅïƼQa¸á; d:…­Ö`‡-^uI&¯,ªÆ‘ÜÏÆ¢VÚ57Ç´Ú¬3W'¿/ ÊŒ£Œ¤Ðyû°n~œ?xÿ棄ïr6ßÛS+#ÆB£Ï=¯Ui ƒ¢‰w5ô,·
+Cà—qžàî´Ô›‘õÔÛ÷5ÇPÍrÃ#Ä^ÄïŒå—“¢¡“ôâm‡{£ÊÛìF^¿¬¥V
+ÖY¢ï㸂çõ(‚Ê7º¦šßaYY®ƒµ‘î¯
+Z[Ä…‘ÇÌ® g{S”v
+…€˜!0"ªó:¤¢¯“‘
+£{t¯TÁ>žµÁ½¢¯.šIw™Rçè²óm+5؆+2¢¶¤Qûg ©!“Q¨¿E&·„•º"²Zhu‚è (4¡JRE†âþ [,›·äbU8ì`Hj¬F(Á2"Lã<û}蔸ÙÌívØ_ƒ8Z¢Ý|„Àh›œ_á³bŽ¾–F Èe/í‚œ6¿ì~á0€l è'oÖßN‹¾'tKà©H øêÇQud8ÖVX“'K \¸ÈÍ€‘•Û¬d Ô‹ßÜhû¹ÏýýWÅάJT¨dÝ'›h° ÙÞ @Ò«û3pw+Ä÷–ÆŒÅÎés—øj¢:\ƒ;mBÔí—¦‡Î®÷É€’N#ÒÀØóÍìÍ~êe¶!oEγqi{ÎÍ ÙDoM¬ÏÇEðMFðêã_Ïã8°©ý«¯Jw-!<À~e•\B+SÝP3èŒ"ð= 5}Ö;QÍõË^ŠïÊ¿[qªsâ#Ï·ÈXs© Å!µüôÕdx´@Æ×<8[õ^ìMÌVhx²ýç@÷Ô»¤‘ÏÙõCYÝ–«<PµÈØ…„ùå=°Üœ±üÞ¤Bk‡‘ ŸôÓ:
+Ž3^ïîtl7éEÐR^™UY5.ÔÉ<ÙŒ?tLúdN¬OÔÖ
+Ô>Ä*â-æ6Ò}É›@CÌ=ÒžæPÛÏÓUmeX†0>¥Š;qA0hºxôÌ%šæ¡îËÀ÷·]³c^þå˜[¶Iî4÷,_#5é¡ñ;X“g+É1¨ê#=µmuþm^G˲K‹c¦éÆ3 =U_²Ÿ}{óÉɶ=éÜ~Ã*Ly¾•µ1hÌâÇ„'Šƒ{ŸôHrHOðŸûû“7„æ ¿Z6ÐL4Ó÷€»Qª4™Ö®ÍåY»s¿¥¤Ò'w²¸q;F¸5ûfå9$X†/ñ‘2—¹nl¡-'jU¦wíû E¿•¡¥\H[‰Úû¦ËÞSŒâ¼ @¹8>Üp¼îf©óXŠ+6§Ú ¡¥0”j9Ímp\`Y¥¢«§
+–0@JèÝõ5@9>ÐmçæsS£pð\OÏJðôEXŠ±É¬Uâ”Û͆B¨Ç—ùYʦ˜nà^`nn$ÛLÆ®¬ÂÇýã?µòÔ5™ŒQË™Jƒ­×C‰½Ñ=´³q™»môûrlîÆ"HµÕÿý·”TÑ Ð)§^nL¾”¦–ãiõ@¨­Î~†+ÆÂÆkinuyÄMò.-ÛŃ«×åÝ,>áa•¬
+…>èc‹ÿµï"¨ÈIÓè ÛÝÔÆ./>À"¸x»øÙ^ªç-RR¨¥ñR-Åå\-‡´¤DoÞå±($ú&—øôV°â½âî”Ä`(f þQ̤Ön•W†&mr¦ òäéŠ7K¢ðUVž¼)(E3ô9€…Ûn’ª“mÎU@âÒS²ëÔÇ@×gÜÞÒ—Ppþ
+¶¨f»Ü–õ|Ï bžcÞ2¡„<¡N„_“‚ÂÕÉÜ~ `$@ÇдvW›çBº¼6&»SÊv¥Ü “¬[S‰×òñÞõT9Žþ¼K”)‚Zû)¸pÛjCŽÚN+ï'hssµ½6ýIa…äS4XäHA
+^”Ô~Ïœ(Xt
+zÿÖc:›#é¦,‹  l¾1M¼ï™áŒ ¶èIÊ¡5Díœ ]ÍT%f'Á”^…+>l$& úÃåú[úHõCÿ»_»ßðsÀG¹zÇ%Á¦«ËªIš ÚF=/÷ó~Ãç‘iç*Oéâ¶;¸‘_ºNê½&úÓ©8õÏh­°WäÒýÒ±wÒð3Æ©á¸X‰„»¸ˆRÛz99Ðø|y2+·º¸ôôÅò‹>&cc{¸mÜl|³„ýˆÈ7^€§;{í:`ØÏÓpÏ>ø0#Çù^|V”ñÚÀUéé,±[ý&¸¤h«¸YÊArÇó×J{D†:ðëÒÚ&ˆßæée¼ü×+[ŠÔ;¾ Ç-áTWQßmtÖUüÇ^ÒlÆ‘jpnå) Vi²+b¨¤ïëìl÷ØéØaK´x4èD0ž}Ó$Óï<¯l<>~ÚXvŒ‘¶5ÙüF;¼RåÅ-NSÎÖÏ)P¶’ maKËîf×èËÀÊX4ø®ó·œè—ôÑ–`9dfÍ·µÄÉmbc°k›íŽ¾¶‘nªºtw³­ ¢íÛŠ­²ÞY®%ÈBV¥*(<=Èn®±ˆ¢8w#Ðù÷–ºÒÑ$1wBú,1AjÕÅ#)K¼kòãùmË¥4ÚHkÛM\áfyÉ7ϽfšWp…ŸDÇÛ8ªÝYqRyœ:+äóÞ™? HÔošÃ»ÎJÅi5ÍERP†\¤äbchÚJé
+n‡¤˜o|YÇœ! ¾ÿ|`VÓsÕ'6¾ZÃ:‘ˆ†XµX–Oß•vnwspÙDbE:Þ]Õ–
+ÊлwB…È1ƒþ”¯úäUoà.ó+i‘ =ÈÕýŠN¬m·þÃxí.=Œ­5®óš®H¿><ǤíÅ6‰W¢óÕ³NPùg›ÊXtItàó
+ÂÞeî£Ñ|ïÁþlÒ3ë«a3È2À¦¼‹¢;œWË|ºaƹ’å|ßkõ@Rín-Àø A­©mr#<]b‰åô÷eœõ,ÖœvŠdüeÛ¹0ð0û .};“Íá“Jƒóû$(f ”-b4ÅVÂDk᤼;àSZR«ä*å½ß¯;l@‰8îXïLÁa¥(S}×9ú´‹¼EYaý ‚Æ©+g«¡f›"P>ç =pyEµ$C®,s§™eÛ¤O«¹·lœXì.ÅðÚP¢rnÏlƦi _‰æÕ(ûíÌñùh'³¹Ž‘Q]i-> 8F /'›\„@Hù½Ü{\dß—§S"Ç i8<hÀîÛÇAÉtã´¦÷
+m 3¡¹ø—)zõ%<§
+ÓÛ‰šSNÕ— =·ÞGæQ\iB~Lrb+×ŇbÄÐÙ•+¤Wi2ªhWä.
+oÉ1Ê0웘àÍk.sD•}?*åVMVÇp%:h¦·ˆú]9RG®å3/¥ñÛ@f 3öÁª®‘ÙµÿxTº‡W†×qNë#èô‡F0ôxƒO =­E:5½´è.Ü&>Sï$§ØrY§r–¹qJ
+i8WÚ¿\N[Ž”!öL,Œ'nâu¸våtÌ¢–£a¡ŠãµèÁ%œÀ /*w.ˆxé:”~5K(¬mg}îu1Ý3ï㫽ûõW¤®48P‚JÈÐ_¥3UþìÊtÖ÷Á•C3s-ãYYvÓ‚²Y ±µxÈk½S¢¦U·yÔ5ôÔb\z34V£r ,w‡~ˆå.…CYϾ5„]×Úµ'Ó›øs+qˆ)‚‹v«tüc(“Rlh
+ï|?ÕFð &‡Åi%DáWª®)slŒAè-¾Â¼`]‚þ¥Ÿ¹´¿½Úçp¦ÀÅó)†–z«.µ°½ã+fç.Ye8ÚzF‚ô³îüAÅ´ãñ!GÔ~0Ѻ<|
+#æk›\B23/°|‚ÖN—’ÞÒXtEiÄé(â8]€
+\J®=EÊ~¤¯€k/Pßõ—´”÷æýÖ7öÝ× øòœ†eô毒¨> ¾hÓ;(°äõ²4\–¸©? ePiJ~m×뛇£hb3d¹n½gŠŠ=¬ÓˆlQ,~KBN”†WÅ^"Œ“zÞT‘nNÖ®ÿZƶžßiýb.z<!qr.ÂË<J®p^ÞG5’!ãh¦- UøŠ‡vOòÓI#§¿,žà6ËW±þ$ä‹!ôBeÃyGGl »§ÄMIRö-©¬[­ïª¦Œ@¯}8K¢ÖĘ•àˆ×Gj4×NOÓøÕ¶¯õ‘†Â§íj¾¨Œ(Æ%mÑåÎDÕš9h> þ$®…Î\“©ªm´‚ŠÆ¨Îò&aa.òä^çšàu~{ •q¯2 ]}‘G@åŠä×aÑU®ó:`’PX@h&õx†HˆâóÒf†Bz˨¨_ïI@B&f4Mš¬.aƒ¢KBzê«!ªÿ3NP‰É¥9*š1zÆ\–|wQS…59f¶Øinµ¼IîË
+ýÑ ×òÈ_ûAówVäïjq'!1 mS<œ¶»Í² À­ "áì7zóÇHnØ¿jU‰f~-Õ·SÊvöñÀJqg”`ÇjYÔ˜.N\ø ý>èây\ÖÛ ˜ÎôAЫXÀþPË#-Ęéý†õ¾ð¥20ÄÙß‹„i=óYÃ$¢5Â'5D̸”ijÙªu昬iåOjãa!øêÊL™-ƒ c ÐøD‹ŠÕ««Ç•c#Ù=
+n®±ˆÊž¶ ®áJ<©ö; €îÜ x+ø÷­µ –'IטáŸoŒY™(±¦¬óÓE_3µ#d1š‘jsÅû³Rñüä~
+«…ÛÁ0|ØÛ¨rž[ñÅ
+n£Œˆàwƒm5†‰u“ Ž°‘£óq
+/U¼;Ö}â$X…ÚÓ´Kç«fàÓ*MM‘9Œ}ì‹À@ÄèßSš³« <Gëw²¾×+TR­–òŽÌöQ„ g@Gs ¡ÀÆ£E½4µ­l
+MÞúÅ>Hd‘$ã^ÃÌ[¡û/äX+Ít~ÅßþS$3Ùß—~z]ôúYhí²ä!Ô"'ðÕã:t¸ÛÏÅK`ƒ[‡Çxý4õìÐ!#çˆ/jÎpÊ\£ØiæÍÁÆ‹‚- ^è‚…''¿O òD¹Ê·êÞaw•ïí)0 õP`Q?x9š ü°šhx‰?·Ø c~ûZ6ÒQ@
+keG
+
+Ÿ‚„¨Õ/k‡ ]Ñ º/ÍxÂp¬\>™Lê}û(ù'™y ^d1] ÀGò¤­K\ÙL·(Û×9Ʀ i‹cÝ›õN ™¹n,:m$øçhÚV‡.¬
+ÈÙ!z»[úœD¸¡\™V\aü<I'bÜšÄÎgw—ì£;ÞüÒÙ ¤#~™6HùYS’‡•å蓳6Ò9f|Ðl}çšß‚¥/d¥Þ…vXËpd&—H~T §ÅÔ—s¬:×÷öÚèžnžŠÕ¥á¢ý\ñóÖr4íô+³»¥XÐvel›¢žŠEJ&vÚw·ðÌ:˜6WG'K9¯ j—‚l¦xÃ逖LÖ^Žqþƒ='\ŽAï é/*‹`~&Ë}UïV…ÆMlƒÙ÷‰x^³CI“=_k<S_óØÝîDÍæªê.úõ ®3[ù;ìÛ. $šÓžæSá2ZЯ
+ß¼'ýPb€XÑFM¿ÊœJ» '“ˆ¸Î„J‡ÄÜg*Ÿµ¤õµ§C*•ñ
+¦Çƒç†«4 yãöæšã§>Κüè¯>šbºØýúÅP¬
+ælî tV¸û‘–3qû%ŽY7‰‰p’u1$q…ˆÑÙÈ  ƒŠÙǾ¼\‹uûK¡&˺hûD'n"Q¢&¯iÊ7Í¡ú»šØiµ ÿҨ퉇Ka¯Ñðò(`hò쪆G6XðMÈ ²ß±à;ñÖ¶{õ°”H$3isCÁ†`Ã#: ^üëäçÔ{T\žCÙì¥öD.íðbU'çMPä Î“&.A0(œ”ûéò ût?…7Ÿ4;î¹ÁîRâUÀ0cQ¨œi)‚\ò_\òùÁ±§Ôí"‘Ïn¡¨çW¹@
+4mbA‘., +ù3ÞräÉ7zz¸xº„vFà5Åï÷`>ƒ¿ Ê3¢jÐ1 _òÿMšÎQ1Y©à$SÁÎꨄó‘ð,?/øŒ#q¹,•Mþ@š7Èlf§¯•1NK¨æ×$£`ÈxEŠÕ 6èr%ò1+Éà÷ †Cp³pÜo†WiÎë*$•FxO.†@Mñ¹™å«i;Lg{ã v
+„,˜›"óšœT&iÙÎà±n”:Èt' ¢ª¬õA©AúÚ†ô ˜ìëI¢ÔJÏöG)MûüÅÁù½¬‡f¤Õ<mÊ¡žÄ«|d‚ÉŸr¨Ù/•‰NµÇYû‹Hª¹®|)³Œó^£»¯Ù¤0B¯+Ìxƒôt~乃FÅÖ–þo¹6”¿x‰ï;MܪðXB“ô¬,‡C#)bðùðVÕwЙ"§Êh—UZ‚žÕë}S§ðl¢@vM 9Jà½é¹Tò}(ú¶±©Øb«çsÈIS-(
+G-ƒcD¶–:ß^è†ëÚ8¹g¯y,9b~¦œáV{pî“O'þ’G1¡½à1–ü¾"ÃQíFV©wVŽ¡ÂΕÏa;k²„¼5tÕK®¿ÈÄ´
+&{b¾é\QÊcèâåKŠ¡Û€•\±"Ó{E),ŸŸË#E‘·iUHš™·'6 &<i[ÞÀÑçºËÔg+éA¼Töl¬n´•ÿRÔ—œÄù²4ˆ/åÖƒ ZÓoíضSG‡EŸÃqÉÛ³í±FÁéÛn´!19÷÷. ý¥+õh¨Üíïs´q×0 2|—…ÃtBƧ´ä ¾œJ3›n`m$Ä;Pž=Ì!·þö»$Q¯I cQÞò>u¯_«÷–¤ËÜ‘ÛàÐðÔKÛ?¼ û©)ÑQTóQUm`¦iø<uè¿>:Ñ[—§sø®á›)% ¤ç7 óD¨×K×F´XÖŒAHØú¸a—/« 5:›†Šú™ïn¼#`‡+»Þ[øjXZNiåJx)T»\—ØãÚšæs÷DlIÚb`·:eÛÄôöïT£º)£&ïyd„ãì°3e2ò–/@
+ .Ó0']Ó _Odqâ®Ä–üå…­>#ÞWÖ³cRªv×Sž¼XΧ!8$õËàí 3D=ón“~·ÁŸD㕹=’ô™h¿IÒîÇvƒK>A¨sÎÞtݘÏZ¶G U^W0åõ®’•¤¡Íš’
+/<˜“}ß;ëOжrš³<ˆþ–hMèj‹â×òų@W 4tú:©ë•×`±–T¿/à#]ÛÍN›‰öÍQ«ÕÇØÑ£ƒžoŽzB}ˆŒ¢ÁõSÞ˲ÛA!YÛahZg¼¤u|W¾qþ~âWt`us2yX‚
+¨El* Å3/ZÑÿTãi.)ÑÍ¢G÷8•{ðp œ¾!î4½á´ÞfÍ+ç9'LF¡»^É¿Nd*¹ÆhÇŽ g¥n)ZR¾œ2/@KŒµK¨øXI6ÇRÉ ëaµ$ÅîN»-¢'¼%+iâ?h%Fbs„òj\¥­¡uËøÄ âÂêáÄí(- ¯!Ö0\÷è|žÀ
+¶ ƒ ¢E2Ltãæâè¾I;Æ|ˆ»µ]0ÊÈ!çÛJ¢b^ûÙ­&×à}»'0qT[}yë&P½1ÞAæá^™0qŒk7Ù¥±ßbª0Äüh«N±D3Gˆ¾_²ßý&±UG·b`üÂO|=ÇÎYדnj‡üG tÆδ/Œ±§ÚÖ%t}šøhPÀgz͆ª©d•î2^G¡¥o¯¡Óü‘UC‹)Ö”ÖSˆ*Ñ’È:k@o‹ý})f°+LXnÅ@ê_ ß2Åiâ(ªt…Þ¨¶–+ÈÛk¿(ŸQg䔈Šfl.¬¤þË8èÖâ¥> ø|gúÜ”
+TpŽ‰ß¾®º]+.;+¼•ÝŸô6¶èhÕmØóÚ¹ ˆÿwkÍn‹ØÖæaðÙFu—k\!Ïé“>í}Éþ²ÒS°ÅìC½ïPUÈÉÁ¾Fö,éà¾eö4°Gñeá ºÑ¢Å"w)œçzO§$#g^†¾I†b¡lì4e—8&áâÄ«ðÔc‰þo˜iw¨ ={€õôI=wlº·(n'˜}ü;h|-Pn%Xª²ˆ~~»'›ò!é@Õ]͹à*îªDÝ*õæO͵˜ý¨¡Ò-s‡˜ÐIò3)‘™{¦_ÇWu†ùµ°\°%ßï7iåÜG¥DÞ ñ?’|%ÆüiG—lGê¾L‹`1îDx,½‹ŒÊp—š‚D~e'K™…V,u¤>ŸâìçF» nLFäè”.1°FÖˆ-oË”pÊøcó;6³ùFma7A­CÕW'éÞ¼<«1„6œ&³ƒF5Ì7Òo`¥dº%<‡|W¹[õTú'ÿX'3§ ]…±åvR§ó(›ÜOæÿD³¯ir §ðßù¾¿¡Â¯ŽˆV!"ñ/Ô­‚VcYén‚§ F#ütñé¤DÞ@Ä`] gO»{¬íWxj+.ª¶(XNô`bŠ§Êé.WQT2³Ù‡y©X¦Ž(÷|Α‘Ýv*¤†Õ¤D˜Ï‹ÏâM[E Ó
+ëá0íá3õFt;ÉÁš¼‘Þ<ÅyÕê©–ze¢lÒft£?ÿF%݇¤G[dÊ°ó2¯|?s‡·‚ÁÆ9—¸,k/KÁØÖI_ GÂ+Š$ý v$¡G|7FiÃoÑLØS‰µ¶‰V6bBš×F¬zÓä·Wè߆Û#¢š»°žq"® ¦<I6Ãèýñ4
+Û–åÃ{>;³Ä¬²ÔÙþSXqå§%Œo… Š¥]ôêûæ‰ÁyP;Bi)Omq”©{‡+™ Y=Ëv—0ÒË+AŸ´ë Ó&5Š÷ÓP„R'ë-â+ „ÛƵq›Ý“<–áC“Þ®›8ÔÁhîÏ#íÞ^tG†°QbŲ)N#†·î ?±°ù¦„•›£æˆa$(H쵄…PZsÑ&†®é¶àb’ã°¤Œ0‹§§ï»§óD‡~3:+éØÕä}÷ 8ñ`î©?ßÓo›wºFWÐéO´© 0Èò¹½¶BÄÛp =d²ÿP-âëÅèTÊÏÞg~®ýú=£g­l´þC}—&³¯ÁŒÊ÷ššIîä™é9©±ùÉ•àõ+#ž¢˜£ºþ\Öƒ#ÞkÝŒë&t0ÊÝá¦7Ö¶¡ä”5jÌÔ²ÉwvxÙ–î›à`¬ç÷ì¡"a¡f*í`–zL©b¤5Þ+6=jô{zÌ9ùŠ÷´zû¤dI7ý¢éaùgÌ]rä–ºúhl=M(jtn˜3à ¯L2èféòÞ¹’IPË—~/+$c ª‰Á½ˆã+Z ºù­
+Ï{ªsåšU#ô½V¼oØ6‚ž€‚êƒ37•(S¸nÛ\+5ˆððr~ÉžLO5Ÿ?žUaÂCs`~I®úb®E»IÏZ0<LPÛ~²|gUkìFÒ`×0ÖþÈÙ [Â3䀳ýÜ;ߢšìµèÓxƒÊ 'ÉÇWõ©>¸y‡(.Uôë ´ŸG}µ‚wëN<heÕn']D³C‹u„̯ä?O V†w9àÊHýžt;ƒÀv7vŸT¸[xNø%²OfpIø_$§é5.¾‰ìZÌ
+çßQ-<F_¾Aºtï=Wxi¿'SŸ{Ç4 ¡†[PǦØÊv±­o*SÚ®²2WÿWûæ°À(ÐضÕØnÒÆnl6lc[íL&ÎÄæÄFcÛžØNcÜ»¹Opwÿ÷Ÿ8«³=ÝÃR.ÅE…E‹UöÁÎtZ‹¸»4Àâ)³SdÖÑ´S p@E‹iɳ×aBk®$^‘½ùèVŒ× µæv1’qpVnªra\KJÃ02øÏQ?”KñµyTˆ"\ºg‘K®™Ö„Ê›Tc/¾-ª«1ïkÄó çôç%E ׿ÖÃŒ±Læ‹ØÞ¨€áýf¡g·/7Å¢¼R[õâ7ï™Æz’ø/Nzoàû¬åäckƒÇ›˜Äù˜Võð:)ÿýãµüþéJ
+ 3n
+ÿýûAL”2àC¼IÑ2VÃ$:9Ûö¹o„rcl¼Î]üÉ%ä[&=ë6…ï¾ëiÈ¥øOŒ‚ã$K¿h«•uÕ6Iå/8dÉwMNNX’ÔZ1(Ö¥ô¤`ÑkÙ°Ô‚7U%bŸMWž•:+úa™šíù´Ïè΄Ÿ,^Ç0Š!qù«N6@ñË«µ°¤”¯S©iÝÆ{ÝÇ>_À
+ÿ?!Cçcæ^‘O}ÿƒ5 “Cü!ØÉ»®?í|”+¨4ÂöªlØå½û$†,øá¾/ùt£ËzÒ~ج¡1ш—~DÕ1ˆ%ÀlÑ„A·ïª©þ5c ŽŒ·(ˆèß…®tÞ6ž«¨ý+>ù¤" µÕØ®¦?¤Fn®¤ðÂÀ¯BˆCÍoä ÛV ü¾‘«`$¸+°"¤u¡%f ?ýãŽVãüZékK ²}_î™ééË@©éŸ­z™xzWáQ&gvL®ÎØÕÏƉÈP¨î¬/uâ¤á£ §XdýÿÖ•fB]
+:À€•áŽ±¿X8Ñj‡Œ˜>Ág{ZÐ×Ø°i«‡ºyDj"Å jµK–D¥«œ.¯üç”äàd7X‘7æ<¶’Û*¢†ED6 
+” ]´±1Ü?“¹FÁ&¦¡l—FJÐs²!½‹Dãpù!/dÔˆOÄŽ]{TÖƒ:_IîÖáíŒãH%#ˆ1`@®Ö|Èuåñ¢O¾.$YP'jŸ?¿5×^Ü‚îY%’ >É,MŒ20 HÒV ™H³ÊÎÒ—àýŽ³Ñ]E}Tyƒ¿Õ´9•&ÝÝ
+¾²Sî¹”s¬ ¨Ë¶´óEñźA/Me‘Å
+é >Ÿ¼Ã<»ê
+8‚ã*[KEUè)ùa$¿N¢µ øïÍÇ>:Ç4Ø-,¾Ÿò>Þ¤¹µÀžSƒ…n5É¡è7»~²§bí–L
+•¡–¸CŒ#¶ž©Þ.ίè¿·zÆQè}ÛÌŒ6™Äò"ò¼h÷üõ2ÿ²,›û}‹0~77_J¼­SÕdj 1ø7nÅëH‘óx>/'7ÅWWâ7'Žú yÒ>;Fç:ä{g'àÉ.C»4H%ì²õ8ÃñÒj MæúmÒ“<ïPѤ}RÐQ­}Gý.\Ìûþïã Ú/X…$Ѧ{ЗÝØMÉaúèÜch¨$D
+‹ÁcB
+AàÃÐ> 4.Ðt’ÁýŽ`¡ õ1uĬS‰aÏ çF^V-š>¡ýØN ñ‡0åT¯Ù
+·è‡7ëéBñ(9™ÀcY+k$þŶ«Œ=ðµ¢QwL ä<(ró`,XeG÷¦ÝY–‚®ùÕKé÷ÈÞHC°£ää$=üæ…q
+_Ñ=d´)î`Åœ¬~sÙ:Uµ ´§ÞV¶_K!Ô¦`‘EùcTñYŽdÊæÎx¹ÓÀÏÕ7s,|äºS†ííRN]exÀq”›ý-Ë`ë`‰¨ÖÄc±¸.u¹g9ºBµfœ:îïæ2HV1ÒÎ<lš”¶Øµ±HiœQ‘5ü»ž¹Rª»ôB€î.VÂ˵ävŽí®)üfÄ?æˆ,ÞÄoà¤È Íæ
+ôéeÉþ&‡2"$8¬íÛãO˜ˆ7SÆ,é
+±õñ¨E'Oƒ¦ò¸Žœ­²„Œ¨ISŽ§ìº2!²³’D‡H¶ê;”|‹!¶jè²_rDꀩžÖ¸Øã}ˆ8——T²|+Å׋8¾ûW÷šo
+†?Å, Ô±™x¬ç¥\3*Ï©C¶q0ëß½«™Ž>­jâÄ>Kt¤)¦k>(ªK·#:›xMµ–Ð2²ßñ®ÄýRò¡ì‘wz!î,±•ÁÌõ
+DŒ–¯ØØ®0o´×\Ú²{löjâ­°C¨õ3Lu3¤RLyz§ 1ÛÁÂË6».} À|?ò{,j¢:µæû#-ÝÑ"åHbˆGžaæÀ~À_tݶÛàE•
+ócÆ
+ݲ+‡S?èoJ£K¤
+ÓþL5ºÐ$p•ü›yBÃ|5»w^þl23(ËÛô€åµm‘ï7ì·5v°“’._ô]ÕDO¸XR6ö}ÇÉÉ
+Û7Ñ8úŠßî7;°”—\&›ˆÏæÄeâê.s¤ÆÑŽ…Y0´ÊéÞÀ âžì ‹x4ÜÁw\•fèöê°¼Ÿ3pÇOy³Í4ù”-†¢£À ÂN¿ËþÙP³z[´‹üò®¯˜ Æ®-×I£+”–öH34PçM÷|´wÁ°Qv@2vºŒR¶f¼Ÿ4È,²,BÓœ“Uêä~ó‚ù·•6oáéA+K?ó FC¤h¼ÍRÚ_±L²"çªÒÍ“÷û³ÔBKŒÃ(¼shEŽmä_ÞÙSI f8¢lEúKAfð²ÜeM¥ ÐŽ™Ü*ÝS‰§d#…$3u}!jÌïƨCaô‚”¿•Ú Q,Ü4ŒT=AÅ?AUJ” e –×S<)UÇ‘¡„cc lÛ mvØsÖË(?ú¸D˺¯xì/Pç/·‡ðbÞ
+ËÚ."dšñãí·<ÈAmMãsåýëà½Æ™ûÓKæPú iìЇÖó!œi "
+RY,ÀrÚ° ݧ-¦£<@$•N\×:6EwFàC´Y«Uvvµ×çên¿ò\Vê6â~òT¥•½IýA<_½µ™íb+ö@ö­xž>o´x(°‹àšƒû‹ÿ'õeÓloZK’8´†á'ÔpøºÔfžni(|"¨,ÿ°®u ¨‹êûÔˆ,Фè¾9 {+¸$°w/ž‰’&3RÀ¯„„cÁ šOmÏHµ] Ú!ÝÕJ$Žá
+V‘<}6j]'»EVîhû‚}6¡ÝÀ6àÛ·o÷CfÀ¿ièﬕò1e·)(+‚§l¦…ãƒÖˆç\àíÈìk}/y»—ìǸoÕóÑ#Žuo'i”FG œpÖCfïÌŸ¢7j½W¨évôœ­FaÇ¢~®|Z][pÔÖù(Ž¥å –pÖ– œL®€î2Ÿd#FñD§ðïƳK“UðIó‘½ØÒ^¿ºýO4Jh%9rCØ\\ú+Þüæ8[…}Ú ôu¨›ÔV¤J»ˆ¢<#¡%ÁtÇ2å 7ÙIŸÔ®O™oßpÙêÈ—µ9 §.†*iTáŠNG‚÷Yk(ÅiJÌÇgÖ'gOZU\òo®\9F®hÛŽ²v@›”PN•ªþ|z¥»"^‘—ËN§³$Ë'‡kWØœ.Þe#ÄÚä/ª«:I!îò@F.Ù§N,X!Ϫ%µpºDÖEÐ’6å5eFÙ™ÂôÛ’EöqäœØ+R²Ÿ]C~=ëÿÖxP„»w(ŠÉTn ý£êöÅëGÏ!_/Ä!„ûݸЩîçCs›äJ §±üð@ÔÖfË4á ü%å/«‚ÎüTï;MKð"3¢Îæc7 
+Ú–þb$ˆF›š×4ÌGÂw6 JBÊA©­R"±#ªvw>!*3ûLß´ÖaxqUR±™^3îjÕƪ®vOÍ+ê] N nìþù‡Õ¨¸®âƒÑ±ÕÉíÍU
+`õØ i:ey/ÓT“îüÃg{qª}ŽTr 3ý\:×îY6Ò°’Ù<eÚCÈ_üiš–Qm–›#öïÎTº9\œëyíŽ&$ÞñeÞ I4ðúl#ÿ¿{ 2/ô)™®#0„ÇB_ò l•û©¥×ë¥ê:&T‡í¨9WÚ!’q¨ÿÁTˆÛ¥â«×™a9¦ˆRPÕ½¤Ô_i&U—M“X<ÜôYÈ«¶ª&v@¤àÆ2˜1j 9
+ƒÖù9üÞë%CßšAÛ±·ÁÿxHí´ËúD®Ãn6j­°øc„-± ‘F®mð€äÓz#ìA;L {&a0%­j8ÊÔó£{Gµ¢=4‰¤)Ú[ôÐÓ°ÏOw¥Ç÷MªºA:X¹Í¶Âv4ihìä×s¾ø,‚ÆP’㉖ Õù™\†@¯Á±ÆÎßC —èœFì§M¹"â“Êonn_Ö³ÿLBfFÄ  >;xŒoù3‡ý%¤àö.ÜÍ‘8iòzÍ´ÎÈéÕCùÔîÉ(ŒŒ«ªû-äd˜6í‹(ÇJT*L_4¥öÍü…°í¡M¶¤íâ‹1Ö`×xÜe²lÜá†Ö/®;Gæ+àÆÛÔÜÞ釾{å
+2K(¾àÈrG€éI^ݯ§ËœE;ÉëZ$„)½J%† * ÷%„.Jr–&*¹Ü¯Ms¶°_k„îš ¿NÆS»‚wX*ÿï­fƒ=ºðW=›±7Zx‰’d­#ó’1ãZ˜5'`N @­@Ótq¶¥ÙƉ›–îà—%Š7ûÙ¹%.Ìx¤D—ãðÁ³b‰C5ø Idõk/ÅQŠ?èxãê5³¯ÄÖ>Òðuowõ=–è9­Y'àã« Õ‚zɦ±¶Ô‚>N ;}`÷*Ž¿ÃÞƒ$“ƒ†Ï|£ã·Ä#@ºêÊͪ²Æ.ˆX³¤ ¾àŽG¿¯ö„«‡w‚MšZögsÎÙQ1ª¡ï±ª;_þSì?“áx´ Ÿ‚^¯I«˜E2•“§–κÛw!l¾:‡_¼sªÔNÿ˜~ù™Û݃[²3ùULiµeižÀìe%¥½˜¨üß’O¬/°”:¿èx>D@þ¦ùòá=9'»|»Ä½Œ©L²Ä/–ê-‚½ÎìÃsœ” ~(áà,åpƒ¡ËRs,Õ:Ž±ÿÃ6hÆËÔDÞï^ÑêI¬'k𽠱ĞÙþ÷ŸøŸ…ÜÈ Æ› ;™l+ä­ñy̼Ú(g`ý s}ÔÖ’×åù$Ï–c†ƒvjlHM»kœÄ^ý08ùqS}ã!<¢¥mPYm¼ÑјÃs:öhª6¯!Û(sD¹16äÑ?«r.o™Éûòˆ ¾SšÉí³•õP1K²EreS‘(§AðÖ?žÔo§G,C<òΔ½kuló µkX“ÁñÓ—WOGˆ‹v$ÔÃÁ×a¶D´­ƒæé<xç x÷DÉ ºBõoÙòQ3ª‘GÞŠgMyÎëæ:ç èWƒ’¥oáµ=£öb2ð»±K<6ö%J{
+‹ÅK0}´zc?¹ L£Z^ FªËï;—þ d%CºŸüÂ¥ü¨)0óšâ5µû|#ñÊ1¤Šµ– Pgm _R„®z1ÙïO,îSò[³ÃY[Z…-¶2
+{å]­è«X• ²ßæF]T%9FáTâþ¥}qÚxo‚{w;w+h|ŠÏíaq ˆíX7ŒÒz¡î±vñ¨ˆæK܉bs6Ÿ±™"‚¬|;¯mš®u˜4bƼý¦þ 7õ™•»Ð¯l(hõ)&I—¼¸óÝ ô#Fê%yDôêWÖëÏäôD‡߂ù‘|}Å99Q}â> uôÒ§«h†:úVLãÖzBžÅŒå’F'üÕÆQÓ/9ÎFÝҰɵ#6snœjGöXã~ÃéPóLpJýœ&wB˽óÂób17aªÓHj;è•ßÐðS½]þÅÝpÌÚò“ ­ªAë8Kžpªä¦<ëñ-ùS¢äëÊõ&}9c­àÒo˜òt3aëc` StŒÔDr3œ–ic#Ñ‘x"£ž7ý³–þl­ÊêIF)^ˆ×LÌŠ[h£IµA _#ƒc«¬LÔ'PŒ ö–Tñ™»,Š x´År
+‹;dTx¢CŠÚµ'x^3$|ÀȽ¬4ì^ᜥ$0ý'©´s ác@ÓAÙouÖŒÎ@@‹Ù[¨ñÄ#rµì‘ö9s¤Nè2êš>8*û@‹hËçESæIh’V\ºw+›øYET Žë楋ÆEêæcfCoŠåÚM¬·Ôþáéw„IiD¤^‹J­÷T¹J†a±kãÂú ôꟶÊçÆck€-T ÿŠ×Ý¥èÝû
+¥`M/\oõÛþJXSù6”¿ü'ŽOØLaà¨oÍZNõµáø÷P³¬æ#À«-’·^=èCp§“´ñ»wÓ^»±òž,àìÎ-3à rg‡lÖ:G>
+‡û$Ëú*Ï[¾'е5Ø̽þ^¿‚@rG{XÎN3?Ü&Óvj½ìÖfl3O­ˆÐ¥\á" ÝJ)P\°7À«J&zgT‘š|†ñhÝh^r×X&âhŒç]CŠÒ÷ˆÂú%#ÅŸß’ïçUUÒÙ$ïRDäü¾Rk¤zwŒñ­ã—Z
+UßD„j%‘{7¹’&LoÅLó´T0‰*
+Ë—ÌF+uå| ã_ìŽ'¬gk"¸qáD]²
endobj
-714 0 obj <<
+930 0 obj <<
/Type /Font
/Subtype /Type1
-/Encoding 2140 0 R
+/Encoding 2705 0 R
/FirstChar 2
/LastChar 151
-/Widths 2157 0 R
-/BaseFont /QOWXRN+URWPalladioL-Bold
-/FontDescriptor 712 0 R
+/Widths 2722 0 R
+/BaseFont /NSYDKZ+URWPalladioL-Bold
+/FontDescriptor 928 0 R
>> endobj
-712 0 obj <<
+928 0 obj <<
/Ascent 708
/CapHeight 672
/Descent -266
-/FontName /QOWXRN+URWPalladioL-Bold
+/FontName /NSYDKZ+URWPalladioL-Bold
/ItalicAngle 0
/StemV 123
/XHeight 471
/FontBBox [-152 -301 1000 935]
/Flags 4
-/CharSet (/fi/fl/exclam/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/question/at/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/emdash)
-/FontFile 713 0 R
+/CharSet (/fi/fl/exclam/numbersign/dollar/percent/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/question/at/A/B/C/D/E/F/G/H/I/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/bracketright/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/quotedblright/emdash)
+/FontFile 929 0 R
>> endobj
-2157 0 obj
-[611 611 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 0 500 889 0 278 333 333 444 606 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 250 0 0 0 444 747 778 667 722 833 611 556 833 833 389 0 778 611 1000 833 833 611 833 722 611 667 778 778 1000 667 667 667 333 0 333 0 0 0 500 611 444 611 500 389 556 611 333 333 611 333 889 611 556 611 611 389 444 333 611 556 833 500 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 0 1000 ]
+2722 0 obj
+[611 611 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 278 0 500 500 889 0 278 333 333 444 606 250 333 250 296 500 500 500 500 500 500 500 500 500 500 250 250 0 0 0 444 747 778 667 722 833 611 556 833 833 389 0 778 611 1000 833 833 611 833 722 611 667 778 778 1000 667 667 667 333 0 333 0 0 0 500 611 444 611 500 389 556 611 333 333 611 333 889 611 556 611 611 389 444 333 611 556 833 500 556 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 0 1000 ]
endobj
-715 0 obj <<
+931 0 obj <<
/Type /Pages
/Count 6
-/Parent 2158 0 R
-/Kids [706 0 R 732 0 R 742 0 R 797 0 R 861 0 R 923 0 R]
+/Parent 2723 0 R
+/Kids [922 0 R 948 0 R 958 0 R 1013 0 R 1077 0 R 1140 0 R]
>> endobj
-954 0 obj <<
+1216 0 obj <<
/Type /Pages
/Count 6
-/Parent 2158 0 R
-/Kids [943 0 R 956 0 R 969 0 R 980 0 R 987 0 R 999 0 R]
+/Parent 2723 0 R
+/Kids [1202 0 R 1218 0 R 1230 0 R 1243 0 R 1254 0 R 1261 0 R]
>> endobj
-1011 0 obj <<
+1277 0 obj <<
/Type /Pages
/Count 6
-/Parent 2158 0 R
-/Kids [1004 0 R 1013 0 R 1024 0 R 1032 0 R 1039 0 R 1045 0 R]
+/Parent 2723 0 R
+/Kids [1273 0 R 1279 0 R 1287 0 R 1296 0 R 1306 0 R 1320 0 R]
>> endobj
-1068 0 obj <<
+1328 0 obj <<
/Type /Pages
/Count 6
-/Parent 2158 0 R
-/Kids [1053 0 R 1075 0 R 1085 0 R 1090 0 R 1094 0 R 1101 0 R]
+/Parent 2723 0 R
+/Kids [1324 0 R 1331 0 R 1338 0 R 1343 0 R 1364 0 R 1374 0 R]
>> endobj
-1117 0 obj <<
+1383 0 obj <<
/Type /Pages
/Count 6
-/Parent 2158 0 R
-/Kids [1109 0 R 1120 0 R 1127 0 R 1132 0 R 1142 0 R 1148 0 R]
+/Parent 2723 0 R
+/Kids [1380 0 R 1385 0 R 1390 0 R 1399 0 R 1408 0 R 1415 0 R]
>> endobj
-1158 0 obj <<
+1424 0 obj <<
/Type /Pages
/Count 6
-/Parent 2158 0 R
-/Kids [1152 0 R 1160 0 R 1164 0 R 1174 0 R 1179 0 R 1187 0 R]
+/Parent 2723 0 R
+/Kids [1421 0 R 1426 0 R 1436 0 R 1449 0 R 1457 0 R 1470 0 R]
>> endobj
-1203 0 obj <<
+1480 0 obj <<
/Type /Pages
/Count 6
-/Parent 2159 0 R
-/Kids [1195 0 R 1205 0 R 1214 0 R 1225 0 R 1230 0 R 1236 0 R]
+/Parent 2724 0 R
+/Kids [1476 0 R 1482 0 R 1488 0 R 1496 0 R 1502 0 R 1508 0 R]
>> endobj
-1245 0 obj <<
+1520 0 obj <<
/Type /Pages
/Count 6
-/Parent 2159 0 R
-/Kids [1242 0 R 1247 0 R 1255 0 R 1265 0 R 1269 0 R 1273 0 R]
+/Parent 2724 0 R
+/Kids [1517 0 R 1522 0 R 1529 0 R 1533 0 R 1543 0 R 1548 0 R]
>> endobj
-1282 0 obj <<
+1562 0 obj <<
/Type /Pages
/Count 6
-/Parent 2159 0 R
-/Kids [1278 0 R 1285 0 R 1289 0 R 1295 0 R 1306 0 R 1310 0 R]
+/Parent 2724 0 R
+/Kids [1555 0 R 1564 0 R 1573 0 R 1581 0 R 1592 0 R 1598 0 R]
>> endobj
-1322 0 obj <<
+1609 0 obj <<
/Type /Pages
/Count 6
-/Parent 2159 0 R
-/Kids [1314 0 R 1325 0 R 1332 0 R 1337 0 R 1342 0 R 1346 0 R]
+/Parent 2724 0 R
+/Kids [1604 0 R 1611 0 R 1615 0 R 1622 0 R 1627 0 R 1637 0 R]
>> endobj
-1356 0 obj <<
+1644 0 obj <<
/Type /Pages
/Count 6
-/Parent 2159 0 R
-/Kids [1350 0 R 1358 0 R 1365 0 R 1371 0 R 1378 0 R 1385 0 R]
+/Parent 2724 0 R
+/Kids [1641 0 R 1646 0 R 1650 0 R 1654 0 R 1660 0 R 1665 0 R]
>> endobj
-1398 0 obj <<
+1675 0 obj <<
/Type /Pages
/Count 6
-/Parent 2159 0 R
-/Kids [1391 0 R 1401 0 R 1409 0 R 1413 0 R 1418 0 R 1424 0 R]
+/Parent 2724 0 R
+/Kids [1670 0 R 1677 0 R 1682 0 R 1692 0 R 1696 0 R 1700 0 R]
>> endobj
-1437 0 obj <<
+1712 0 obj <<
/Type /Pages
/Count 6
-/Parent 2160 0 R
-/Kids [1433 0 R 1439 0 R 1443 0 R 1447 0 R 1454 0 R 1459 0 R]
+/Parent 2725 0 R
+/Kids [1705 0 R 1715 0 R 1723 0 R 1728 0 R 1732 0 R 1736 0 R]
>> endobj
-1486 0 obj <<
+1747 0 obj <<
/Type /Pages
/Count 6
-/Parent 2160 0 R
-/Kids [1474 0 R 1488 0 R 1512 0 R 1522 0 R 1528 0 R 1538 0 R]
+/Parent 2725 0 R
+/Kids [1740 0 R 1749 0 R 1756 0 R 1761 0 R 1768 0 R 1776 0 R]
>> endobj
-1552 0 obj <<
+1787 0 obj <<
/Type /Pages
/Count 6
-/Parent 2160 0 R
-/Kids [1544 0 R 1554 0 R 1564 0 R 1574 0 R 1583 0 R 1590 0 R]
+/Parent 2725 0 R
+/Kids [1781 0 R 1791 0 R 1796 0 R 1800 0 R 1806 0 R 1811 0 R]
>> endobj
-1603 0 obj <<
+1820 0 obj <<
/Type /Pages
/Count 6
-/Parent 2160 0 R
-/Kids [1596 0 R 1606 0 R 1616 0 R 1623 0 R 1631 0 R 1637 0 R]
+/Parent 2725 0 R
+/Kids [1816 0 R 1822 0 R 1830 0 R 1837 0 R 1842 0 R 1846 0 R]
>> endobj
-1651 0 obj <<
+1853 0 obj <<
/Type /Pages
/Count 6
-/Parent 2160 0 R
-/Kids [1648 0 R 1653 0 R 1657 0 R 1668 0 R 1672 0 R 1679 0 R]
+/Parent 2725 0 R
+/Kids [1850 0 R 1855 0 R 1863 0 R 1867 0 R 1882 0 R 1896 0 R]
>> endobj
-1747 0 obj <<
+1927 0 obj <<
/Type /Pages
/Count 6
-/Parent 2160 0 R
-/Kids [1689 0 R 1749 0 R 1805 0 R 1859 0 R 1893 0 R 1902 0 R]
+/Parent 2725 0 R
+/Kids [1908 0 R 1929 0 R 1936 0 R 1942 0 R 1952 0 R 1958 0 R]
>> endobj
-1912 0 obj <<
+1973 0 obj <<
/Type /Pages
/Count 6
-/Parent 2161 0 R
-/Kids [1908 0 R 1914 0 R 1918 0 R 1923 0 R 1934 0 R 1939 0 R]
+/Parent 2726 0 R
+/Kids [1964 0 R 1975 0 R 1987 0 R 1995 0 R 2003 0 R 2007 0 R]
>> endobj
-1961 0 obj <<
+2022 0 obj <<
/Type /Pages
/Count 6
-/Parent 2161 0 R
-/Kids [1951 0 R 1963 0 R 1970 0 R 1982 0 R 1986 0 R 1997 0 R]
+/Parent 2726 0 R
+/Kids [2015 0 R 2024 0 R 2036 0 R 2043 0 R 2051 0 R 2055 0 R]
>> endobj
-2006 0 obj <<
+2071 0 obj <<
/Type /Pages
/Count 6
-/Parent 2161 0 R
-/Kids [2003 0 R 2008 0 R 2014 0 R 2027 0 R 2037 0 R 2041 0 R]
+/Parent 2726 0 R
+/Kids [2061 0 R 2073 0 R 2077 0 R 2081 0 R 2092 0 R 2096 0 R]
>> endobj
-2056 0 obj <<
+2112 0 obj <<
/Type /Pages
/Count 6
-/Parent 2161 0 R
-/Kids [2053 0 R 2058 0 R 2064 0 R 2075 0 R 2080 0 R 2084 0 R]
+/Parent 2726 0 R
+/Kids [2103 0 R 2114 0 R 2173 0 R 2229 0 R 2283 0 R 2318 0 R]
>> endobj
-2100 0 obj <<
+2333 0 obj <<
/Type /Pages
/Count 6
-/Parent 2161 0 R
-/Kids [2091 0 R 2102 0 R 2113 0 R 2118 0 R 2129 0 R 2135 0 R]
+/Parent 2726 0 R
+/Kids [2326 0 R 2335 0 R 2342 0 R 2347 0 R 2353 0 R 2357 0 R]
>> endobj
-2158 0 obj <<
+2371 0 obj <<
+/Type /Pages
+/Count 6
+/Parent 2726 0 R
+/Kids [2366 0 R 2373 0 R 2378 0 R 2382 0 R 2387 0 R 2398 0 R]
+>> endobj
+2414 0 obj <<
+/Type /Pages
+/Count 6
+/Parent 2727 0 R
+/Kids [2403 0 R 2416 0 R 2425 0 R 2434 0 R 2439 0 R 2448 0 R]
+>> endobj
+2457 0 obj <<
+/Type /Pages
+/Count 6
+/Parent 2727 0 R
+/Kids [2454 0 R 2459 0 R 2465 0 R 2476 0 R 2486 0 R 2492 0 R]
+>> endobj
+2507 0 obj <<
+/Type /Pages
+/Count 6
+/Parent 2727 0 R
+/Kids [2503 0 R 2509 0 R 2513 0 R 2517 0 R 2528 0 R 2539 0 R]
+>> endobj
+2549 0 obj <<
+/Type /Pages
+/Count 6
+/Parent 2727 0 R
+/Kids [2545 0 R 2551 0 R 2562 0 R 2566 0 R 2573 0 R 2587 0 R]
+>> endobj
+2597 0 obj <<
+/Type /Pages
+/Count 6
+/Parent 2727 0 R
+/Kids [2593 0 R 2599 0 R 2604 0 R 2613 0 R 2621 0 R 2631 0 R]
+>> endobj
+2647 0 obj <<
+/Type /Pages
+/Count 6
+/Parent 2727 0 R
+/Kids [2636 0 R 2649 0 R 2658 0 R 2666 0 R 2681 0 R 2693 0 R]
+>> endobj
+2723 0 obj <<
/Type /Pages
/Count 36
-/Parent 2162 0 R
-/Kids [715 0 R 954 0 R 1011 0 R 1068 0 R 1117 0 R 1158 0 R]
+/Parent 2728 0 R
+/Kids [931 0 R 1216 0 R 1277 0 R 1328 0 R 1383 0 R 1424 0 R]
>> endobj
-2159 0 obj <<
+2724 0 obj <<
/Type /Pages
/Count 36
-/Parent 2162 0 R
-/Kids [1203 0 R 1245 0 R 1282 0 R 1322 0 R 1356 0 R 1398 0 R]
+/Parent 2728 0 R
+/Kids [1480 0 R 1520 0 R 1562 0 R 1609 0 R 1644 0 R 1675 0 R]
>> endobj
-2160 0 obj <<
+2725 0 obj <<
/Type /Pages
/Count 36
-/Parent 2162 0 R
-/Kids [1437 0 R 1486 0 R 1552 0 R 1603 0 R 1651 0 R 1747 0 R]
+/Parent 2728 0 R
+/Kids [1712 0 R 1747 0 R 1787 0 R 1820 0 R 1853 0 R 1927 0 R]
>> endobj
-2161 0 obj <<
+2726 0 obj <<
/Type /Pages
-/Count 30
-/Parent 2162 0 R
-/Kids [1912 0 R 1961 0 R 2006 0 R 2056 0 R 2100 0 R]
+/Count 36
+/Parent 2728 0 R
+/Kids [1973 0 R 2022 0 R 2071 0 R 2112 0 R 2333 0 R 2371 0 R]
>> endobj
-2162 0 obj <<
+2727 0 obj <<
+/Type /Pages
+/Count 36
+/Parent 2728 0 R
+/Kids [2414 0 R 2457 0 R 2507 0 R 2549 0 R 2597 0 R 2647 0 R]
+>> endobj
+2728 0 obj <<
/Type /Pages
-/Count 138
-/Kids [2158 0 R 2159 0 R 2160 0 R 2161 0 R]
+/Count 180
+/Kids [2723 0 R 2724 0 R 2725 0 R 2726 0 R 2727 0 R]
>> endobj
-2163 0 obj <<
+2729 0 obj <<
/Type /Outlines
/First 7 0 R
-/Last 651 0 R
+/Last 835 0 R
/Count 10
>> endobj
+919 0 obj <<
+/Title 920 0 R
+/A 917 0 R
+/Parent 835 0 R
+/Prev 915 0 R
+>> endobj
+915 0 obj <<
+/Title 916 0 R
+/A 913 0 R
+/Parent 835 0 R
+/Prev 911 0 R
+/Next 919 0 R
+>> endobj
+911 0 obj <<
+/Title 912 0 R
+/A 909 0 R
+/Parent 835 0 R
+/Prev 907 0 R
+/Next 915 0 R
+>> endobj
+907 0 obj <<
+/Title 908 0 R
+/A 905 0 R
+/Parent 835 0 R
+/Prev 903 0 R
+/Next 911 0 R
+>> endobj
+903 0 obj <<
+/Title 904 0 R
+/A 901 0 R
+/Parent 835 0 R
+/Prev 899 0 R
+/Next 907 0 R
+>> endobj
+899 0 obj <<
+/Title 900 0 R
+/A 897 0 R
+/Parent 835 0 R
+/Prev 895 0 R
+/Next 903 0 R
+>> endobj
+895 0 obj <<
+/Title 896 0 R
+/A 893 0 R
+/Parent 835 0 R
+/Prev 891 0 R
+/Next 899 0 R
+>> endobj
+891 0 obj <<
+/Title 892 0 R
+/A 889 0 R
+/Parent 835 0 R
+/Prev 887 0 R
+/Next 895 0 R
+>> endobj
+887 0 obj <<
+/Title 888 0 R
+/A 885 0 R
+/Parent 835 0 R
+/Prev 883 0 R
+/Next 891 0 R
+>> endobj
+883 0 obj <<
+/Title 884 0 R
+/A 881 0 R
+/Parent 835 0 R
+/Prev 879 0 R
+/Next 887 0 R
+>> endobj
+879 0 obj <<
+/Title 880 0 R
+/A 877 0 R
+/Parent 835 0 R
+/Prev 875 0 R
+/Next 883 0 R
+>> endobj
+875 0 obj <<
+/Title 876 0 R
+/A 873 0 R
+/Parent 835 0 R
+/Prev 871 0 R
+/Next 879 0 R
+>> endobj
+871 0 obj <<
+/Title 872 0 R
+/A 869 0 R
+/Parent 835 0 R
+/Prev 867 0 R
+/Next 875 0 R
+>> endobj
+867 0 obj <<
+/Title 868 0 R
+/A 865 0 R
+/Parent 835 0 R
+/Prev 863 0 R
+/Next 871 0 R
+>> endobj
+863 0 obj <<
+/Title 864 0 R
+/A 861 0 R
+/Parent 835 0 R
+/Prev 859 0 R
+/Next 867 0 R
+>> endobj
+859 0 obj <<
+/Title 860 0 R
+/A 857 0 R
+/Parent 835 0 R
+/Prev 855 0 R
+/Next 863 0 R
+>> endobj
+855 0 obj <<
+/Title 856 0 R
+/A 853 0 R
+/Parent 835 0 R
+/Prev 851 0 R
+/Next 859 0 R
+>> endobj
+851 0 obj <<
+/Title 852 0 R
+/A 849 0 R
+/Parent 835 0 R
+/Prev 847 0 R
+/Next 855 0 R
+>> endobj
+847 0 obj <<
+/Title 848 0 R
+/A 845 0 R
+/Parent 835 0 R
+/Prev 843 0 R
+/Next 851 0 R
+>> endobj
+843 0 obj <<
+/Title 844 0 R
+/A 841 0 R
+/Parent 835 0 R
+/Prev 839 0 R
+/Next 847 0 R
+>> endobj
+839 0 obj <<
+/Title 840 0 R
+/A 837 0 R
+/Parent 835 0 R
+/Next 843 0 R
+>> endobj
+835 0 obj <<
+/Title 836 0 R
+/A 833 0 R
+/Parent 2729 0 R
+/Prev 743 0 R
+/First 839 0 R
+/Last 919 0 R
+/Count -21
+>> endobj
+831 0 obj <<
+/Title 832 0 R
+/A 829 0 R
+/Parent 779 0 R
+/Prev 803 0 R
+>> endobj
+827 0 obj <<
+/Title 828 0 R
+/A 825 0 R
+/Parent 803 0 R
+/Prev 823 0 R
+>> endobj
+823 0 obj <<
+/Title 824 0 R
+/A 821 0 R
+/Parent 803 0 R
+/Prev 819 0 R
+/Next 827 0 R
+>> endobj
+819 0 obj <<
+/Title 820 0 R
+/A 817 0 R
+/Parent 803 0 R
+/Prev 815 0 R
+/Next 823 0 R
+>> endobj
+815 0 obj <<
+/Title 816 0 R
+/A 813 0 R
+/Parent 803 0 R
+/Prev 811 0 R
+/Next 819 0 R
+>> endobj
+811 0 obj <<
+/Title 812 0 R
+/A 809 0 R
+/Parent 803 0 R
+/Prev 807 0 R
+/Next 815 0 R
+>> endobj
+807 0 obj <<
+/Title 808 0 R
+/A 805 0 R
+/Parent 803 0 R
+/Next 811 0 R
+>> endobj
+803 0 obj <<
+/Title 804 0 R
+/A 801 0 R
+/Parent 779 0 R
+/Prev 799 0 R
+/Next 831 0 R
+/First 807 0 R
+/Last 827 0 R
+/Count -6
+>> endobj
+799 0 obj <<
+/Title 800 0 R
+/A 797 0 R
+/Parent 779 0 R
+/Prev 795 0 R
+/Next 803 0 R
+>> endobj
+795 0 obj <<
+/Title 796 0 R
+/A 793 0 R
+/Parent 779 0 R
+/Prev 791 0 R
+/Next 799 0 R
+>> endobj
+791 0 obj <<
+/Title 792 0 R
+/A 789 0 R
+/Parent 779 0 R
+/Prev 787 0 R
+/Next 795 0 R
+>> endobj
+787 0 obj <<
+/Title 788 0 R
+/A 785 0 R
+/Parent 779 0 R
+/Prev 783 0 R
+/Next 791 0 R
+>> endobj
+783 0 obj <<
+/Title 784 0 R
+/A 781 0 R
+/Parent 779 0 R
+/Next 787 0 R
+>> endobj
+779 0 obj <<
+/Title 780 0 R
+/A 777 0 R
+/Parent 743 0 R
+/Prev 763 0 R
+/First 783 0 R
+/Last 831 0 R
+/Count -7
+>> endobj
+775 0 obj <<
+/Title 776 0 R
+/A 773 0 R
+/Parent 763 0 R
+/Prev 771 0 R
+>> endobj
+771 0 obj <<
+/Title 772 0 R
+/A 769 0 R
+/Parent 763 0 R
+/Prev 767 0 R
+/Next 775 0 R
+>> endobj
+767 0 obj <<
+/Title 768 0 R
+/A 765 0 R
+/Parent 763 0 R
+/Next 771 0 R
+>> endobj
+763 0 obj <<
+/Title 764 0 R
+/A 761 0 R
+/Parent 743 0 R
+/Prev 755 0 R
+/Next 779 0 R
+/First 767 0 R
+/Last 775 0 R
+/Count -3
+>> endobj
+759 0 obj <<
+/Title 760 0 R
+/A 757 0 R
+/Parent 755 0 R
+>> endobj
+755 0 obj <<
+/Title 756 0 R
+/A 753 0 R
+/Parent 743 0 R
+/Prev 747 0 R
+/Next 763 0 R
+/First 759 0 R
+/Last 759 0 R
+/Count -1
+>> endobj
+751 0 obj <<
+/Title 752 0 R
+/A 749 0 R
+/Parent 747 0 R
+>> endobj
+747 0 obj <<
+/Title 748 0 R
+/A 745 0 R
+/Parent 743 0 R
+/Next 755 0 R
+/First 751 0 R
+/Last 751 0 R
+/Count -1
+>> endobj
+743 0 obj <<
+/Title 744 0 R
+/A 741 0 R
+/Parent 2729 0 R
+/Prev 723 0 R
+/Next 835 0 R
+/First 747 0 R
+/Last 779 0 R
+/Count -4
+>> endobj
+739 0 obj <<
+/Title 740 0 R
+/A 737 0 R
+/Parent 723 0 R
+/Prev 735 0 R
+>> endobj
+735 0 obj <<
+/Title 736 0 R
+/A 733 0 R
+/Parent 723 0 R
+/Prev 727 0 R
+/Next 739 0 R
+>> endobj
+731 0 obj <<
+/Title 732 0 R
+/A 729 0 R
+/Parent 727 0 R
+>> endobj
+727 0 obj <<
+/Title 728 0 R
+/A 725 0 R
+/Parent 723 0 R
+/Next 735 0 R
+/First 731 0 R
+/Last 731 0 R
+/Count -1
+>> endobj
+723 0 obj <<
+/Title 724 0 R
+/A 721 0 R
+/Parent 2729 0 R
+/Prev 699 0 R
+/Next 743 0 R
+/First 727 0 R
+/Last 739 0 R
+/Count -3
+>> endobj
+719 0 obj <<
+/Title 720 0 R
+/A 717 0 R
+/Parent 699 0 R
+/Prev 707 0 R
+>> endobj
+715 0 obj <<
+/Title 716 0 R
+/A 713 0 R
+/Parent 707 0 R
+/Prev 711 0 R
+>> endobj
+711 0 obj <<
+/Title 712 0 R
+/A 709 0 R
+/Parent 707 0 R
+/Next 715 0 R
+>> endobj
+707 0 obj <<
+/Title 708 0 R
+/A 705 0 R
+/Parent 699 0 R
+/Prev 703 0 R
+/Next 719 0 R
+/First 711 0 R
+/Last 715 0 R
+/Count -2
+>> endobj
703 0 obj <<
/Title 704 0 R
/A 701 0 R
-/Parent 651 0 R
-/Prev 699 0 R
+/Parent 699 0 R
+/Next 707 0 R
>> endobj
699 0 obj <<
/Title 700 0 R
/A 697 0 R
-/Parent 651 0 R
-/Prev 695 0 R
-/Next 703 0 R
+/Parent 2729 0 R
+/Prev 355 0 R
+/Next 723 0 R
+/First 703 0 R
+/Last 719 0 R
+/Count -3
>> endobj
695 0 obj <<
/Title 696 0 R
/A 693 0 R
-/Parent 651 0 R
+/Parent 675 0 R
/Prev 691 0 R
-/Next 699 0 R
>> endobj
691 0 obj <<
/Title 692 0 R
/A 689 0 R
-/Parent 651 0 R
+/Parent 675 0 R
/Prev 687 0 R
/Next 695 0 R
>> endobj
687 0 obj <<
/Title 688 0 R
/A 685 0 R
-/Parent 651 0 R
+/Parent 675 0 R
/Prev 683 0 R
/Next 691 0 R
>> endobj
683 0 obj <<
/Title 684 0 R
/A 681 0 R
-/Parent 651 0 R
+/Parent 675 0 R
/Prev 679 0 R
/Next 687 0 R
>> endobj
679 0 obj <<
/Title 680 0 R
/A 677 0 R
-/Parent 651 0 R
-/Prev 675 0 R
+/Parent 675 0 R
/Next 683 0 R
>> endobj
675 0 obj <<
/Title 676 0 R
/A 673 0 R
-/Parent 651 0 R
+/Parent 667 0 R
/Prev 671 0 R
-/Next 679 0 R
+/First 679 0 R
+/Last 695 0 R
+/Count -5
>> endobj
671 0 obj <<
/Title 672 0 R
/A 669 0 R
-/Parent 651 0 R
-/Prev 667 0 R
+/Parent 667 0 R
/Next 675 0 R
>> endobj
667 0 obj <<
/Title 668 0 R
/A 665 0 R
-/Parent 651 0 R
-/Prev 663 0 R
-/Next 671 0 R
+/Parent 355 0 R
+/Prev 611 0 R
+/First 671 0 R
+/Last 675 0 R
+/Count -2
>> endobj
663 0 obj <<
/Title 664 0 R
/A 661 0 R
-/Parent 651 0 R
+/Parent 611 0 R
/Prev 659 0 R
-/Next 667 0 R
>> endobj
659 0 obj <<
/Title 660 0 R
/A 657 0 R
-/Parent 651 0 R
-/Prev 655 0 R
+/Parent 611 0 R
+/Prev 639 0 R
/Next 663 0 R
>> endobj
655 0 obj <<
/Title 656 0 R
/A 653 0 R
-/Parent 651 0 R
-/Next 659 0 R
+/Parent 639 0 R
+/Prev 651 0 R
>> endobj
651 0 obj <<
/Title 652 0 R
/A 649 0 R
-/Parent 2163 0 R
-/Prev 615 0 R
-/First 655 0 R
-/Last 703 0 R
-/Count -13
+/Parent 639 0 R
+/Prev 647 0 R
+/Next 655 0 R
>> endobj
647 0 obj <<
/Title 648 0 R
/A 645 0 R
-/Parent 635 0 R
+/Parent 639 0 R
/Prev 643 0 R
+/Next 651 0 R
>> endobj
643 0 obj <<
/Title 644 0 R
/A 641 0 R
-/Parent 635 0 R
-/Prev 639 0 R
+/Parent 639 0 R
/Next 647 0 R
>> endobj
639 0 obj <<
/Title 640 0 R
/A 637 0 R
-/Parent 635 0 R
-/Next 643 0 R
+/Parent 611 0 R
+/Prev 635 0 R
+/Next 659 0 R
+/First 643 0 R
+/Last 655 0 R
+/Count -4
>> endobj
635 0 obj <<
/Title 636 0 R
/A 633 0 R
-/Parent 615 0 R
-/Prev 627 0 R
-/First 639 0 R
-/Last 647 0 R
-/Count -3
+/Parent 611 0 R
+/Prev 631 0 R
+/Next 639 0 R
>> endobj
631 0 obj <<
/Title 632 0 R
/A 629 0 R
-/Parent 627 0 R
+/Parent 611 0 R
+/Prev 627 0 R
+/Next 635 0 R
>> endobj
627 0 obj <<
/Title 628 0 R
/A 625 0 R
-/Parent 615 0 R
-/Prev 619 0 R
-/Next 635 0 R
-/First 631 0 R
-/Last 631 0 R
-/Count -1
+/Parent 611 0 R
+/Prev 615 0 R
+/Next 631 0 R
>> endobj
623 0 obj <<
/Title 624 0 R
/A 621 0 R
-/Parent 619 0 R
+/Parent 615 0 R
+/Prev 619 0 R
>> endobj
619 0 obj <<
/Title 620 0 R
/A 617 0 R
/Parent 615 0 R
-/Next 627 0 R
-/First 623 0 R
-/Last 623 0 R
-/Count -1
+/Next 623 0 R
>> endobj
615 0 obj <<
/Title 616 0 R
/A 613 0 R
-/Parent 2163 0 R
-/Prev 595 0 R
-/Next 651 0 R
+/Parent 611 0 R
+/Next 627 0 R
/First 619 0 R
-/Last 635 0 R
-/Count -3
+/Last 623 0 R
+/Count -2
>> endobj
611 0 obj <<
/Title 612 0 R
/A 609 0 R
-/Parent 595 0 R
-/Prev 607 0 R
+/Parent 355 0 R
+/Prev 387 0 R
+/Next 667 0 R
+/First 615 0 R
+/Last 663 0 R
+/Count -7
>> endobj
607 0 obj <<
/Title 608 0 R
/A 605 0 R
-/Parent 595 0 R
-/Prev 599 0 R
-/Next 611 0 R
+/Parent 591 0 R
+/Prev 603 0 R
>> endobj
603 0 obj <<
/Title 604 0 R
/A 601 0 R
-/Parent 599 0 R
+/Parent 591 0 R
+/Prev 599 0 R
+/Next 607 0 R
>> endobj
599 0 obj <<
/Title 600 0 R
/A 597 0 R
-/Parent 595 0 R
-/Next 607 0 R
-/First 603 0 R
-/Last 603 0 R
-/Count -1
+/Parent 591 0 R
+/Prev 595 0 R
+/Next 603 0 R
>> endobj
595 0 obj <<
/Title 596 0 R
/A 593 0 R
-/Parent 2163 0 R
-/Prev 571 0 R
-/Next 615 0 R
-/First 599 0 R
-/Last 611 0 R
-/Count -3
+/Parent 591 0 R
+/Next 599 0 R
>> endobj
591 0 obj <<
/Title 592 0 R
/A 589 0 R
-/Parent 571 0 R
-/Prev 579 0 R
+/Parent 387 0 R
+/Prev 587 0 R
+/First 595 0 R
+/Last 607 0 R
+/Count -4
>> endobj
587 0 obj <<
/Title 588 0 R
/A 585 0 R
-/Parent 579 0 R
+/Parent 387 0 R
/Prev 583 0 R
+/Next 591 0 R
>> endobj
583 0 obj <<
/Title 584 0 R
/A 581 0 R
-/Parent 579 0 R
+/Parent 387 0 R
+/Prev 579 0 R
/Next 587 0 R
>> endobj
579 0 obj <<
/Title 580 0 R
/A 577 0 R
-/Parent 571 0 R
+/Parent 387 0 R
/Prev 575 0 R
-/Next 591 0 R
-/First 583 0 R
-/Last 587 0 R
-/Count -2
+/Next 583 0 R
>> endobj
575 0 obj <<
/Title 576 0 R
/A 573 0 R
-/Parent 571 0 R
+/Parent 387 0 R
+/Prev 571 0 R
/Next 579 0 R
>> endobj
571 0 obj <<
/Title 572 0 R
/A 569 0 R
-/Parent 2163 0 R
-/Prev 243 0 R
-/Next 595 0 R
-/First 575 0 R
-/Last 591 0 R
-/Count -3
+/Parent 387 0 R
+/Prev 567 0 R
+/Next 575 0 R
>> endobj
567 0 obj <<
/Title 568 0 R
/A 565 0 R
-/Parent 547 0 R
+/Parent 387 0 R
/Prev 563 0 R
+/Next 571 0 R
>> endobj
563 0 obj <<
/Title 564 0 R
/A 561 0 R
-/Parent 547 0 R
+/Parent 387 0 R
/Prev 559 0 R
/Next 567 0 R
>> endobj
559 0 obj <<
/Title 560 0 R
/A 557 0 R
-/Parent 547 0 R
+/Parent 387 0 R
/Prev 555 0 R
/Next 563 0 R
>> endobj
555 0 obj <<
/Title 556 0 R
/A 553 0 R
-/Parent 547 0 R
+/Parent 387 0 R
/Prev 551 0 R
/Next 559 0 R
>> endobj
551 0 obj <<
/Title 552 0 R
/A 549 0 R
-/Parent 547 0 R
+/Parent 387 0 R
+/Prev 547 0 R
/Next 555 0 R
>> endobj
547 0 obj <<
/Title 548 0 R
/A 545 0 R
-/Parent 539 0 R
-/Prev 543 0 R
-/First 551 0 R
-/Last 567 0 R
-/Count -5
+/Parent 387 0 R
+/Prev 463 0 R
+/Next 551 0 R
>> endobj
543 0 obj <<
/Title 544 0 R
/A 541 0 R
-/Parent 539 0 R
-/Next 547 0 R
+/Parent 463 0 R
+/Prev 539 0 R
>> endobj
539 0 obj <<
/Title 540 0 R
/A 537 0 R
-/Parent 243 0 R
-/Prev 483 0 R
-/First 543 0 R
-/Last 547 0 R
-/Count -2
+/Parent 463 0 R
+/Prev 535 0 R
+/Next 543 0 R
>> endobj
535 0 obj <<
/Title 536 0 R
/A 533 0 R
-/Parent 483 0 R
+/Parent 463 0 R
/Prev 531 0 R
+/Next 539 0 R
>> endobj
531 0 obj <<
/Title 532 0 R
/A 529 0 R
-/Parent 483 0 R
-/Prev 511 0 R
+/Parent 463 0 R
+/Prev 527 0 R
/Next 535 0 R
>> endobj
527 0 obj <<
/Title 528 0 R
/A 525 0 R
-/Parent 511 0 R
+/Parent 463 0 R
/Prev 523 0 R
+/Next 531 0 R
>> endobj
523 0 obj <<
/Title 524 0 R
/A 521 0 R
-/Parent 511 0 R
+/Parent 463 0 R
/Prev 519 0 R
/Next 527 0 R
>> endobj
519 0 obj <<
/Title 520 0 R
/A 517 0 R
-/Parent 511 0 R
+/Parent 463 0 R
/Prev 515 0 R
/Next 523 0 R
>> endobj
515 0 obj <<
/Title 516 0 R
/A 513 0 R
-/Parent 511 0 R
+/Parent 463 0 R
+/Prev 511 0 R
/Next 519 0 R
>> endobj
511 0 obj <<
/Title 512 0 R
/A 509 0 R
-/Parent 483 0 R
+/Parent 463 0 R
/Prev 507 0 R
-/Next 531 0 R
-/First 515 0 R
-/Last 527 0 R
-/Count -4
+/Next 515 0 R
>> endobj
507 0 obj <<
/Title 508 0 R
/A 505 0 R
-/Parent 483 0 R
+/Parent 463 0 R
/Prev 503 0 R
/Next 511 0 R
>> endobj
503 0 obj <<
/Title 504 0 R
/A 501 0 R
-/Parent 483 0 R
+/Parent 463 0 R
/Prev 499 0 R
/Next 507 0 R
>> endobj
499 0 obj <<
/Title 500 0 R
/A 497 0 R
-/Parent 483 0 R
-/Prev 487 0 R
+/Parent 463 0 R
+/Prev 495 0 R
/Next 503 0 R
>> endobj
495 0 obj <<
/Title 496 0 R
/A 493 0 R
-/Parent 487 0 R
+/Parent 463 0 R
/Prev 491 0 R
+/Next 499 0 R
>> endobj
491 0 obj <<
/Title 492 0 R
/A 489 0 R
-/Parent 487 0 R
+/Parent 463 0 R
+/Prev 487 0 R
/Next 495 0 R
>> endobj
487 0 obj <<
/Title 488 0 R
/A 485 0 R
-/Parent 483 0 R
-/Next 499 0 R
-/First 491 0 R
-/Last 495 0 R
-/Count -2
+/Parent 463 0 R
+/Prev 483 0 R
+/Next 491 0 R
>> endobj
483 0 obj <<
/Title 484 0 R
/A 481 0 R
-/Parent 243 0 R
-/Prev 275 0 R
-/Next 539 0 R
-/First 487 0 R
-/Last 535 0 R
-/Count -7
+/Parent 463 0 R
+/Prev 479 0 R
+/Next 487 0 R
>> endobj
479 0 obj <<
/Title 480 0 R
/A 477 0 R
/Parent 463 0 R
/Prev 475 0 R
+/Next 483 0 R
>> endobj
475 0 obj <<
/Title 476 0 R
@@ -12324,328 +15378,338 @@ endobj
463 0 obj <<
/Title 464 0 R
/A 461 0 R
-/Parent 275 0 R
+/Parent 387 0 R
/Prev 459 0 R
+/Next 547 0 R
/First 467 0 R
-/Last 479 0 R
-/Count -4
+/Last 543 0 R
+/Count -20
>> endobj
459 0 obj <<
/Title 460 0 R
/A 457 0 R
-/Parent 275 0 R
+/Parent 387 0 R
/Prev 455 0 R
/Next 463 0 R
>> endobj
455 0 obj <<
/Title 456 0 R
/A 453 0 R
-/Parent 275 0 R
+/Parent 387 0 R
/Prev 451 0 R
/Next 459 0 R
>> endobj
451 0 obj <<
/Title 452 0 R
/A 449 0 R
-/Parent 275 0 R
+/Parent 387 0 R
/Prev 447 0 R
/Next 455 0 R
>> endobj
447 0 obj <<
/Title 448 0 R
/A 445 0 R
-/Parent 275 0 R
+/Parent 387 0 R
/Prev 443 0 R
/Next 451 0 R
>> endobj
443 0 obj <<
/Title 444 0 R
/A 441 0 R
-/Parent 275 0 R
-/Prev 439 0 R
+/Parent 387 0 R
+/Prev 427 0 R
/Next 447 0 R
>> endobj
439 0 obj <<
/Title 440 0 R
/A 437 0 R
-/Parent 275 0 R
+/Parent 427 0 R
/Prev 435 0 R
-/Next 443 0 R
>> endobj
435 0 obj <<
/Title 436 0 R
/A 433 0 R
-/Parent 275 0 R
+/Parent 427 0 R
/Prev 431 0 R
/Next 439 0 R
>> endobj
431 0 obj <<
/Title 432 0 R
/A 429 0 R
-/Parent 275 0 R
-/Prev 427 0 R
+/Parent 427 0 R
/Next 435 0 R
>> endobj
427 0 obj <<
/Title 428 0 R
/A 425 0 R
-/Parent 275 0 R
-/Prev 351 0 R
-/Next 431 0 R
+/Parent 387 0 R
+/Prev 423 0 R
+/Next 443 0 R
+/First 431 0 R
+/Last 439 0 R
+/Count -3
>> endobj
423 0 obj <<
/Title 424 0 R
/A 421 0 R
-/Parent 351 0 R
+/Parent 387 0 R
/Prev 419 0 R
+/Next 427 0 R
>> endobj
419 0 obj <<
/Title 420 0 R
/A 417 0 R
-/Parent 351 0 R
+/Parent 387 0 R
/Prev 415 0 R
/Next 423 0 R
>> endobj
415 0 obj <<
/Title 416 0 R
/A 413 0 R
-/Parent 351 0 R
+/Parent 387 0 R
/Prev 411 0 R
/Next 419 0 R
>> endobj
411 0 obj <<
/Title 412 0 R
/A 409 0 R
-/Parent 351 0 R
+/Parent 387 0 R
/Prev 407 0 R
/Next 415 0 R
>> endobj
407 0 obj <<
/Title 408 0 R
/A 405 0 R
-/Parent 351 0 R
+/Parent 387 0 R
/Prev 403 0 R
/Next 411 0 R
>> endobj
403 0 obj <<
/Title 404 0 R
/A 401 0 R
-/Parent 351 0 R
+/Parent 387 0 R
/Prev 399 0 R
/Next 407 0 R
>> endobj
399 0 obj <<
/Title 400 0 R
/A 397 0 R
-/Parent 351 0 R
+/Parent 387 0 R
/Prev 395 0 R
/Next 403 0 R
>> endobj
395 0 obj <<
/Title 396 0 R
/A 393 0 R
-/Parent 351 0 R
+/Parent 387 0 R
/Prev 391 0 R
/Next 399 0 R
>> endobj
391 0 obj <<
/Title 392 0 R
/A 389 0 R
-/Parent 351 0 R
-/Prev 387 0 R
+/Parent 387 0 R
/Next 395 0 R
>> endobj
387 0 obj <<
/Title 388 0 R
/A 385 0 R
-/Parent 351 0 R
-/Prev 383 0 R
-/Next 391 0 R
+/Parent 355 0 R
+/Prev 359 0 R
+/Next 611 0 R
+/First 391 0 R
+/Last 591 0 R
+/Count -28
>> endobj
383 0 obj <<
/Title 384 0 R
/A 381 0 R
-/Parent 351 0 R
+/Parent 375 0 R
/Prev 379 0 R
-/Next 387 0 R
>> endobj
379 0 obj <<
/Title 380 0 R
/A 377 0 R
-/Parent 351 0 R
-/Prev 375 0 R
+/Parent 375 0 R
/Next 383 0 R
>> endobj
375 0 obj <<
/Title 376 0 R
/A 373 0 R
-/Parent 351 0 R
-/Prev 371 0 R
-/Next 379 0 R
+/Parent 359 0 R
+/Prev 363 0 R
+/First 379 0 R
+/Last 383 0 R
+/Count -2
>> endobj
371 0 obj <<
/Title 372 0 R
/A 369 0 R
-/Parent 351 0 R
+/Parent 363 0 R
/Prev 367 0 R
-/Next 375 0 R
>> endobj
367 0 obj <<
/Title 368 0 R
/A 365 0 R
-/Parent 351 0 R
-/Prev 363 0 R
+/Parent 363 0 R
/Next 371 0 R
>> endobj
363 0 obj <<
/Title 364 0 R
/A 361 0 R
-/Parent 351 0 R
-/Prev 359 0 R
-/Next 367 0 R
+/Parent 359 0 R
+/Next 375 0 R
+/First 367 0 R
+/Last 371 0 R
+/Count -2
>> endobj
359 0 obj <<
/Title 360 0 R
/A 357 0 R
-/Parent 351 0 R
-/Prev 355 0 R
-/Next 363 0 R
+/Parent 355 0 R
+/Next 387 0 R
+/First 363 0 R
+/Last 375 0 R
+/Count -2
>> endobj
355 0 obj <<
/Title 356 0 R
/A 353 0 R
-/Parent 351 0 R
-/Next 359 0 R
+/Parent 2729 0 R
+/Prev 343 0 R
+/Next 699 0 R
+/First 359 0 R
+/Last 667 0 R
+/Count -4
>> endobj
351 0 obj <<
/Title 352 0 R
/A 349 0 R
-/Parent 275 0 R
+/Parent 343 0 R
/Prev 347 0 R
-/Next 427 0 R
-/First 355 0 R
-/Last 423 0 R
-/Count -18
>> endobj
347 0 obj <<
/Title 348 0 R
/A 345 0 R
-/Parent 275 0 R
-/Prev 343 0 R
+/Parent 343 0 R
/Next 351 0 R
>> endobj
343 0 obj <<
/Title 344 0 R
/A 341 0 R
-/Parent 275 0 R
-/Prev 339 0 R
-/Next 347 0 R
+/Parent 2729 0 R
+/Prev 131 0 R
+/Next 355 0 R
+/First 347 0 R
+/Last 351 0 R
+/Count -2
>> endobj
339 0 obj <<
/Title 340 0 R
/A 337 0 R
-/Parent 275 0 R
+/Parent 331 0 R
/Prev 335 0 R
-/Next 343 0 R
>> endobj
335 0 obj <<
/Title 336 0 R
/A 333 0 R
-/Parent 275 0 R
-/Prev 331 0 R
+/Parent 331 0 R
/Next 339 0 R
>> endobj
331 0 obj <<
/Title 332 0 R
/A 329 0 R
-/Parent 275 0 R
-/Prev 315 0 R
-/Next 335 0 R
+/Parent 131 0 R
+/Prev 287 0 R
+/First 335 0 R
+/Last 339 0 R
+/Count -2
>> endobj
327 0 obj <<
/Title 328 0 R
/A 325 0 R
-/Parent 315 0 R
+/Parent 287 0 R
/Prev 323 0 R
>> endobj
323 0 obj <<
/Title 324 0 R
/A 321 0 R
-/Parent 315 0 R
+/Parent 287 0 R
/Prev 319 0 R
/Next 327 0 R
>> endobj
319 0 obj <<
/Title 320 0 R
/A 317 0 R
-/Parent 315 0 R
+/Parent 287 0 R
+/Prev 315 0 R
/Next 323 0 R
>> endobj
315 0 obj <<
/Title 316 0 R
/A 313 0 R
-/Parent 275 0 R
-/Prev 311 0 R
-/Next 331 0 R
-/First 319 0 R
-/Last 327 0 R
-/Count -3
+/Parent 287 0 R
+/Prev 303 0 R
+/Next 319 0 R
>> endobj
311 0 obj <<
/Title 312 0 R
/A 309 0 R
-/Parent 275 0 R
+/Parent 303 0 R
/Prev 307 0 R
-/Next 315 0 R
>> endobj
307 0 obj <<
/Title 308 0 R
/A 305 0 R
-/Parent 275 0 R
-/Prev 303 0 R
+/Parent 303 0 R
/Next 311 0 R
>> endobj
303 0 obj <<
/Title 304 0 R
/A 301 0 R
-/Parent 275 0 R
-/Prev 299 0 R
-/Next 307 0 R
+/Parent 287 0 R
+/Prev 291 0 R
+/Next 315 0 R
+/First 307 0 R
+/Last 311 0 R
+/Count -2
>> endobj
299 0 obj <<
/Title 300 0 R
/A 297 0 R
-/Parent 275 0 R
+/Parent 291 0 R
/Prev 295 0 R
-/Next 303 0 R
>> endobj
295 0 obj <<
/Title 296 0 R
/A 293 0 R
-/Parent 275 0 R
-/Prev 291 0 R
+/Parent 291 0 R
/Next 299 0 R
>> endobj
291 0 obj <<
/Title 292 0 R
/A 289 0 R
-/Parent 275 0 R
-/Prev 287 0 R
-/Next 295 0 R
+/Parent 287 0 R
+/Next 303 0 R
+/First 295 0 R
+/Last 299 0 R
+/Count -2
>> endobj
287 0 obj <<
/Title 288 0 R
/A 285 0 R
-/Parent 275 0 R
-/Prev 283 0 R
-/Next 291 0 R
+/Parent 131 0 R
+/Prev 275 0 R
+/Next 331 0 R
+/First 291 0 R
+/Last 327 0 R
+/Count -6
>> endobj
283 0 obj <<
/Title 284 0 R
/A 281 0 R
/Parent 275 0 R
/Prev 279 0 R
-/Next 287 0 R
>> endobj
279 0 obj <<
/Title 280 0 R
@@ -12656,101 +15720,95 @@ endobj
275 0 obj <<
/Title 276 0 R
/A 273 0 R
-/Parent 243 0 R
-/Prev 247 0 R
-/Next 483 0 R
+/Parent 131 0 R
+/Prev 219 0 R
+/Next 287 0 R
/First 279 0 R
-/Last 463 0 R
-/Count -26
+/Last 283 0 R
+/Count -2
>> endobj
271 0 obj <<
/Title 272 0 R
/A 269 0 R
-/Parent 263 0 R
+/Parent 219 0 R
/Prev 267 0 R
>> endobj
267 0 obj <<
/Title 268 0 R
/A 265 0 R
-/Parent 263 0 R
+/Parent 219 0 R
+/Prev 263 0 R
/Next 271 0 R
>> endobj
263 0 obj <<
/Title 264 0 R
/A 261 0 R
-/Parent 247 0 R
-/Prev 251 0 R
-/First 267 0 R
-/Last 271 0 R
-/Count -2
+/Parent 219 0 R
+/Prev 259 0 R
+/Next 267 0 R
>> endobj
259 0 obj <<
/Title 260 0 R
/A 257 0 R
-/Parent 251 0 R
+/Parent 219 0 R
/Prev 255 0 R
+/Next 263 0 R
>> endobj
255 0 obj <<
/Title 256 0 R
/A 253 0 R
-/Parent 251 0 R
+/Parent 219 0 R
+/Prev 251 0 R
/Next 259 0 R
>> endobj
251 0 obj <<
/Title 252 0 R
/A 249 0 R
-/Parent 247 0 R
-/Next 263 0 R
-/First 255 0 R
-/Last 259 0 R
-/Count -2
+/Parent 219 0 R
+/Prev 247 0 R
+/Next 255 0 R
>> endobj
247 0 obj <<
/Title 248 0 R
/A 245 0 R
-/Parent 243 0 R
-/Next 275 0 R
-/First 251 0 R
-/Last 263 0 R
-/Count -2
+/Parent 219 0 R
+/Prev 243 0 R
+/Next 251 0 R
>> endobj
243 0 obj <<
/Title 244 0 R
/A 241 0 R
-/Parent 2163 0 R
-/Prev 231 0 R
-/Next 571 0 R
-/First 247 0 R
-/Last 539 0 R
-/Count -4
+/Parent 219 0 R
+/Prev 239 0 R
+/Next 247 0 R
>> endobj
239 0 obj <<
/Title 240 0 R
/A 237 0 R
-/Parent 231 0 R
+/Parent 219 0 R
/Prev 235 0 R
+/Next 243 0 R
>> endobj
235 0 obj <<
/Title 236 0 R
/A 233 0 R
-/Parent 231 0 R
+/Parent 219 0 R
+/Prev 231 0 R
/Next 239 0 R
>> endobj
231 0 obj <<
/Title 232 0 R
/A 229 0 R
-/Parent 2163 0 R
-/Prev 131 0 R
-/Next 243 0 R
-/First 235 0 R
-/Last 239 0 R
-/Count -2
+/Parent 219 0 R
+/Prev 227 0 R
+/Next 235 0 R
>> endobj
227 0 obj <<
/Title 228 0 R
/A 225 0 R
/Parent 219 0 R
/Prev 223 0 R
+/Next 231 0 R
>> endobj
223 0 obj <<
/Title 224 0 R
@@ -12763,9 +15821,10 @@ endobj
/A 217 0 R
/Parent 131 0 R
/Prev 203 0 R
+/Next 275 0 R
/First 223 0 R
-/Last 227 0 R
-/Count -2
+/Last 271 0 R
+/Count -13
>> endobj
215 0 obj <<
/Title 216 0 R
@@ -12921,12 +15980,12 @@ endobj
131 0 obj <<
/Title 132 0 R
/A 129 0 R
-/Parent 2163 0 R
+/Parent 2729 0 R
/Prev 91 0 R
-/Next 231 0 R
+/Next 343 0 R
/First 135 0 R
-/Last 219 0 R
-/Count -9
+/Last 331 0 R
+/Count -12
>> endobj
127 0 obj <<
/Title 128 0 R
@@ -12995,7 +16054,7 @@ endobj
91 0 obj <<
/Title 92 0 R
/A 89 0 R
-/Parent 2163 0 R
+/Parent 2729 0 R
/Prev 67 0 R
/Next 131 0 R
/First 95 0 R
@@ -13038,7 +16097,7 @@ endobj
67 0 obj <<
/Title 68 0 R
/A 65 0 R
-/Parent 2163 0 R
+/Parent 2729 0 R
/Prev 7 0 R
/Next 91 0 R
/First 71 0 R
@@ -13147,2213 +16206,2779 @@ endobj
7 0 obj <<
/Title 8 0 R
/A 5 0 R
-/Parent 2163 0 R
+/Parent 2729 0 R
/Next 67 0 R
/First 11 0 R
/Last 23 0 R
/Count -4
>> endobj
-2164 0 obj <<
-/Names [(Access_Control_Lists) 1635 0 R (Bv9ARM.ch01) 945 0 R (Bv9ARM.ch02) 990 0 R (Bv9ARM.ch03) 1007 0 R (Bv9ARM.ch04) 1056 0 R (Bv9ARM.ch05) 1155 0 R (Bv9ARM.ch06) 1167 0 R (Bv9ARM.ch07) 1634 0 R (Bv9ARM.ch08) 1660 0 R (Bv9ARM.ch09) 1675 0 R (Bv9ARM.ch10) 1896 0 R (Configuration_File_Grammar) 1191 0 R (DNSSEC) 1123 0 R (Doc-Start) 711 0 R (Setting_TTLs) 1560 0 R (acache) 997 0 R (access_control) 1320 0 R (acl) 1199 0 R (address_match_lists) 1172 0 R (admin_tools) 1030 0 R (appendix.A) 614 0 R (appendix.B) 650 0 R (bibliography) 1683 0 R (boolean_options) 1072 0 R (builtin) 1404 0 R (chapter*.1) 745 0 R (chapter.1) 6 0 R (chapter.2) 66 0 R (chapter.3) 90 0 R (chapter.4) 130 0 R (chapter.5) 230 0 R (chapter.6) 242 0 R (chapter.7) 570 0 R (chapter.8) 594 0 R (cite.RFC1033) 1811 0 R (cite.RFC1034) 1695 0 R (cite.RFC1035) 1697 0 R (cite.RFC1101) 1793 0 R (cite.RFC1123) 1795 0 R (cite.RFC1183) 1755 0 R (cite.RFC1464) 1833 0 R (cite.RFC1535) 1740 0 R (cite.RFC1536) 1742 0 R (cite.RFC1537) 1813 0 R (cite.RFC1591) 1797 0 R (cite.RFC1706) 1757 0 R (cite.RFC1712) 1853 0 R (cite.RFC1713) 1835 0 R (cite.RFC1794) 1837 0 R (cite.RFC1876) 1759 0 R (cite.RFC1912) 1815 0 R (cite.RFC1982) 1744 0 R (cite.RFC1995) 1702 0 R (cite.RFC1996) 1704 0 R (cite.RFC2010) 1817 0 R (cite.RFC2052) 1761 0 R (cite.RFC2065) 1865 0 R (cite.RFC2136) 1706 0 R (cite.RFC2137) 1867 0 R (cite.RFC2163) 1763 0 R (cite.RFC2168) 1765 0 R (cite.RFC2181) 1708 0 R (cite.RFC2219) 1819 0 R (cite.RFC2230) 1767 0 R (cite.RFC2240) 1839 0 R (cite.RFC2308) 1710 0 R (cite.RFC2317) 1799 0 R (cite.RFC2345) 1841 0 R (cite.RFC2352) 1843 0 R (cite.RFC2535) 1869 0 R (cite.RFC2536) 1769 0 R (cite.RFC2537) 1771 0 R (cite.RFC2538) 1773 0 R (cite.RFC2539) 1775 0 R (cite.RFC2540) 1777 0 R (cite.RFC2671) 1712 0 R (cite.RFC2672) 1714 0 R (cite.RFC2673) 1855 0 R (cite.RFC2782) 1779 0 R (cite.RFC2825) 1823 0 R (cite.RFC2826) 1801 0 R (cite.RFC2845) 1716 0 R (cite.RFC2874) 1857 0 R (cite.RFC2915) 1781 0 R (cite.RFC2929) 1803 0 R (cite.RFC2930) 1718 0 R (cite.RFC2931) 1720 0 R (cite.RFC3007) 1722 0 R (cite.RFC3008) 1871 0 R (cite.RFC3071) 1845 0 R (cite.RFC3090) 1873 0 R (cite.RFC3110) 1783 0 R (cite.RFC3123) 1785 0 R (cite.RFC3225) 1728 0 R (cite.RFC3258) 1847 0 R (cite.RFC3445) 1875 0 R (cite.RFC3490) 1825 0 R (cite.RFC3491) 1827 0 R (cite.RFC3492) 1829 0 R (cite.RFC3596) 1787 0 R (cite.RFC3597) 1789 0 R (cite.RFC3645) 1724 0 R (cite.RFC3655) 1877 0 R (cite.RFC3658) 1879 0 R (cite.RFC3755) 1881 0 R (cite.RFC3757) 1883 0 R (cite.RFC3833) 1730 0 R (cite.RFC3845) 1885 0 R (cite.RFC3901) 1849 0 R (cite.RFC4033) 1732 0 R (cite.RFC4034) 1734 0 R (cite.RFC4035) 1736 0 R (cite.RFC4074) 1746 0 R (cite.RFC974) 1699 0 R (cite.id2506284) 1890 0 R (clients-per-query) 1604 0 R (configuration_file_elements) 1168 0 R (controls_statement_definition_and_usage) 1043 0 R (diagnostic_tools) 978 0 R (dynamic_update) 1066 0 R (dynamic_update_policies) 1118 0 R (dynamic_update_security) 1330 0 R (empty) 1406 0 R (historical_dns_information) 1677 0 R (id2466560) 946 0 R (id2466583) 947 0 R (id2467290) 1081 0 R (id2467308) 1082 0 R (id2467474) 948 0 R (id2467483) 949 0 R (id2467723) 960 0 R (id2467745) 961 0 R (id2467779) 962 0 R (id2467863) 965 0 R (id2467956) 958 0 R (id2470261) 972 0 R (id2470284) 975 0 R (id2470382) 976 0 R (id2470404) 977 0 R (id2470502) 983 0 R (id2470537) 984 0 R (id2470564) 985 0 R (id2470598) 991 0 R (id2470625) 992 0 R (id2470637) 993 0 R (id2470731) 996 0 R (id2470742) 1002 0 R (id2470774) 1009 0 R (id2470790) 1010 0 R (id2470812) 1016 0 R (id2470829) 1017 0 R (id2471235) 1020 0 R (id2471240) 1021 0 R (id2473016) 1048 0 R (id2473028) 1049 0 R (id2473683) 1098 0 R (id2473700) 1099 0 R (id2474421) 1104 0 R (id2474439) 1105 0 R (id2474450) 1106 0 R (id2474554) 1107 0 R (id2474680) 1112 0 R (id2474728) 1114 0 R (id2474742) 1115 0 R (id2474791) 1116 0 R (id2474859) 1124 0 R (id2475006) 1125 0 R (id2475156) 1130 0 R (id2475394) 1138 0 R (id2475524) 1145 0 R (id2475545) 1146 0 R (id2475578) 1156 0 R (id2475862) 1169 0 R (id2476724) 1177 0 R (id2476752) 1182 0 R (id2476957) 1183 0 R (id2476972) 1184 0 R (id2477070) 1190 0 R (id2477213) 1192 0 R (id2477656) 1198 0 R (id2477699) 1200 0 R (id2477846) 1202 0 R (id2478275) 1210 0 R (id2478292) 1211 0 R (id2478315) 1217 0 R (id2478339) 1218 0 R (id2478498) 1222 0 R (id2478624) 1223 0 R (id2478676) 1228 0 R (id2479437) 1239 0 R (id2480103) 1250 0 R (id2480163) 1251 0 R (id2480548) 1253 0 R (id2480621) 1258 0 R (id2480685) 1261 0 R (id2480729) 1262 0 R (id2480744) 1263 0 R (id2483230) 1292 0 R (id2485002) 1317 0 R (id2485061) 1319 0 R (id2485635) 1335 0 R (id2486906) 1353 0 R (id2486966) 1355 0 R (id2487320) 1368 0 R (id2487822) 1382 0 R (id2489986) 1428 0 R (id2490140) 1429 0 R (id2490192) 1430 0 R (id2490410) 1436 0 R (id2491952) 1450 0 R (id2491959) 1451 0 R (id2491964) 1452 0 R (id2492318) 1463 0 R (id2492352) 1464 0 R (id2494048) 1519 0 R (id2494430) 1525 0 R (id2494449) 1526 0 R (id2494537) 1533 0 R (id2494706) 1535 0 R (id2495944) 1541 0 R (id2496072) 1547 0 R (id2496093) 1548 0 R (id2496388) 1550 0 R (id2496524) 1557 0 R (id2496542) 1558 0 R (id2497015) 1561 0 R (id2497140) 1567 0 R (id2497155) 1568 0 R (id2497267) 1570 0 R (id2497289) 1571 0 R (id2497305) 1572 0 R (id2497434) 1577 0 R (id2497504) 1578 0 R (id2497676) 1579 0 R (id2497738) 1580 0 R (id2498169) 1587 0 R (id2498604) 1599 0 R (id2498610) 1600 0 R (id2500077) 1609 0 R (id2500084) 1610 0 R (id2500529) 1612 0 R (id2500534) 1613 0 R (id2501479) 1619 0 R (id2501648) 1620 0 R (id2501989) 1629 0 R (id2502163) 1644 0 R (id2502312) 1645 0 R (id2502440) 1646 0 R (id2502588) 1661 0 R (id2502594) 1662 0 R (id2502605) 1663 0 R (id2502622) 1664 0 R (id2502753) 1676 0 R (id2502993) 1682 0 R (id2503180) 1687 0 R (id2503182) 1693 0 R (id2503191) 1698 0 R (id2503214) 1694 0 R (id2503238) 1696 0 R (id2503274) 1707 0 R (id2503301) 1709 0 R (id2503326) 1701 0 R (id2503351) 1703 0 R (id2503374) 1705 0 R (id2503430) 1711 0 R (id2503457) 1713 0 R (id2503483) 1715 0 R (id2503545) 1717 0 R (id2503575) 1719 0 R (id2503605) 1721 0 R (id2503632) 1723 0 R (id2503706) 1726 0 R (id2503714) 1727 0 R (id2503740) 1729 0 R (id2503845) 1731 0 R (id2503910) 1733 0 R (id2503975) 1735 0 R (id2504040) 1738 0 R (id2504049) 1739 0 R (id2504074) 1741 0 R (id2504142) 1743 0 R (id2504178) 1745 0 R (id2504218) 1753 0 R (id2504224) 1754 0 R (id2504281) 1756 0 R (id2504318) 1764 0 R (id2504354) 1758 0 R (id2504408) 1760 0 R (id2504446) 1762 0 R (id2504472) 1766 0 R (id2504498) 1768 0 R (id2504524) 1770 0 R (id2504551) 1772 0 R (id2504590) 1774 0 R (id2504620) 1776 0 R (id2504650) 1778 0 R (id2504693) 1780 0 R (id2504726) 1782 0 R (id2504753) 1784 0 R (id2504844) 1786 0 R (id2504902) 1788 0 R (id2504926) 1791 0 R (id2504934) 1792 0 R (id2504960) 1794 0 R (id2504982) 1796 0 R (id2505005) 1798 0 R (id2505051) 1800 0 R (id2505075) 1802 0 R (id2505125) 1809 0 R (id2505132) 1810 0 R (id2505156) 1812 0 R (id2505182) 1814 0 R (id2505209) 1816 0 R (id2505245) 1818 0 R (id2505286) 1821 0 R (id2505291) 1822 0 R (id2505323) 1824 0 R (id2505369) 1826 0 R (id2505404) 1828 0 R (id2505431) 1831 0 R (id2505449) 1832 0 R (id2505472) 1834 0 R (id2505497) 1836 0 R (id2505523) 1838 0 R (id2505546) 1840 0 R (id2505592) 1842 0 R (id2505616) 1844 0 R (id2505642) 1846 0 R (id2505668) 1848 0 R (id2505705) 1851 0 R (id2505712) 1852 0 R (id2505769) 1854 0 R (id2505796) 1856 0 R (id2505832) 1863 0 R (id2505844) 1864 0 R (id2505883) 1866 0 R (id2505910) 1868 0 R (id2505940) 1870 0 R (id2505965) 1872 0 R (id2505992) 1874 0 R (id2506028) 1876 0 R (id2506065) 1878 0 R (id2506091) 1880 0 R (id2506118) 1882 0 R (id2506163) 1884 0 R (id2506204) 1887 0 R (id2506282) 1889 0 R (id2506284) 1891 0 R (incremental_zone_transfers) 1078 0 R (internet_drafts) 1886 0 R (ipv6addresses) 1140 0 R (journal) 1067 0 R (lwresd) 1157 0 R (man.dig) 1897 0 R (man.dnssec-dsfromkey) 1945 0 R (man.dnssec-keyfromlabel) 1959 0 R (man.dnssec-keygen) 1976 0 R (man.dnssec-signzone) 1993 0 R (man.host) 1930 0 R (man.named) 2047 0 R (man.named-checkconf) 2019 0 R (man.named-checkzone) 2031 0 R (man.nsupdate) 2070 0 R (man.rndc) 2095 0 R (man.rndc-confgen) 2124 0 R (man.rndc.conf) 2108 0 R (notify) 1057 0 R (options) 1276 0 R (page.1) 710 0 R (page.10) 1034 0 R (page.100) 1861 0 R (page.101) 1895 0 R (page.102) 1904 0 R (page.103) 1910 0 R (page.104) 1916 0 R (page.105) 1920 0 R (page.106) 1925 0 R (page.107) 1936 0 R (page.108) 1941 0 R (page.109) 1953 0 R (page.11) 1041 0 R (page.110) 1965 0 R (page.111) 1972 0 R (page.112) 1984 0 R (page.113) 1988 0 R (page.114) 1999 0 R (page.115) 2005 0 R (page.116) 2010 0 R (page.117) 2016 0 R (page.118) 2029 0 R (page.119) 2039 0 R (page.12) 1047 0 R (page.120) 2043 0 R (page.121) 2055 0 R (page.122) 2060 0 R (page.123) 2066 0 R (page.124) 2077 0 R (page.125) 2082 0 R (page.126) 2086 0 R (page.127) 2093 0 R (page.128) 2104 0 R (page.129) 2115 0 R (page.13) 1055 0 R (page.130) 2120 0 R (page.131) 2131 0 R (page.132) 2137 0 R (page.14) 1077 0 R (page.15) 1087 0 R (page.16) 1092 0 R (page.17) 1096 0 R (page.18) 1103 0 R (page.19) 1111 0 R (page.2) 734 0 R (page.20) 1122 0 R (page.21) 1129 0 R (page.22) 1134 0 R (page.23) 1144 0 R (page.24) 1150 0 R (page.25) 1154 0 R (page.26) 1162 0 R (page.27) 1166 0 R (page.28) 1176 0 R (page.29) 1181 0 R (page.3) 971 0 R (page.30) 1189 0 R (page.31) 1197 0 R (page.32) 1207 0 R (page.33) 1216 0 R (page.34) 1227 0 R (page.35) 1232 0 R (page.36) 1238 0 R (page.37) 1244 0 R (page.38) 1249 0 R (page.39) 1257 0 R (page.4) 982 0 R (page.40) 1267 0 R (page.41) 1271 0 R (page.42) 1275 0 R (page.43) 1280 0 R (page.44) 1287 0 R (page.45) 1291 0 R (page.46) 1297 0 R (page.47) 1308 0 R (page.48) 1312 0 R (page.49) 1316 0 R (page.5) 989 0 R (page.50) 1327 0 R (page.51) 1334 0 R (page.52) 1339 0 R (page.53) 1344 0 R (page.54) 1348 0 R (page.55) 1352 0 R (page.56) 1360 0 R (page.57) 1367 0 R (page.58) 1373 0 R (page.59) 1380 0 R (page.6) 1001 0 R (page.60) 1387 0 R (page.61) 1393 0 R (page.62) 1403 0 R (page.63) 1411 0 R (page.64) 1415 0 R (page.65) 1420 0 R (page.66) 1426 0 R (page.67) 1435 0 R (page.68) 1441 0 R (page.69) 1445 0 R (page.7) 1006 0 R (page.70) 1449 0 R (page.71) 1456 0 R (page.72) 1461 0 R (page.73) 1476 0 R (page.74) 1490 0 R (page.75) 1514 0 R (page.76) 1524 0 R (page.77) 1530 0 R (page.78) 1540 0 R (page.79) 1546 0 R (page.8) 1015 0 R (page.80) 1556 0 R (page.81) 1566 0 R (page.82) 1576 0 R (page.83) 1585 0 R (page.84) 1592 0 R (page.85) 1598 0 R (page.86) 1608 0 R (page.87) 1618 0 R (page.88) 1625 0 R (page.89) 1633 0 R (page.9) 1026 0 R (page.90) 1639 0 R (page.91) 1650 0 R (page.92) 1655 0 R (page.93) 1659 0 R (page.94) 1670 0 R (page.95) 1674 0 R (page.96) 1681 0 R (page.97) 1691 0 R (page.98) 1751 0 R (page.99) 1807 0 R (page.i) 744 0 R (page.ii) 799 0 R (page.iii) 863 0 R (page.iv) 925 0 R (proposed_standards) 1083 0 R (query_address) 1340 0 R (rfcs) 967 0 R (rndc) 1212 0 R (root_delegation_only) 1472 0 R (rrset_ordering) 1022 0 R (sample_configuration) 1008 0 R (section*.10) 1820 0 R (section*.100) 2106 0 R (section*.101) 2107 0 R (section*.102) 2109 0 R (section*.103) 2110 0 R (section*.104) 2111 0 R (section*.105) 2116 0 R (section*.106) 2121 0 R (section*.107) 2122 0 R (section*.108) 2123 0 R (section*.109) 2125 0 R (section*.11) 1830 0 R (section*.110) 2126 0 R (section*.111) 2127 0 R (section*.112) 2132 0 R (section*.113) 2133 0 R (section*.114) 2138 0 R (section*.115) 2139 0 R (section*.12) 1850 0 R (section*.13) 1862 0 R (section*.14) 1888 0 R (section*.15) 1898 0 R (section*.16) 1899 0 R (section*.17) 1900 0 R (section*.18) 1905 0 R (section*.19) 1906 0 R (section*.2) 1686 0 R (section*.20) 1911 0 R (section*.21) 1921 0 R (section*.22) 1926 0 R (section*.23) 1927 0 R (section*.24) 1928 0 R (section*.25) 1929 0 R (section*.26) 1931 0 R (section*.27) 1932 0 R (section*.28) 1937 0 R (section*.29) 1942 0 R (section*.3) 1692 0 R (section*.30) 1943 0 R (section*.31) 1944 0 R (section*.32) 1946 0 R (section*.33) 1947 0 R (section*.34) 1948 0 R (section*.35) 1949 0 R (section*.36) 1954 0 R (section*.37) 1955 0 R (section*.38) 1956 0 R (section*.39) 1957 0 R (section*.4) 1700 0 R (section*.40) 1958 0 R (section*.41) 1960 0 R (section*.42) 1966 0 R (section*.43) 1967 0 R (section*.44) 1968 0 R (section*.45) 1973 0 R (section*.46) 1974 0 R (section*.47) 1975 0 R (section*.48) 1977 0 R (section*.49) 1978 0 R (section*.5) 1725 0 R (section*.50) 1979 0 R (section*.51) 1980 0 R (section*.52) 1989 0 R (section*.53) 1990 0 R (section*.54) 1991 0 R (section*.55) 1992 0 R (section*.56) 1994 0 R (section*.57) 1995 0 R (section*.58) 2000 0 R (section*.59) 2001 0 R (section*.6) 1737 0 R (section*.60) 2011 0 R (section*.61) 2012 0 R (section*.62) 2017 0 R (section*.63) 2018 0 R (section*.64) 2020 0 R (section*.65) 2021 0 R (section*.66) 2022 0 R (section*.67) 2023 0 R (section*.68) 2024 0 R (section*.69) 2025 0 R (section*.7) 1752 0 R (section*.70) 2030 0 R (section*.71) 2032 0 R (section*.72) 2033 0 R (section*.73) 2034 0 R (section*.74) 2035 0 R (section*.75) 2044 0 R (section*.76) 2045 0 R (section*.77) 2046 0 R (section*.78) 2048 0 R (section*.79) 2049 0 R (section*.8) 1790 0 R (section*.80) 2050 0 R (section*.81) 2051 0 R (section*.82) 2061 0 R (section*.83) 2062 0 R (section*.84) 2067 0 R (section*.85) 2068 0 R (section*.86) 2069 0 R (section*.87) 2071 0 R (section*.88) 2072 0 R (section*.89) 2073 0 R (section*.9) 1808 0 R (section*.90) 2078 0 R (section*.91) 2087 0 R (section*.92) 2088 0 R (section*.93) 2089 0 R (section*.94) 2094 0 R (section*.95) 2096 0 R (section*.96) 2097 0 R (section*.97) 2098 0 R (section*.98) 2099 0 R (section*.99) 2105 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R (section.1.4) 22 0 R (section.2.1) 70 0 R (section.2.2) 74 0 R (section.2.3) 78 0 R (section.2.4) 82 0 R (section.2.5) 86 0 R (section.3.1) 94 0 R (section.3.2) 106 0 R (section.3.3) 110 0 R (section.4.1) 134 0 R (section.4.2) 138 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 158 0 R (section.4.6) 194 0 R (section.4.7) 198 0 R (section.4.8) 202 0 R (section.4.9) 218 0 R (section.5.1) 234 0 R (section.5.2) 238 0 R (section.6.1) 246 0 R (section.6.2) 274 0 R (section.6.3) 482 0 R (section.6.4) 538 0 R (section.7.1) 574 0 R (section.7.2) 578 0 R (section.7.3) 590 0 R (section.8.1) 598 0 R (section.8.2) 606 0 R (section.8.3) 610 0 R (section.A.1) 618 0 R (section.A.2) 626 0 R (section.A.3) 634 0 R (section.B.1) 654 0 R (section.B.10) 690 0 R (section.B.11) 694 0 R (section.B.12) 698 0 R (section.B.13) 702 0 R (section.B.2) 658 0 R (section.B.3) 662 0 R (section.B.4) 666 0 R (section.B.5) 670 0 R (section.B.6) 674 0 R (section.B.7) 678 0 R (section.B.8) 682 0 R (section.B.9) 686 0 R (server_resource_limits) 1362 0 R (server_statement_definition_and_usage) 1304 0 R (server_statement_grammar) 1416 0 R (statistics) 1586 0 R (statistics_counters) 1594 0 R (statschannels) 1427 0 R (statsfile) 1283 0 R (subsection.1.4.1) 26 0 R (subsection.1.4.2) 30 0 R (subsection.1.4.3) 34 0 R (subsection.1.4.4) 38 0 R (subsection.1.4.5) 54 0 R (subsection.1.4.6) 62 0 R (subsection.3.1.1) 98 0 R (subsection.3.1.2) 102 0 R (subsection.3.3.1) 114 0 R (subsection.3.3.2) 126 0 R (subsection.4.2.1) 142 0 R (subsection.4.4.1) 154 0 R (subsection.4.5.1) 162 0 R (subsection.4.5.2) 174 0 R (subsection.4.5.3) 178 0 R (subsection.4.5.4) 182 0 R (subsection.4.5.5) 186 0 R (subsection.4.5.6) 190 0 R (subsection.4.8.1) 206 0 R (subsection.4.8.2) 210 0 R (subsection.4.8.3) 214 0 R (subsection.4.9.1) 222 0 R (subsection.4.9.2) 226 0 R (subsection.6.1.1) 250 0 R (subsection.6.1.2) 262 0 R (subsection.6.2.1) 278 0 R (subsection.6.2.10) 314 0 R (subsection.6.2.11) 330 0 R (subsection.6.2.12) 334 0 R (subsection.6.2.13) 338 0 R (subsection.6.2.14) 342 0 R (subsection.6.2.15) 346 0 R (subsection.6.2.16) 350 0 R (subsection.6.2.17) 426 0 R (subsection.6.2.18) 430 0 R (subsection.6.2.19) 434 0 R (subsection.6.2.2) 282 0 R (subsection.6.2.20) 438 0 R (subsection.6.2.21) 442 0 R (subsection.6.2.22) 446 0 R (subsection.6.2.23) 450 0 R (subsection.6.2.24) 454 0 R (subsection.6.2.25) 458 0 R (subsection.6.2.26) 462 0 R (subsection.6.2.3) 286 0 R (subsection.6.2.4) 290 0 R (subsection.6.2.5) 294 0 R (subsection.6.2.6) 298 0 R (subsection.6.2.7) 302 0 R (subsection.6.2.8) 306 0 R (subsection.6.2.9) 310 0 R (subsection.6.3.1) 486 0 R (subsection.6.3.2) 498 0 R (subsection.6.3.3) 502 0 R (subsection.6.3.4) 506 0 R (subsection.6.3.5) 510 0 R (subsection.6.3.6) 530 0 R (subsection.6.3.7) 534 0 R (subsection.6.4.1) 546 0 R (subsection.7.2.1) 582 0 R (subsection.7.2.2) 586 0 R (subsection.8.1.1) 602 0 R (subsection.A.1.1) 622 0 R (subsection.A.2.1) 630 0 R (subsection.A.3.1) 638 0 R (subsection.A.3.2) 642 0 R (subsection.A.3.3) 646 0 R (subsubsection.1.4.4.1) 42 0 R (subsubsection.1.4.4.2) 46 0 R (subsubsection.1.4.4.3) 50 0 R (subsubsection.1.4.5.1) 58 0 R (subsubsection.3.3.1.1) 118 0 R (subsubsection.3.3.1.2) 122 0 R (subsubsection.4.5.1.1) 166 0 R (subsubsection.4.5.1.2) 170 0 R (subsubsection.6.1.1.1) 254 0 R (subsubsection.6.1.1.2) 258 0 R (subsubsection.6.1.2.1) 266 0 R (subsubsection.6.1.2.2) 270 0 R (subsubsection.6.2.10.1) 318 0 R (subsubsection.6.2.10.2) 322 0 R (subsubsection.6.2.10.3) 326 0 R (subsubsection.6.2.16.1) 354 0 R (subsubsection.6.2.16.10) 390 0 R (subsubsection.6.2.16.11) 394 0 R (subsubsection.6.2.16.12) 398 0 R (subsubsection.6.2.16.13) 402 0 R (subsubsection.6.2.16.14) 406 0 R (subsubsection.6.2.16.15) 410 0 R (subsubsection.6.2.16.16) 414 0 R (subsubsection.6.2.16.17) 418 0 R (subsubsection.6.2.16.18) 422 0 R (subsubsection.6.2.16.2) 358 0 R (subsubsection.6.2.16.3) 362 0 R (subsubsection.6.2.16.4) 366 0 R (subsubsection.6.2.16.5) 370 0 R (subsubsection.6.2.16.6) 374 0 R (subsubsection.6.2.16.7) 378 0 R (subsubsection.6.2.16.8) 382 0 R (subsubsection.6.2.16.9) 386 0 R (subsubsection.6.2.26.1) 466 0 R (subsubsection.6.2.26.2) 470 0 R (subsubsection.6.2.26.3) 474 0 R (subsubsection.6.2.26.4) 478 0 R (subsubsection.6.3.1.1) 490 0 R (subsubsection.6.3.1.2) 494 0 R (subsubsection.6.3.5.1) 514 0 R (subsubsection.6.3.5.2) 518 0 R (subsubsection.6.3.5.3) 522 0 R (subsubsection.6.3.5.4) 526 0 R (subsubsection.6.4.0.1) 542 0 R (subsubsection.6.4.1.1) 550 0 R (subsubsection.6.4.1.2) 554 0 R (subsubsection.6.4.1.3) 558 0 R (subsubsection.6.4.1.4) 562 0 R (subsubsection.6.4.1.5) 566 0 R (table.1.1) 950 0 R (table.1.2) 959 0 R (table.3.1) 1018 0 R (table.3.2) 1050 0 R (table.6.1) 1170 0 R (table.6.10) 1534 0 R (table.6.11) 1536 0 R (table.6.12) 1542 0 R (table.6.13) 1549 0 R (table.6.14) 1551 0 R (table.6.15) 1559 0 R (table.6.16) 1562 0 R (table.6.17) 1569 0 R (table.6.18) 1581 0 R (table.6.19) 1588 0 R (table.6.2) 1193 0 R (table.6.20) 1601 0 R (table.6.21) 1611 0 R (table.6.22) 1614 0 R (table.6.23) 1621 0 R (table.6.3) 1201 0 R (table.6.4) 1240 0 R (table.6.5) 1252 0 R (table.6.6) 1293 0 R (table.6.7) 1383 0 R (table.6.8) 1457 0 R (table.6.9) 1520 0 R (the_category_phrase) 1234 0 R (the_sortlist_statement) 1374 0 R (topology) 1369 0 R (tsig) 1097 0 R (tuning) 1388 0 R (types_of_resource_records_and_when_to_use_them) 966 0 R (view_statement_grammar) 1407 0 R (zone_statement_grammar) 1323 0 R (zone_transfers) 1073 0 R (zonefile_format) 1399 0 R]
+2730 0 obj <<
+/Names [(Access_Control_Lists) 2059 0 R (Bv9ARM.ch01) 1220 0 R (Bv9ARM.ch02) 1264 0 R (Bv9ARM.ch03) 1282 0 R (Bv9ARM.ch04) 1346 0 R (Bv9ARM.ch05) 1525 0 R (Bv9ARM.ch06) 1536 0 R (Bv9ARM.ch07) 2058 0 R (Bv9ARM.ch08) 2084 0 R (Bv9ARM.ch09) 2099 0 R (Bv9ARM.ch10) 2360 0 R (Configuration_File_Grammar) 1559 0 R (DNSSEC) 1412 0 R (Doc-Start) 927 0 R (Setting_TTLs) 1980 0 R (acache) 1271 0 R (access_control) 1710 0 R (acl) 1568 0 R (address_match_lists) 1541 0 R (admin_tools) 1304 0 R (appendix.A) 742 0 R (appendix.B) 834 0 R (bibliography) 2107 0 R (bind9.library) 2316 0 R (boolean_options) 1361 0 R (builtin) 1785 0 R (chapter*.1) 961 0 R (chapter.1) 6 0 R (chapter.2) 66 0 R (chapter.3) 90 0 R (chapter.4) 130 0 R (chapter.5) 342 0 R (chapter.6) 354 0 R (chapter.7) 698 0 R (chapter.8) 722 0 R (cite.RFC1033) 2235 0 R (cite.RFC1034) 2120 0 R (cite.RFC1035) 2122 0 R (cite.RFC1101) 2217 0 R (cite.RFC1123) 2219 0 R (cite.RFC1183) 2179 0 R (cite.RFC1464) 2257 0 R (cite.RFC1535) 2165 0 R (cite.RFC1536) 2167 0 R (cite.RFC1537) 2237 0 R (cite.RFC1591) 2221 0 R (cite.RFC1706) 2181 0 R (cite.RFC1712) 2277 0 R (cite.RFC1713) 2259 0 R (cite.RFC1794) 2261 0 R (cite.RFC1876) 2183 0 R (cite.RFC1912) 2239 0 R (cite.RFC1982) 2169 0 R (cite.RFC1995) 2127 0 R (cite.RFC1996) 2129 0 R (cite.RFC2010) 2241 0 R (cite.RFC2052) 2185 0 R (cite.RFC2065) 2289 0 R (cite.RFC2136) 2131 0 R (cite.RFC2137) 2291 0 R (cite.RFC2163) 2187 0 R (cite.RFC2168) 2189 0 R (cite.RFC2181) 2133 0 R (cite.RFC2219) 2243 0 R (cite.RFC2230) 2191 0 R (cite.RFC2240) 2263 0 R (cite.RFC2308) 2135 0 R (cite.RFC2317) 2223 0 R (cite.RFC2345) 2265 0 R (cite.RFC2352) 2267 0 R (cite.RFC2535) 2293 0 R (cite.RFC2536) 2193 0 R (cite.RFC2537) 2195 0 R (cite.RFC2538) 2197 0 R (cite.RFC2539) 2199 0 R (cite.RFC2540) 2201 0 R (cite.RFC2671) 2137 0 R (cite.RFC2672) 2139 0 R (cite.RFC2673) 2279 0 R (cite.RFC2782) 2203 0 R (cite.RFC2825) 2247 0 R (cite.RFC2826) 2225 0 R (cite.RFC2845) 2141 0 R (cite.RFC2874) 2281 0 R (cite.RFC2915) 2205 0 R (cite.RFC2929) 2227 0 R (cite.RFC2930) 2143 0 R (cite.RFC2931) 2145 0 R (cite.RFC3007) 2147 0 R (cite.RFC3008) 2295 0 R (cite.RFC3071) 2269 0 R (cite.RFC3090) 2297 0 R (cite.RFC3110) 2207 0 R (cite.RFC3123) 2209 0 R (cite.RFC3225) 2153 0 R (cite.RFC3258) 2271 0 R (cite.RFC3445) 2299 0 R (cite.RFC3490) 2249 0 R (cite.RFC3491) 2251 0 R (cite.RFC3492) 2253 0 R (cite.RFC3596) 2211 0 R (cite.RFC3597) 2213 0 R (cite.RFC3645) 2149 0 R (cite.RFC3655) 2301 0 R (cite.RFC3658) 2303 0 R (cite.RFC3755) 2305 0 R (cite.RFC3757) 2307 0 R (cite.RFC3833) 2155 0 R (cite.RFC3845) 2309 0 R (cite.RFC3901) 2273 0 R (cite.RFC4033) 2157 0 R (cite.RFC4034) 2159 0 R (cite.RFC4035) 2161 0 R (cite.RFC4074) 2171 0 R (cite.RFC974) 2124 0 R (cite.id2511436) 2314 0 R (clients-per-query) 2034 0 R (configuration_file_elements) 1537 0 R (controls_statement_definition_and_usage) 1329 0 R (diagnostic_tools) 1252 0 R (dnssec.dynamic.zones) 1432 0 R (dynamic_update) 1356 0 R (dynamic_update_policies) 1318 0 R (dynamic_update_security) 1721 0 R (empty) 1794 0 R (historical_dns_information) 2101 0 R (id2466563) 1221 0 R (id2466586) 1222 0 R (id2467270) 1411 0 R (id2467406) 1413 0 R (id2467477) 1223 0 R (id2467486) 1224 0 R (id2467726) 1234 0 R (id2467748) 1235 0 R (id2467782) 1236 0 R (id2467866) 1239 0 R (id2467959) 1232 0 R (id2470264) 1246 0 R (id2470288) 1249 0 R (id2470386) 1250 0 R (id2470407) 1251 0 R (id2470505) 1257 0 R (id2470540) 1258 0 R (id2470567) 1259 0 R (id2470601) 1265 0 R (id2470628) 1266 0 R (id2470709) 1267 0 R (id2470734) 1270 0 R (id2470745) 1276 0 R (id2470777) 1284 0 R (id2470793) 1285 0 R (id2470816) 1290 0 R (id2470833) 1291 0 R (id2471238) 1299 0 R (id2471243) 1300 0 R (id2473326) 1334 0 R (id2473338) 1335 0 R (id2473765) 1371 0 R (id2473851) 1377 0 R (id2474284) 1393 0 R (id2474301) 1394 0 R (id2474340) 1395 0 R (id2474358) 1396 0 R (id2474369) 1397 0 R (id2474405) 1402 0 R (id2474531) 1403 0 R (id2474580) 1405 0 R (id2474594) 1406 0 R (id2475200) 1418 0 R (id2475281) 1419 0 R (id2475706) 1433 0 R (id2475744) 1434 0 R (id2475780) 1439 0 R (id2475862) 1445 0 R (id2475899) 1452 0 R (id2475912) 1453 0 R (id2475945) 1454 0 R (id2476040) 1455 0 R (id2476050) 1460 0 R (id2476059) 1461 0 R (id2476072) 1462 0 R (id2476178) 1463 0 R (id2476187) 1464 0 R (id2476224) 1466 0 R (id2476314) 1473 0 R (id2476484) 1479 0 R (id2476648) 1485 0 R (id2476786) 1486 0 R (id2476891) 1491 0 R (id2476900) 1492 0 R (id2476931) 1493 0 R (id2476986) 1494 0 R (id2477085) 1499 0 R (id2477420) 1505 0 R (id2477466) 1506 0 R (id2477521) 1511 0 R (id2477651) 1513 0 R (id2477672) 1514 0 R (id2477705) 1526 0 R (id2477921) 1538 0 R (id2478882) 1546 0 R (id2478909) 1551 0 R (id2479115) 1552 0 R (id2479130) 1553 0 R (id2479160) 1558 0 R (id2479303) 1560 0 R (id2479837) 1567 0 R (id2479880) 1569 0 R (id2480027) 1571 0 R (id2480455) 1578 0 R (id2480472) 1584 0 R (id2480496) 1585 0 R (id2480519) 1586 0 R (id2480678) 1590 0 R (id2480804) 1595 0 R (id2480856) 1596 0 R (id2481481) 1607 0 R (id2482215) 1618 0 R (id2482345) 1619 0 R (id2482666) 1625 0 R (id2482808) 1630 0 R (id2482872) 1633 0 R (id2482916) 1634 0 R (id2482931) 1635 0 R (id2486190) 1673 0 R (id2488442) 1703 0 R (id2488501) 1709 0 R (id2489121) 1720 0 R (id2490256) 1743 0 R (id2490452) 1745 0 R (id2490806) 1754 0 R (id2491308) 1772 0 R (id2492919) 1803 0 R (id2493178) 1809 0 R (id2494065) 1827 0 R (id2494273) 1833 0 R (id2494320) 1835 0 R (id2494745) 1840 0 R (id2496290) 1858 0 R (id2496297) 1859 0 R (id2496302) 1860 0 R (id2496774) 1871 0 R (id2496875) 1872 0 R (id2499008) 1939 0 R (id2499554) 1945 0 R (id2499572) 1946 0 R (id2499660) 1949 0 R (id2499829) 1955 0 R (id2500999) 1961 0 R (id2501195) 1967 0 R (id2501217) 1968 0 R (id2501579) 1970 0 R (id2501716) 1972 0 R (id2501734) 1978 0 R (id2502206) 1981 0 R (id2502331) 1983 0 R (id2502346) 1984 0 R (id2502458) 1990 0 R (id2502481) 1991 0 R (id2502497) 1992 0 R (id2502694) 1993 0 R (id2502763) 1998 0 R (id2502800) 1999 0 R (id2502875) 2000 0 R (id2503386) 2011 0 R (id2503821) 2019 0 R (id2503827) 2020 0 R (id2505363) 2028 0 R (id2505369) 2029 0 R (id2505814) 2031 0 R (id2505819) 2032 0 R (id2506768) 2039 0 R (id2506800) 2040 0 R (id2507209) 2049 0 R (id2507520) 2068 0 R (id2507601) 2069 0 R (id2507660) 2070 0 R (id2507740) 2085 0 R (id2507746) 2086 0 R (id2507757) 2087 0 R (id2507774) 2088 0 R (id2507973) 2100 0 R (id2508213) 2106 0 R (id2508401) 2111 0 R (id2508403) 2118 0 R (id2508411) 2123 0 R (id2508435) 2119 0 R (id2508458) 2121 0 R (id2508494) 2132 0 R (id2508521) 2134 0 R (id2508547) 2126 0 R (id2508571) 2128 0 R (id2508595) 2130 0 R (id2508650) 2136 0 R (id2508677) 2138 0 R (id2508704) 2140 0 R (id2508765) 2142 0 R (id2508795) 2144 0 R (id2508825) 2146 0 R (id2508852) 2148 0 R (id2508926) 2151 0 R (id2508934) 2152 0 R (id2508961) 2154 0 R (id2508997) 2156 0 R (id2509062) 2158 0 R (id2509127) 2160 0 R (id2509192) 2163 0 R (id2509201) 2164 0 R (id2509226) 2166 0 R (id2509294) 2168 0 R (id2509330) 2170 0 R (id2509438) 2177 0 R (id2509444) 2178 0 R (id2509501) 2180 0 R (id2509539) 2188 0 R (id2509574) 2182 0 R (id2509628) 2184 0 R (id2509667) 2186 0 R (id2509692) 2190 0 R (id2509718) 2192 0 R (id2509745) 2194 0 R (id2509840) 2196 0 R (id2509879) 2198 0 R (id2509909) 2200 0 R (id2509939) 2202 0 R (id2509981) 2204 0 R (id2510014) 2206 0 R (id2510041) 2208 0 R (id2510065) 2210 0 R (id2510122) 2212 0 R (id2510147) 2215 0 R (id2510154) 2216 0 R (id2510180) 2218 0 R (id2510202) 2220 0 R (id2510226) 2222 0 R (id2510272) 2224 0 R (id2510295) 2226 0 R (id2510345) 2233 0 R (id2510353) 2234 0 R (id2510376) 2236 0 R (id2510403) 2238 0 R (id2510429) 2240 0 R (id2510466) 2242 0 R (id2510506) 2245 0 R (id2510512) 2246 0 R (id2510544) 2248 0 R (id2510589) 2250 0 R (id2510625) 2252 0 R (id2510651) 2255 0 R (id2510669) 2256 0 R (id2510692) 2258 0 R (id2510717) 2260 0 R (id2510743) 2262 0 R (id2510766) 2264 0 R (id2510812) 2266 0 R (id2510836) 2268 0 R (id2510862) 2270 0 R (id2510888) 2272 0 R (id2510925) 2275 0 R (id2510932) 2276 0 R (id2510989) 2278 0 R (id2511016) 2280 0 R (id2511052) 2287 0 R (id2511064) 2288 0 R (id2511104) 2290 0 R (id2511130) 2292 0 R (id2511160) 2294 0 R (id2511186) 2296 0 R (id2511212) 2298 0 R (id2511249) 2300 0 R (id2511285) 2302 0 R (id2511312) 2304 0 R (id2511338) 2306 0 R (id2511383) 2308 0 R (id2511425) 2311 0 R (id2511434) 2313 0 R (id2511436) 2315 0 R (id2511524) 2321 0 R (id2511533) 2322 0 R (id2511558) 2323 0 R (id2511589) 2324 0 R (id2511734) 2329 0 R (id2511829) 2331 0 R (id2511837) 2332 0 R (id2511928) 2338 0 R (id2511981) 2339 0 R (id2512045) 2340 0 R (id2512060) 2345 0 R (id2512260) 2350 0 R (id2512392) 2351 0 R (incremental_zone_transfers) 1368 0 R (internet_drafts) 2310 0 R (ipv6addresses) 1515 0 R (journal) 1367 0 R (lwresd) 1527 0 R (man.arpaname) 2670 0 R (man.ddns-confgen) 2655 0 R (man.dig) 2361 0 R (man.dnssec-dsfromkey) 2409 0 R (man.dnssec-keyfromlabel) 2428 0 R (man.dnssec-keygen) 1446 0 R (man.dnssec-revoke) 2471 0 R (man.dnssec-settime) 1447 0 R (man.dnssec-signzone) 2498 0 R (man.genrandom) 2676 0 R (man.host) 2394 0 R (man.isc-hmac-fixup) 2687 0 R (man.named) 2556 0 R (man.named-checkconf) 2523 0 R (man.named-checkzone) 2535 0 R (man.named-journalprint) 2578 0 R (man.nsec3hash) 2698 0 R (man.nsupdate) 2584 0 R (man.rndc) 2610 0 R (man.rndc-confgen) 2642 0 R (man.rndc.conf) 2626 0 R (managed-keys) 1468 0 R (notify) 1347 0 R (options) 1317 0 R (page.1) 926 0 R (page.10) 1308 0 R (page.100) 1954 0 R (page.101) 1960 0 R (page.102) 1966 0 R (page.103) 1977 0 R (page.104) 1989 0 R (page.105) 1997 0 R (page.106) 2005 0 R (page.107) 2009 0 R (page.108) 2017 0 R (page.109) 2026 0 R (page.11) 1322 0 R (page.110) 2038 0 R (page.111) 2045 0 R (page.112) 2053 0 R (page.113) 2057 0 R (page.114) 2063 0 R (page.115) 2075 0 R (page.116) 2079 0 R (page.117) 2083 0 R (page.118) 2094 0 R (page.119) 2098 0 R (page.12) 1326 0 R (page.120) 2105 0 R (page.121) 2116 0 R (page.122) 2175 0 R (page.123) 2231 0 R (page.124) 2285 0 R (page.125) 2320 0 R (page.126) 2328 0 R (page.127) 2337 0 R (page.128) 2344 0 R (page.129) 2349 0 R (page.13) 1333 0 R (page.130) 2355 0 R (page.131) 2359 0 R (page.132) 2368 0 R (page.133) 2375 0 R (page.134) 2380 0 R (page.135) 2384 0 R (page.136) 2389 0 R (page.137) 2400 0 R (page.138) 2405 0 R (page.139) 2418 0 R (page.14) 1340 0 R (page.140) 2427 0 R (page.141) 2436 0 R (page.142) 2441 0 R (page.143) 2450 0 R (page.144) 2456 0 R (page.145) 2461 0 R (page.146) 2467 0 R (page.147) 2478 0 R (page.148) 2488 0 R (page.149) 2494 0 R (page.15) 1345 0 R (page.150) 2505 0 R (page.151) 2511 0 R (page.152) 2515 0 R (page.153) 2519 0 R (page.154) 2530 0 R (page.155) 2541 0 R (page.156) 2547 0 R (page.157) 2553 0 R (page.158) 2564 0 R (page.159) 2568 0 R (page.16) 1366 0 R (page.160) 2575 0 R (page.161) 2589 0 R (page.162) 2595 0 R (page.163) 2601 0 R (page.164) 2606 0 R (page.165) 2615 0 R (page.166) 2623 0 R (page.167) 2633 0 R (page.168) 2638 0 R (page.169) 2651 0 R (page.17) 1376 0 R (page.170) 2660 0 R (page.171) 2668 0 R (page.172) 2683 0 R (page.173) 2695 0 R (page.18) 1382 0 R (page.19) 1387 0 R (page.2) 950 0 R (page.20) 1392 0 R (page.21) 1401 0 R (page.22) 1410 0 R (page.23) 1417 0 R (page.24) 1423 0 R (page.25) 1428 0 R (page.26) 1438 0 R (page.27) 1451 0 R (page.28) 1459 0 R (page.29) 1472 0 R (page.3) 1245 0 R (page.30) 1478 0 R (page.31) 1484 0 R (page.32) 1490 0 R (page.33) 1498 0 R (page.34) 1504 0 R (page.35) 1510 0 R (page.36) 1519 0 R (page.37) 1524 0 R (page.38) 1531 0 R (page.39) 1535 0 R (page.4) 1256 0 R (page.40) 1545 0 R (page.41) 1550 0 R (page.42) 1557 0 R (page.43) 1566 0 R (page.44) 1575 0 R (page.45) 1583 0 R (page.46) 1594 0 R (page.47) 1600 0 R (page.48) 1606 0 R (page.49) 1613 0 R (page.5) 1263 0 R (page.50) 1617 0 R (page.51) 1624 0 R (page.52) 1629 0 R (page.53) 1639 0 R (page.54) 1643 0 R (page.55) 1648 0 R (page.56) 1652 0 R (page.57) 1656 0 R (page.58) 1662 0 R (page.59) 1667 0 R (page.6) 1275 0 R (page.60) 1672 0 R (page.61) 1679 0 R (page.62) 1684 0 R (page.63) 1694 0 R (page.64) 1698 0 R (page.65) 1702 0 R (page.66) 1707 0 R (page.67) 1717 0 R (page.68) 1725 0 R (page.69) 1730 0 R (page.7) 1281 0 R (page.70) 1734 0 R (page.71) 1738 0 R (page.72) 1742 0 R (page.73) 1751 0 R (page.74) 1758 0 R (page.75) 1763 0 R (page.76) 1770 0 R (page.77) 1778 0 R (page.78) 1783 0 R (page.79) 1793 0 R (page.8) 1289 0 R (page.80) 1798 0 R (page.81) 1802 0 R (page.82) 1808 0 R (page.83) 1813 0 R (page.84) 1818 0 R (page.85) 1824 0 R (page.86) 1832 0 R (page.87) 1839 0 R (page.88) 1844 0 R (page.89) 1848 0 R (page.9) 1298 0 R (page.90) 1852 0 R (page.91) 1857 0 R (page.92) 1865 0 R (page.93) 1869 0 R (page.94) 1884 0 R (page.95) 1898 0 R (page.96) 1910 0 R (page.97) 1931 0 R (page.98) 1938 0 R (page.99) 1944 0 R (page.i) 960 0 R (page.ii) 1015 0 R (page.iii) 1079 0 R (page.iv) 1142 0 R (page.v) 1204 0 R (pkcs11) 1474 0 R (proposed_standards) 1372 0 R (query_address) 1726 0 R (rfc5011.support) 1465 0 R (rfcs) 1241 0 R (rndc) 1579 0 R (root_delegation_only) 1880 0 R (rrset_ordering) 1294 0 R (sample_configuration) 1283 0 R (section*.10) 2244 0 R (section*.100) 2576 0 R (section*.101) 2577 0 R (section*.102) 2579 0 R (section*.103) 2580 0 R (section*.104) 2581 0 R (section*.105) 2582 0 R (section*.106) 2583 0 R (section*.107) 2585 0 R (section*.108) 2590 0 R (section*.109) 2591 0 R (section*.11) 2254 0 R (section*.110) 2596 0 R (section*.111) 2602 0 R (section*.112) 2607 0 R (section*.113) 2608 0 R (section*.114) 2609 0 R (section*.115) 2611 0 R (section*.116) 2616 0 R (section*.117) 2617 0 R (section*.118) 2618 0 R (section*.119) 2619 0 R (section*.12) 2274 0 R (section*.120) 2624 0 R (section*.121) 2625 0 R (section*.122) 2627 0 R (section*.123) 2628 0 R (section*.124) 2629 0 R (section*.125) 2634 0 R (section*.126) 2639 0 R (section*.127) 2640 0 R (section*.128) 2641 0 R (section*.129) 2643 0 R (section*.13) 2286 0 R (section*.130) 2644 0 R (section*.131) 2645 0 R (section*.132) 2646 0 R (section*.133) 2652 0 R (section*.134) 2653 0 R (section*.135) 2654 0 R (section*.136) 2656 0 R (section*.137) 2661 0 R (section*.138) 2662 0 R (section*.139) 2663 0 R (section*.14) 2312 0 R (section*.140) 2664 0 R (section*.141) 2669 0 R (section*.142) 2671 0 R (section*.143) 2672 0 R (section*.144) 2673 0 R (section*.145) 2674 0 R (section*.146) 2675 0 R (section*.147) 2677 0 R (section*.148) 2678 0 R (section*.149) 2679 0 R (section*.15) 2362 0 R (section*.150) 2684 0 R (section*.151) 2685 0 R (section*.152) 2686 0 R (section*.153) 2688 0 R (section*.154) 2689 0 R (section*.155) 2690 0 R (section*.156) 2691 0 R (section*.157) 2696 0 R (section*.158) 2697 0 R (section*.159) 2699 0 R (section*.16) 2363 0 R (section*.160) 2700 0 R (section*.161) 2701 0 R (section*.162) 2702 0 R (section*.163) 2703 0 R (section*.164) 2704 0 R (section*.17) 2364 0 R (section*.18) 2369 0 R (section*.19) 2370 0 R (section*.2) 2110 0 R (section*.20) 2376 0 R (section*.21) 2385 0 R (section*.22) 2390 0 R (section*.23) 2391 0 R (section*.24) 2392 0 R (section*.25) 2393 0 R (section*.26) 2395 0 R (section*.27) 2396 0 R (section*.28) 2401 0 R (section*.29) 2406 0 R (section*.3) 2117 0 R (section*.30) 2407 0 R (section*.31) 2408 0 R (section*.32) 2410 0 R (section*.33) 2411 0 R (section*.34) 2412 0 R (section*.35) 2413 0 R (section*.36) 2419 0 R (section*.37) 2420 0 R (section*.38) 2421 0 R (section*.39) 2422 0 R (section*.4) 2125 0 R (section*.40) 2423 0 R (section*.41) 2429 0 R (section*.42) 2430 0 R (section*.43) 2431 0 R (section*.44) 2432 0 R (section*.45) 2437 0 R (section*.46) 2442 0 R (section*.47) 2443 0 R (section*.48) 2444 0 R (section*.49) 2445 0 R (section*.5) 2150 0 R (section*.50) 2446 0 R (section*.51) 2451 0 R (section*.52) 2452 0 R (section*.53) 2462 0 R (section*.54) 2463 0 R (section*.55) 2468 0 R (section*.56) 2469 0 R (section*.57) 2470 0 R (section*.58) 2472 0 R (section*.59) 2473 0 R (section*.6) 2162 0 R (section*.60) 2474 0 R (section*.61) 2479 0 R (section*.62) 2480 0 R (section*.63) 2481 0 R (section*.64) 2482 0 R (section*.65) 2483 0 R (section*.66) 2484 0 R (section*.67) 2489 0 R (section*.68) 2490 0 R (section*.69) 2495 0 R (section*.7) 2176 0 R (section*.70) 2496 0 R (section*.71) 2497 0 R (section*.72) 2499 0 R (section*.73) 2500 0 R (section*.74) 2501 0 R (section*.75) 2506 0 R (section*.76) 2520 0 R (section*.77) 2521 0 R (section*.78) 2522 0 R (section*.79) 2524 0 R (section*.8) 2214 0 R (section*.80) 2525 0 R (section*.81) 2526 0 R (section*.82) 2531 0 R (section*.83) 2532 0 R (section*.84) 2533 0 R (section*.85) 2534 0 R (section*.86) 2536 0 R (section*.87) 2537 0 R (section*.88) 2542 0 R (section*.89) 2543 0 R (section*.9) 2232 0 R (section*.90) 2548 0 R (section*.91) 2554 0 R (section*.92) 2555 0 R (section*.93) 2557 0 R (section*.94) 2558 0 R (section*.95) 2559 0 R (section*.96) 2560 0 R (section*.97) 2569 0 R (section*.98) 2570 0 R (section*.99) 2571 0 R (section.1.1) 10 0 R (section.1.2) 14 0 R (section.1.3) 18 0 R (section.1.4) 22 0 R (section.2.1) 70 0 R (section.2.2) 74 0 R (section.2.3) 78 0 R (section.2.4) 82 0 R (section.2.5) 86 0 R (section.3.1) 94 0 R (section.3.2) 106 0 R (section.3.3) 110 0 R (section.4.1) 134 0 R (section.4.10) 274 0 R (section.4.11) 286 0 R (section.4.12) 330 0 R (section.4.2) 138 0 R (section.4.3) 146 0 R (section.4.4) 150 0 R (section.4.5) 158 0 R (section.4.6) 194 0 R (section.4.7) 198 0 R (section.4.8) 202 0 R (section.4.9) 218 0 R (section.5.1) 346 0 R (section.5.2) 350 0 R (section.6.1) 358 0 R (section.6.2) 386 0 R (section.6.3) 610 0 R (section.6.4) 666 0 R (section.7.1) 702 0 R (section.7.2) 706 0 R (section.7.3) 718 0 R (section.8.1) 726 0 R (section.8.2) 734 0 R (section.8.3) 738 0 R (section.A.1) 746 0 R (section.A.2) 754 0 R (section.A.3) 762 0 R (section.A.4) 778 0 R (section.B.1) 838 0 R (section.B.10) 874 0 R (section.B.11) 878 0 R (section.B.12) 882 0 R (section.B.13) 886 0 R (section.B.14) 890 0 R (section.B.15) 894 0 R (section.B.16) 898 0 R (section.B.17) 902 0 R (section.B.18) 906 0 R (section.B.19) 910 0 R (section.B.2) 842 0 R (section.B.20) 914 0 R (section.B.21) 918 0 R (section.B.3) 846 0 R (section.B.4) 850 0 R (section.B.5) 854 0 R (section.B.6) 858 0 R (section.B.7) 862 0 R (section.B.8) 866 0 R (section.B.9) 870 0 R (server_resource_limits) 1752 0 R (server_statement_definition_and_usage) 1690 0 R (server_statement_grammar) 1814 0 R (statistics) 2010 0 R (statistics_counters) 2018 0 R (statschannels) 1826 0 R (statsfile) 1658 0 R (subsection.1.4.1) 26 0 R (subsection.1.4.2) 30 0 R (subsection.1.4.3) 34 0 R (subsection.1.4.4) 38 0 R (subsection.1.4.5) 54 0 R (subsection.1.4.6) 62 0 R (subsection.3.1.1) 98 0 R (subsection.3.1.2) 102 0 R (subsection.3.3.1) 114 0 R (subsection.3.3.2) 126 0 R (subsection.4.10.1) 278 0 R (subsection.4.10.2) 282 0 R (subsection.4.11.1) 290 0 R (subsection.4.11.2) 302 0 R (subsection.4.11.3) 314 0 R (subsection.4.11.4) 318 0 R (subsection.4.11.5) 322 0 R (subsection.4.11.6) 326 0 R (subsection.4.12.1) 334 0 R (subsection.4.12.2) 338 0 R (subsection.4.2.1) 142 0 R (subsection.4.4.1) 154 0 R (subsection.4.5.1) 162 0 R (subsection.4.5.2) 174 0 R (subsection.4.5.3) 178 0 R (subsection.4.5.4) 182 0 R (subsection.4.5.5) 186 0 R (subsection.4.5.6) 190 0 R (subsection.4.8.1) 206 0 R (subsection.4.8.2) 210 0 R (subsection.4.8.3) 214 0 R (subsection.4.9.1) 222 0 R (subsection.4.9.10) 258 0 R (subsection.4.9.11) 262 0 R (subsection.4.9.12) 266 0 R (subsection.4.9.13) 270 0 R (subsection.4.9.2) 226 0 R (subsection.4.9.3) 230 0 R (subsection.4.9.4) 234 0 R (subsection.4.9.5) 238 0 R (subsection.4.9.6) 242 0 R (subsection.4.9.7) 246 0 R (subsection.4.9.8) 250 0 R (subsection.4.9.9) 254 0 R (subsection.6.1.1) 362 0 R (subsection.6.1.2) 374 0 R (subsection.6.2.1) 390 0 R (subsection.6.2.10) 426 0 R (subsection.6.2.11) 442 0 R (subsection.6.2.12) 446 0 R (subsection.6.2.13) 450 0 R (subsection.6.2.14) 454 0 R (subsection.6.2.15) 458 0 R (subsection.6.2.16) 462 0 R (subsection.6.2.17) 546 0 R (subsection.6.2.18) 550 0 R (subsection.6.2.19) 554 0 R (subsection.6.2.2) 394 0 R (subsection.6.2.20) 558 0 R (subsection.6.2.21) 562 0 R (subsection.6.2.22) 566 0 R (subsection.6.2.23) 570 0 R (subsection.6.2.24) 574 0 R (subsection.6.2.25) 578 0 R (subsection.6.2.26) 582 0 R (subsection.6.2.27) 586 0 R (subsection.6.2.28) 590 0 R (subsection.6.2.3) 398 0 R (subsection.6.2.4) 402 0 R (subsection.6.2.5) 406 0 R (subsection.6.2.6) 410 0 R (subsection.6.2.7) 414 0 R (subsection.6.2.8) 418 0 R (subsection.6.2.9) 422 0 R (subsection.6.3.1) 614 0 R (subsection.6.3.2) 626 0 R (subsection.6.3.3) 630 0 R (subsection.6.3.4) 634 0 R (subsection.6.3.5) 638 0 R (subsection.6.3.6) 658 0 R (subsection.6.3.7) 662 0 R (subsection.6.4.1) 674 0 R (subsection.7.2.1) 710 0 R (subsection.7.2.2) 714 0 R (subsection.8.1.1) 730 0 R (subsection.A.1.1) 750 0 R (subsection.A.2.1) 758 0 R (subsection.A.3.1) 766 0 R (subsection.A.3.2) 770 0 R (subsection.A.3.3) 774 0 R (subsection.A.4.1) 782 0 R (subsection.A.4.2) 786 0 R (subsection.A.4.3) 790 0 R (subsection.A.4.4) 794 0 R (subsection.A.4.5) 798 0 R (subsection.A.4.6) 802 0 R (subsection.A.4.7) 830 0 R (subsubsection.1.4.4.1) 42 0 R (subsubsection.1.4.4.2) 46 0 R (subsubsection.1.4.4.3) 50 0 R (subsubsection.1.4.5.1) 58 0 R (subsubsection.3.3.1.1) 118 0 R (subsubsection.3.3.1.2) 122 0 R (subsubsection.4.11.1.1) 294 0 R (subsubsection.4.11.1.2) 298 0 R (subsubsection.4.11.2.1) 306 0 R (subsubsection.4.11.2.2) 310 0 R (subsubsection.4.5.1.1) 166 0 R (subsubsection.4.5.1.2) 170 0 R (subsubsection.6.1.1.1) 366 0 R (subsubsection.6.1.1.2) 370 0 R (subsubsection.6.1.2.1) 378 0 R (subsubsection.6.1.2.2) 382 0 R (subsubsection.6.2.10.1) 430 0 R (subsubsection.6.2.10.2) 434 0 R (subsubsection.6.2.10.3) 438 0 R (subsubsection.6.2.16.1) 466 0 R (subsubsection.6.2.16.10) 502 0 R (subsubsection.6.2.16.11) 506 0 R (subsubsection.6.2.16.12) 510 0 R (subsubsection.6.2.16.13) 514 0 R (subsubsection.6.2.16.14) 518 0 R (subsubsection.6.2.16.15) 522 0 R (subsubsection.6.2.16.16) 526 0 R (subsubsection.6.2.16.17) 530 0 R (subsubsection.6.2.16.18) 534 0 R (subsubsection.6.2.16.19) 538 0 R (subsubsection.6.2.16.2) 470 0 R (subsubsection.6.2.16.20) 542 0 R (subsubsection.6.2.16.3) 474 0 R (subsubsection.6.2.16.4) 478 0 R (subsubsection.6.2.16.5) 482 0 R (subsubsection.6.2.16.6) 486 0 R (subsubsection.6.2.16.7) 490 0 R (subsubsection.6.2.16.8) 494 0 R (subsubsection.6.2.16.9) 498 0 R (subsubsection.6.2.28.1) 594 0 R (subsubsection.6.2.28.2) 598 0 R (subsubsection.6.2.28.3) 602 0 R (subsubsection.6.2.28.4) 606 0 R (subsubsection.6.3.1.1) 618 0 R (subsubsection.6.3.1.2) 622 0 R (subsubsection.6.3.5.1) 642 0 R (subsubsection.6.3.5.2) 646 0 R (subsubsection.6.3.5.3) 650 0 R (subsubsection.6.3.5.4) 654 0 R (subsubsection.6.4.0.1) 670 0 R (subsubsection.6.4.1.1) 678 0 R (subsubsection.6.4.1.2) 682 0 R (subsubsection.6.4.1.3) 686 0 R (subsubsection.6.4.1.4) 690 0 R (subsubsection.6.4.1.5) 694 0 R (subsubsection.A.4.6.1) 806 0 R (subsubsection.A.4.6.2) 810 0 R (subsubsection.A.4.6.3) 814 0 R (subsubsection.A.4.6.4) 818 0 R (subsubsection.A.4.6.5) 822 0 R (subsubsection.A.4.6.6) 826 0 R (table.1.1) 1225 0 R (table.1.2) 1233 0 R (table.3.1) 1292 0 R (table.3.2) 1336 0 R (table.6.1) 1539 0 R (table.6.10) 1950 0 R (table.6.11) 1956 0 R (table.6.12) 1962 0 R (table.6.13) 1969 0 R (table.6.14) 1971 0 R (table.6.15) 1979 0 R (table.6.16) 1982 0 R (table.6.17) 1985 0 R (table.6.18) 2001 0 R (table.6.19) 2012 0 R (table.6.2) 1561 0 R (table.6.20) 2021 0 R (table.6.21) 2030 0 R (table.6.22) 2033 0 R (table.6.23) 2041 0 R (table.6.3) 1570 0 R (table.6.4) 1608 0 R (table.6.5) 1620 0 R (table.6.6) 1674 0 R (table.6.7) 1773 0 R (table.6.8) 1861 0 R (table.6.9) 1940 0 R (the_category_phrase) 1602 0 R (the_sortlist_statement) 1764 0 R (topology) 1759 0 R (trusted-keys) 1828 0 R (tsig) 1388 0 R (tuning) 1774 0 R (types_of_resource_records_and_when_to_use_them) 1240 0 R (view_statement_grammar) 1789 0 R (zone_statement_grammar) 1713 0 R (zone_transfers) 1362 0 R (zonefile_format) 1788 0 R]
/Limits [(Access_Control_Lists) (zonefile_format)]
>> endobj
-2165 0 obj <<
-/Kids [2164 0 R]
+2731 0 obj <<
+/Kids [2730 0 R]
>> endobj
-2166 0 obj <<
-/Dests 2165 0 R
+2732 0 obj <<
+/Dests 2731 0 R
>> endobj
-2167 0 obj <<
+2733 0 obj <<
/Type /Catalog
-/Pages 2162 0 R
-/Outlines 2163 0 R
-/Names 2166 0 R
+/Pages 2728 0 R
+/Outlines 2729 0 R
+/Names 2732 0 R
/PageMode /UseOutlines
-/OpenAction 705 0 R
+/OpenAction 921 0 R
>> endobj
-2168 0 obj <<
+2734 0 obj <<
/Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfeTeX-1.21a)/Keywords()
-/CreationDate (D:20100910020422Z)
+/CreationDate (D:20110609034043Z)
/PTEX.Fullbanner (This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) kpathsea version 3.5.4)
>> endobj
xref
-0 2169
+0 2735
0000000001 65535 f
0000000002 00000 f
0000000003 00000 f
0000000004 00000 f
0000000000 00000 f
0000000009 00000 n
-0000328752 00000 n
-0001011409 00000 n
+0000347882 00000 n
+0001171649 00000 n
0000000054 00000 n
0000000086 00000 n
-0000328876 00000 n
-0001011337 00000 n
+0000348009 00000 n
+0001171577 00000 n
0000000133 00000 n
0000000173 00000 n
-0000329001 00000 n
-0001011251 00000 n
+0000348137 00000 n
+0001171491 00000 n
0000000221 00000 n
0000000273 00000 n
-0000329126 00000 n
-0001011165 00000 n
+0000348265 00000 n
+0001171405 00000 n
0000000321 00000 n
0000000377 00000 n
-0000333388 00000 n
-0001011055 00000 n
+0000352551 00000 n
+0001171295 00000 n
0000000425 00000 n
0000000478 00000 n
-0000333512 00000 n
-0001010981 00000 n
+0000352678 00000 n
+0001171221 00000 n
0000000531 00000 n
0000000572 00000 n
-0000333637 00000 n
-0001010894 00000 n
+0000352806 00000 n
+0001171134 00000 n
0000000625 00000 n
0000000674 00000 n
-0000333761 00000 n
-0001010807 00000 n
+0000352933 00000 n
+0001171047 00000 n
0000000727 00000 n
0000000757 00000 n
-0000338040 00000 n
-0001010683 00000 n
+0000357230 00000 n
+0001170923 00000 n
0000000810 00000 n
0000000861 00000 n
-0000338165 00000 n
-0001010609 00000 n
+0000357358 00000 n
+0001170849 00000 n
0000000919 00000 n
0000000964 00000 n
-0000338290 00000 n
-0001010522 00000 n
+0000357486 00000 n
+0001170762 00000 n
0000001022 00000 n
0000001062 00000 n
-0000338415 00000 n
-0001010448 00000 n
+0000357614 00000 n
+0001170688 00000 n
0000001120 00000 n
0000001162 00000 n
-0000341386 00000 n
-0001010324 00000 n
+0000360599 00000 n
+0001170564 00000 n
0000001215 00000 n
0000001260 00000 n
-0000341511 00000 n
-0001010263 00000 n
+0000360727 00000 n
+0001170503 00000 n
0000001318 00000 n
0000001355 00000 n
-0000341636 00000 n
-0001010189 00000 n
+0000360855 00000 n
+0001170429 00000 n
0000001408 00000 n
0000001463 00000 n
-0000344566 00000 n
-0001010064 00000 n
+0000363802 00000 n
+0001170304 00000 n
0000001509 00000 n
0000001556 00000 n
-0000344691 00000 n
-0001009990 00000 n
+0000363930 00000 n
+0001170230 00000 n
0000001604 00000 n
0000001648 00000 n
-0000344816 00000 n
-0001009903 00000 n
+0000364058 00000 n
+0001170143 00000 n
0000001696 00000 n
0000001735 00000 n
-0000344941 00000 n
-0001009816 00000 n
+0000364186 00000 n
+0001170056 00000 n
0000001783 00000 n
0000001825 00000 n
-0000345065 00000 n
-0001009729 00000 n
+0000364313 00000 n
+0001169969 00000 n
0000001873 00000 n
0000001936 00000 n
-0000346148 00000 n
-0001009655 00000 n
+0000365390 00000 n
+0001169895 00000 n
0000001984 00000 n
0000002034 00000 n
-0000347859 00000 n
-0001009527 00000 n
+0000367049 00000 n
+0001169767 00000 n
0000002080 00000 n
0000002126 00000 n
-0000347986 00000 n
-0001009414 00000 n
+0000367176 00000 n
+0001169654 00000 n
0000002174 00000 n
0000002218 00000 n
-0000348114 00000 n
-0001009338 00000 n
+0000367304 00000 n
+0001169578 00000 n
0000002271 00000 n
0000002323 00000 n
-0000348242 00000 n
-0001009261 00000 n
+0000367432 00000 n
+0001169501 00000 n
0000002377 00000 n
0000002436 00000 n
-0000350787 00000 n
-0001009170 00000 n
+0000369881 00000 n
+0001169410 00000 n
0000002485 00000 n
0000002523 00000 n
-0000351046 00000 n
-0001009053 00000 n
+0000373219 00000 n
+0001169293 00000 n
0000002572 00000 n
0000002618 00000 n
-0000351175 00000 n
-0001008935 00000 n
+0000373347 00000 n
+0001169175 00000 n
0000002672 00000 n
0000002739 00000 n
-0000354406 00000 n
-0001008856 00000 n
+0000373475 00000 n
+0001169096 00000 n
0000002798 00000 n
0000002842 00000 n
-0000354534 00000 n
-0001008777 00000 n
+0000373604 00000 n
+0001169017 00000 n
0000002901 00000 n
0000002949 00000 n
-0000365183 00000 n
-0001008698 00000 n
+0000388343 00000 n
+0001168938 00000 n
0000003003 00000 n
0000003036 00000 n
-0000370204 00000 n
-0001008566 00000 n
+0000393969 00000 n
+0001168805 00000 n
0000003083 00000 n
0000003126 00000 n
-0000370333 00000 n
-0001008487 00000 n
+0000394098 00000 n
+0001168726 00000 n
0000003175 00000 n
0000003205 00000 n
-0000370462 00000 n
-0001008355 00000 n
+0000394227 00000 n
+0001168594 00000 n
0000003254 00000 n
0000003292 00000 n
-0000370591 00000 n
-0001008290 00000 n
+0000398736 00000 n
+0001168529 00000 n
0000003346 00000 n
0000003388 00000 n
-0000374998 00000 n
-0001008197 00000 n
+0000398865 00000 n
+0001168436 00000 n
0000003437 00000 n
0000003496 00000 n
-0000375127 00000 n
-0001008065 00000 n
+0000398994 00000 n
+0001168304 00000 n
0000003545 00000 n
0000003578 00000 n
-0000375256 00000 n
-0001008000 00000 n
+0000402912 00000 n
+0001168239 00000 n
0000003632 00000 n
0000003681 00000 n
-0000382582 00000 n
-0001007868 00000 n
+0000405926 00000 n
+0001168107 00000 n
0000003730 00000 n
0000003758 00000 n
-0000382711 00000 n
-0001007750 00000 n
+0000408706 00000 n
+0001167989 00000 n
0000003812 00000 n
0000003881 00000 n
-0000382840 00000 n
-0001007671 00000 n
+0000408835 00000 n
+0001167910 00000 n
0000003940 00000 n
0000003988 00000 n
-0000385631 00000 n
-0001007592 00000 n
+0000408963 00000 n
+0001167831 00000 n
0000004047 00000 n
0000004092 00000 n
-0000385760 00000 n
-0001007499 00000 n
+0000409092 00000 n
+0001167738 00000 n
0000004146 00000 n
0000004214 00000 n
-0000385889 00000 n
-0001007406 00000 n
+0000409221 00000 n
+0001167645 00000 n
0000004268 00000 n
0000004338 00000 n
-0000386018 00000 n
-0001007313 00000 n
+0000412890 00000 n
+0001167552 00000 n
0000004392 00000 n
0000004455 00000 n
-0000389940 00000 n
-0001007220 00000 n
+0000413019 00000 n
+0001167459 00000 n
0000004509 00000 n
0000004564 00000 n
-0000390069 00000 n
-0001007141 00000 n
+0000413147 00000 n
+0001167380 00000 n
0000004618 00000 n
0000004650 00000 n
-0000390198 00000 n
-0001007048 00000 n
+0000413275 00000 n
+0001167287 00000 n
0000004699 00000 n
0000004727 00000 n
-0000390327 00000 n
-0001006955 00000 n
+0000417044 00000 n
+0001167194 00000 n
0000004776 00000 n
0000004808 00000 n
-0000394104 00000 n
-0001006823 00000 n
+0000417173 00000 n
+0001167062 00000 n
0000004857 00000 n
0000004887 00000 n
-0000394233 00000 n
-0001006744 00000 n
+0000417302 00000 n
+0001166983 00000 n
0000004941 00000 n
0000004982 00000 n
-0000394362 00000 n
-0001006651 00000 n
+0000421100 00000 n
+0001166890 00000 n
0000005036 00000 n
0000005078 00000 n
-0000397957 00000 n
-0001006572 00000 n
+0000421229 00000 n
+0001166811 00000 n
0000005132 00000 n
0000005177 00000 n
-0000401403 00000 n
-0001006454 00000 n
+0000426552 00000 n
+0001166678 00000 n
0000005226 00000 n
-0000005272 00000 n
-0000403004 00000 n
-0001006375 00000 n
-0000005326 00000 n
-0000005386 00000 n
-0000403133 00000 n
-0001006296 00000 n
-0000005440 00000 n
-0000005509 00000 n
-0000405940 00000 n
-0001006163 00000 n
-0000005556 00000 n
-0000005609 00000 n
-0000406069 00000 n
-0001006084 00000 n
-0000005658 00000 n
-0000005714 00000 n
-0000406198 00000 n
-0001006005 00000 n
-0000005763 00000 n
-0000005812 00000 n
-0000410382 00000 n
-0001005872 00000 n
-0000005859 00000 n
-0000005911 00000 n
-0000410511 00000 n
-0001005754 00000 n
-0000005960 00000 n
-0000006011 00000 n
-0000415203 00000 n
-0001005636 00000 n
-0000006065 00000 n
-0000006110 00000 n
-0000415331 00000 n
-0001005557 00000 n
-0000006169 00000 n
-0000006203 00000 n
-0000418952 00000 n
-0001005478 00000 n
-0000006262 00000 n
-0000006310 00000 n
-0000419080 00000 n
-0001005360 00000 n
-0000006364 00000 n
-0000006404 00000 n
-0000419209 00000 n
-0001005281 00000 n
-0000006463 00000 n
-0000006497 00000 n
-0000423146 00000 n
-0001005202 00000 n
-0000006556 00000 n
-0000006604 00000 n
-0000423275 00000 n
-0001005069 00000 n
-0000006653 00000 n
-0000006703 00000 n
-0000426095 00000 n
-0001004990 00000 n
-0000006757 00000 n
-0000006804 00000 n
-0000426223 00000 n
-0001004897 00000 n
-0000006858 00000 n
-0000006918 00000 n
-0000426482 00000 n
-0001004804 00000 n
-0000006972 00000 n
-0000007024 00000 n
-0000431831 00000 n
-0001004711 00000 n
-0000007078 00000 n
-0000007143 00000 n
-0000431960 00000 n
-0001004618 00000 n
-0000007197 00000 n
-0000007248 00000 n
-0000432089 00000 n
-0001004525 00000 n
-0000007302 00000 n
-0000007366 00000 n
-0000435541 00000 n
-0001004432 00000 n
-0000007420 00000 n
-0000007467 00000 n
-0000435670 00000 n
-0001004339 00000 n
-0000007521 00000 n
-0000007581 00000 n
-0000435799 00000 n
-0001004246 00000 n
-0000007635 00000 n
-0000007686 00000 n
-0000435928 00000 n
-0001004114 00000 n
-0000007741 00000 n
-0000007806 00000 n
-0000440159 00000 n
-0001004035 00000 n
-0000007866 00000 n
-0000007913 00000 n
-0000446716 00000 n
-0001003942 00000 n
-0000007973 00000 n
-0000008021 00000 n
-0000454268 00000 n
-0001003863 00000 n
-0000008081 00000 n
-0000008135 00000 n
-0000454527 00000 n
-0001003770 00000 n
-0000008190 00000 n
+0000005294 00000 n
+0000426681 00000 n
+0001166599 00000 n
+0000005348 00000 n
+0000005408 00000 n
+0000426810 00000 n
+0001166506 00000 n
+0000005462 00000 n
+0000005513 00000 n
+0000430749 00000 n
+0001166413 00000 n
+0000005567 00000 n
+0000005621 00000 n
+0000430877 00000 n
+0001166320 00000 n
+0000005675 00000 n
+0000005721 00000 n
+0000434027 00000 n
+0001166227 00000 n
+0000005775 00000 n
+0000005817 00000 n
+0000434156 00000 n
+0001166134 00000 n
+0000005871 00000 n
+0000005922 00000 n
+0000434285 00000 n
+0001166041 00000 n
+0000005976 00000 n
+0000006025 00000 n
+0000434414 00000 n
+0001165948 00000 n
+0000006079 00000 n
+0000006136 00000 n
+0000437328 00000 n
+0001165855 00000 n
+0000006190 00000 n
+0000006245 00000 n
+0000437457 00000 n
+0001165762 00000 n
+0000006300 00000 n
+0000006356 00000 n
+0000437586 00000 n
+0001165669 00000 n
+0000006411 00000 n
+0000006472 00000 n
+0000437715 00000 n
+0001165576 00000 n
+0000006527 00000 n
+0000006573 00000 n
+0000437844 00000 n
+0001165497 00000 n
+0000006628 00000 n
+0000006671 00000 n
+0000437973 00000 n
+0001165365 00000 n
+0000006721 00000 n
+0000006777 00000 n
+0000438102 00000 n
+0001165286 00000 n
+0000006832 00000 n
+0000006878 00000 n
+0000441694 00000 n
+0001165207 00000 n
+0000006933 00000 n
+0000006980 00000 n
+0000441823 00000 n
+0001165075 00000 n
+0000007030 00000 n
+0000007087 00000 n
+0000444830 00000 n
+0001164957 00000 n
+0000007142 00000 n
+0000007182 00000 n
+0000447718 00000 n
+0001164878 00000 n
+0000007242 00000 n
+0000007315 00000 n
+0000447847 00000 n
+0001164799 00000 n
+0000007375 00000 n
+0000007448 00000 n
+0000450309 00000 n
+0001164667 00000 n
+0000007503 00000 n
+0000007561 00000 n
+0000450438 00000 n
+0001164588 00000 n
+0000007621 00000 n
+0000007678 00000 n
+0000450567 00000 n
+0001164509 00000 n
+0000007738 00000 n
+0000007797 00000 n
+0000450696 00000 n
+0001164416 00000 n
+0000007852 00000 n
+0000007896 00000 n
+0000453505 00000 n
+0001164323 00000 n
+0000007951 00000 n
+0000007991 00000 n
+0000456304 00000 n
+0001164230 00000 n
+0000008046 00000 n
+0000008114 00000 n
+0000456433 00000 n
+0001164151 00000 n
+0000008169 00000 n
0000008240 00000 n
-0000457350 00000 n
-0001003677 00000 n
-0000008295 00000 n
-0000008358 00000 n
-0000457479 00000 n
-0001003584 00000 n
-0000008413 00000 n
-0000008465 00000 n
-0000457608 00000 n
-0001003491 00000 n
-0000008520 00000 n
-0000008585 00000 n
-0000457737 00000 n
-0001003398 00000 n
-0000008640 00000 n
-0000008692 00000 n
-0000463748 00000 n
-0001003265 00000 n
-0000008747 00000 n
-0000008812 00000 n
-0000472151 00000 n
-0001003186 00000 n
-0000008872 00000 n
-0000008916 00000 n
-0000493407 00000 n
-0001003093 00000 n
-0000008976 00000 n
-0000009015 00000 n
-0000493536 00000 n
-0001003000 00000 n
-0000009075 00000 n
-0000009122 00000 n
-0000493665 00000 n
-0001002907 00000 n
-0000009182 00000 n
-0000009225 00000 n
-0000500581 00000 n
-0001002814 00000 n
-0000009285 00000 n
-0000009324 00000 n
-0000504097 00000 n
-0001002721 00000 n
-0000009384 00000 n
-0000009426 00000 n
-0000507277 00000 n
-0001002628 00000 n
-0000009486 00000 n
-0000009529 00000 n
-0000514841 00000 n
-0001002535 00000 n
-0000009589 00000 n
-0000009632 00000 n
-0000514970 00000 n
-0001002442 00000 n
-0000009692 00000 n
-0000009753 00000 n
-0000519163 00000 n
-0001002349 00000 n
-0000009814 00000 n
-0000009866 00000 n
-0000523056 00000 n
-0001002256 00000 n
+0000460499 00000 n
+0001164033 00000 n
+0000008290 00000 n
+0000008337 00000 n
+0000460628 00000 n
+0001163954 00000 n
+0000008392 00000 n
+0000008453 00000 n
+0000460757 00000 n
+0001163875 00000 n
+0000008508 00000 n
+0000008578 00000 n
+0000463625 00000 n
+0001163742 00000 n
+0000008625 00000 n
+0000008678 00000 n
+0000463754 00000 n
+0001163663 00000 n
+0000008727 00000 n
+0000008783 00000 n
+0000463883 00000 n
+0001163584 00000 n
+0000008832 00000 n
+0000008881 00000 n
+0000468153 00000 n
+0001163451 00000 n
+0000008928 00000 n
+0000008980 00000 n
+0000468282 00000 n
+0001163333 00000 n
+0000009029 00000 n
+0000009080 00000 n
+0000472974 00000 n
+0001163215 00000 n
+0000009134 00000 n
+0000009179 00000 n
+0000473102 00000 n
+0001163136 00000 n
+0000009238 00000 n
+0000009272 00000 n
+0000476695 00000 n
+0001163057 00000 n
+0000009331 00000 n
+0000009379 00000 n
+0000476824 00000 n
+0001162939 00000 n
+0000009433 00000 n
+0000009473 00000 n
+0000476953 00000 n
+0001162860 00000 n
+0000009532 00000 n
+0000009566 00000 n
+0000479805 00000 n
+0001162781 00000 n
+0000009625 00000 n
+0000009673 00000 n
+0000479934 00000 n
+0001162648 00000 n
+0000009722 00000 n
+0000009772 00000 n
+0000483004 00000 n
+0001162569 00000 n
+0000009826 00000 n
+0000009873 00000 n
+0000483132 00000 n
+0001162476 00000 n
0000009927 00000 n
-0000009980 00000 n
-0000523185 00000 n
-0001002163 00000 n
+0000009987 00000 n
+0000483391 00000 n
+0001162383 00000 n
0000010041 00000 n
-0000010079 00000 n
-0000527219 00000 n
-0001002070 00000 n
-0000010140 00000 n
-0000010192 00000 n
-0000530375 00000 n
-0001001977 00000 n
-0000010253 00000 n
-0000010297 00000 n
-0000534314 00000 n
-0001001884 00000 n
-0000010358 00000 n
-0000010394 00000 n
-0000542730 00000 n
-0001001791 00000 n
-0000010455 00000 n
-0000010518 00000 n
-0000542859 00000 n
-0001001698 00000 n
-0000010579 00000 n
-0000010629 00000 n
-0000546041 00000 n
-0001001619 00000 n
-0000010690 00000 n
-0000010746 00000 n
-0000549267 00000 n
-0001001526 00000 n
-0000010801 00000 n
-0000010852 00000 n
-0000554329 00000 n
-0001001433 00000 n
-0000010907 00000 n
-0000010971 00000 n
-0000558052 00000 n
-0001001340 00000 n
-0000011026 00000 n
+0000010093 00000 n
+0000488573 00000 n
+0001162290 00000 n
+0000010147 00000 n
+0000010212 00000 n
+0000488702 00000 n
+0001162197 00000 n
+0000010266 00000 n
+0000010317 00000 n
+0000492179 00000 n
+0001162104 00000 n
+0000010371 00000 n
+0000010435 00000 n
+0000492308 00000 n
+0001162011 00000 n
+0000010489 00000 n
+0000010536 00000 n
+0000492437 00000 n
+0001161918 00000 n
+0000010590 00000 n
+0000010650 00000 n
+0000492566 00000 n
+0001161825 00000 n
+0000010704 00000 n
+0000010755 00000 n
+0000496584 00000 n
+0001161693 00000 n
+0000010810 00000 n
+0000010875 00000 n
+0000496713 00000 n
+0001161614 00000 n
+0000010935 00000 n
+0000010982 00000 n
+0000503534 00000 n
+0001161521 00000 n
+0000011042 00000 n
0000011090 00000 n
-0000558180 00000 n
-0001001247 00000 n
-0000011145 00000 n
-0000011222 00000 n
-0000558309 00000 n
-0001001154 00000 n
-0000011277 00000 n
-0000011334 00000 n
-0000558437 00000 n
-0001001061 00000 n
-0000011389 00000 n
-0000011459 00000 n
-0000562254 00000 n
-0001000968 00000 n
-0000011514 00000 n
-0000011563 00000 n
-0000562383 00000 n
-0001000875 00000 n
-0000011618 00000 n
-0000011680 00000 n
-0000564065 00000 n
-0001000782 00000 n
-0000011735 00000 n
-0000011784 00000 n
-0000567156 00000 n
-0001000664 00000 n
-0000011839 00000 n
-0000011901 00000 n
-0000567284 00000 n
-0001000585 00000 n
-0000011961 00000 n
-0000012000 00000 n
-0000576166 00000 n
-0001000492 00000 n
-0000012060 00000 n
-0000012094 00000 n
-0000576295 00000 n
-0001000399 00000 n
-0000012154 00000 n
-0000012195 00000 n
-0000592451 00000 n
-0001000320 00000 n
-0000012255 00000 n
-0000012307 00000 n
-0000595699 00000 n
-0001000188 00000 n
-0000012356 00000 n
-0000012389 00000 n
-0000595827 00000 n
-0001000070 00000 n
-0000012443 00000 n
-0000012515 00000 n
-0000595955 00000 n
-0000999991 00000 n
-0000012574 00000 n
-0000012618 00000 n
-0000607186 00000 n
-0000999912 00000 n
-0000012677 00000 n
-0000012730 00000 n
-0000610897 00000 n
-0000999819 00000 n
-0000012784 00000 n
-0000012834 00000 n
-0000611156 00000 n
-0000999726 00000 n
-0000012888 00000 n
-0000012926 00000 n
-0000614299 00000 n
-0000999633 00000 n
-0000012980 00000 n
-0000013029 00000 n
-0000614558 00000 n
-0000999501 00000 n
-0000013083 00000 n
-0000013135 00000 n
-0000614687 00000 n
-0000999422 00000 n
-0000013194 00000 n
-0000013239 00000 n
-0000614816 00000 n
-0000999329 00000 n
-0000013298 00000 n
-0000013350 00000 n
-0000617602 00000 n
-0000999236 00000 n
-0000013409 00000 n
-0000013462 00000 n
-0000617730 00000 n
-0000999157 00000 n
-0000013521 00000 n
-0000013570 00000 n
-0000617859 00000 n
-0000999064 00000 n
-0000013624 00000 n
-0000013704 00000 n
-0000622193 00000 n
-0000998985 00000 n
-0000013758 00000 n
-0000013807 00000 n
-0000622322 00000 n
-0000998867 00000 n
-0000013856 00000 n
-0000013896 00000 n
-0000625918 00000 n
-0000998788 00000 n
-0000013955 00000 n
-0000014002 00000 n
-0000626047 00000 n
-0000998670 00000 n
-0000014056 00000 n
-0000014101 00000 n
-0000629692 00000 n
-0000998591 00000 n
-0000014160 00000 n
-0000014219 00000 n
-0000632705 00000 n
-0000998498 00000 n
-0000014278 00000 n
-0000014342 00000 n
-0000632963 00000 n
-0000998405 00000 n
-0000014401 00000 n
-0000014457 00000 n
-0000636831 00000 n
-0000998312 00000 n
-0000014516 00000 n
-0000014574 00000 n
-0000638438 00000 n
-0000998233 00000 n
-0000014633 00000 n
+0000509939 00000 n
+0001161442 00000 n
+0000011150 00000 n
+0000011204 00000 n
+0000513027 00000 n
+0001161349 00000 n
+0000011259 00000 n
+0000011309 00000 n
+0000515884 00000 n
+0001161256 00000 n
+0000011364 00000 n
+0000011427 00000 n
+0000516013 00000 n
+0001161163 00000 n
+0000011482 00000 n
+0000011534 00000 n
+0000516141 00000 n
+0001161070 00000 n
+0000011589 00000 n
+0000011654 00000 n
+0000516269 00000 n
+0001160977 00000 n
+0000011709 00000 n
+0000011761 00000 n
+0000521189 00000 n
+0001160844 00000 n
+0000011816 00000 n
+0000011881 00000 n
+0000541024 00000 n
+0001160765 00000 n
+0000011941 00000 n
+0000011985 00000 n
+0000562621 00000 n
+0001160672 00000 n
+0000012045 00000 n
+0000012084 00000 n
+0000566256 00000 n
+0001160579 00000 n
+0000012144 00000 n
+0000012191 00000 n
+0000566385 00000 n
+0001160486 00000 n
+0000012251 00000 n
+0000012294 00000 n
+0000570803 00000 n
+0001160393 00000 n
+0000012354 00000 n
+0000012393 00000 n
+0000574151 00000 n
+0001160300 00000 n
+0000012453 00000 n
+0000012495 00000 n
+0000580978 00000 n
+0001160207 00000 n
+0000012555 00000 n
+0000012598 00000 n
+0000588866 00000 n
+0001160114 00000 n
+0000012658 00000 n
+0000012701 00000 n
+0000588995 00000 n
+0001160021 00000 n
+0000012761 00000 n
+0000012822 00000 n
+0000593028 00000 n
+0001159928 00000 n
+0000012883 00000 n
+0000012935 00000 n
+0000593157 00000 n
+0001159835 00000 n
+0000012996 00000 n
+0000013049 00000 n
+0000596321 00000 n
+0001159742 00000 n
+0000013110 00000 n
+0000013148 00000 n
+0000600259 00000 n
+0001159649 00000 n
+0000013209 00000 n
+0000013261 00000 n
+0000603551 00000 n
+0001159556 00000 n
+0000013322 00000 n
+0000013366 00000 n
+0000603809 00000 n
+0001159463 00000 n
+0000013427 00000 n
+0000013463 00000 n
+0000612635 00000 n
+0001159370 00000 n
+0000013524 00000 n
+0000013587 00000 n
+0000615981 00000 n
+0001159277 00000 n
+0000013648 00000 n
+0000013698 00000 n
+0000619742 00000 n
+0001159184 00000 n
+0000013759 00000 n
+0000013815 00000 n
+0000624070 00000 n
+0001159091 00000 n
+0000013876 00000 n
+0000013923 00000 n
+0000628370 00000 n
+0001159012 00000 n
+0000013984 00000 n
+0000014052 00000 n
+0000630938 00000 n
+0001158919 00000 n
+0000014107 00000 n
+0000014158 00000 n
+0000635461 00000 n
+0001158826 00000 n
+0000014213 00000 n
+0000014277 00000 n
+0000639146 00000 n
+0001158733 00000 n
+0000014332 00000 n
+0000014396 00000 n
+0000639275 00000 n
+0001158640 00000 n
+0000014451 00000 n
+0000014528 00000 n
+0000639403 00000 n
+0001158547 00000 n
+0000014583 00000 n
+0000014640 00000 n
+0000643560 00000 n
+0001158454 00000 n
0000014695 00000 n
-0000640286 00000 n
-0000998100 00000 n
-0000014742 00000 n
-0000014794 00000 n
-0000640415 00000 n
-0000998021 00000 n
-0000014843 00000 n
-0000014887 00000 n
-0000644614 00000 n
-0000997889 00000 n
-0000014936 00000 n
-0000014977 00000 n
-0000644743 00000 n
-0000997810 00000 n
-0000015031 00000 n
-0000015079 00000 n
-0000644871 00000 n
-0000997731 00000 n
-0000015133 00000 n
-0000015184 00000 n
-0000645000 00000 n
-0000997652 00000 n
-0000015233 00000 n
-0000015280 00000 n
-0000649267 00000 n
-0000997519 00000 n
+0000014765 00000 n
+0000643688 00000 n
+0001158361 00000 n
+0000014820 00000 n
+0000014877 00000 n
+0000643817 00000 n
+0001158268 00000 n
+0000014932 00000 n
+0000015002 00000 n
+0000648072 00000 n
+0001158175 00000 n
+0000015057 00000 n
+0000015106 00000 n
+0000648201 00000 n
+0001158082 00000 n
+0000015161 00000 n
+0000015223 00000 n
+0000650348 00000 n
+0001157989 00000 n
+0000015278 00000 n
0000015327 00000 n
-0000015364 00000 n
-0000649396 00000 n
-0000997401 00000 n
-0000015413 00000 n
-0000015452 00000 n
-0000649525 00000 n
-0000997336 00000 n
-0000015506 00000 n
-0000015584 00000 n
-0000649654 00000 n
-0000997243 00000 n
-0000015633 00000 n
-0000015700 00000 n
-0000649783 00000 n
-0000997164 00000 n
-0000015749 00000 n
-0000015794 00000 n
-0000653222 00000 n
-0000997031 00000 n
-0000015842 00000 n
-0000015874 00000 n
-0000653351 00000 n
-0000996913 00000 n
-0000015923 00000 n
-0000015962 00000 n
-0000653480 00000 n
-0000996848 00000 n
-0000016016 00000 n
-0000016077 00000 n
-0000657161 00000 n
-0000996716 00000 n
-0000016126 00000 n
-0000016183 00000 n
-0000657290 00000 n
-0000996651 00000 n
-0000016237 00000 n
-0000016286 00000 n
-0000657419 00000 n
-0000996533 00000 n
-0000016335 00000 n
-0000016397 00000 n
-0000657548 00000 n
-0000996454 00000 n
-0000016451 00000 n
-0000016506 00000 n
-0000681573 00000 n
-0000996361 00000 n
-0000016560 00000 n
-0000016601 00000 n
-0000681702 00000 n
-0000996282 00000 n
-0000016655 00000 n
-0000016707 00000 n
-0000684433 00000 n
-0000996162 00000 n
-0000016755 00000 n
-0000016789 00000 n
-0000684562 00000 n
-0000996083 00000 n
-0000016838 00000 n
-0000016865 00000 n
-0000702386 00000 n
-0000995990 00000 n
-0000016914 00000 n
-0000016942 00000 n
-0000709874 00000 n
-0000995897 00000 n
-0000016991 00000 n
-0000017031 00000 n
-0000712670 00000 n
-0000995804 00000 n
-0000017080 00000 n
-0000017123 00000 n
-0000718853 00000 n
-0000995711 00000 n
-0000017172 00000 n
-0000017209 00000 n
-0000725478 00000 n
-0000995618 00000 n
-0000017258 00000 n
-0000017297 00000 n
-0000737861 00000 n
-0000995525 00000 n
-0000017346 00000 n
-0000017385 00000 n
-0000740957 00000 n
-0000995432 00000 n
-0000017434 00000 n
-0000017473 00000 n
-0000747237 00000 n
-0000995339 00000 n
-0000017522 00000 n
-0000017551 00000 n
-0000757049 00000 n
-0000995246 00000 n
-0000017601 00000 n
-0000017634 00000 n
-0000771281 00000 n
-0000995153 00000 n
-0000017684 00000 n
-0000017713 00000 n
-0000774411 00000 n
-0000995060 00000 n
-0000017763 00000 n
-0000017797 00000 n
-0000780649 00000 n
-0000994981 00000 n
-0000017847 00000 n
-0000017884 00000 n
-0000018257 00000 n
-0000018379 00000 n
-0000283180 00000 n
-0000017937 00000 n
-0000283054 00000 n
-0000283117 00000 n
-0000990433 00000 n
-0000964490 00000 n
-0000990259 00000 n
-0000991458 00000 n
-0000019688 00000 n
-0000019881 00000 n
-0000019961 00000 n
-0000019998 00000 n
-0000020079 00000 n
-0000020203 00000 n
-0000020462 00000 n
-0000020821 00000 n
-0000020853 00000 n
-0000020947 00000 n
-0000021980 00000 n
-0000033116 00000 n
-0000098706 00000 n
-0000164296 00000 n
-0000229886 00000 n
-0000284604 00000 n
-0000284419 00000 n
-0000283280 00000 n
-0000284541 00000 n
-0000963269 00000 n
-0000936748 00000 n
-0000963095 00000 n
-0000936063 00000 n
-0000933918 00000 n
-0000935899 00000 n
-0000296307 00000 n
-0000287653 00000 n
-0000284689 00000 n
-0000296181 00000 n
-0000296244 00000 n
-0000288187 00000 n
-0000288341 00000 n
-0000288498 00000 n
-0000288655 00000 n
-0000288812 00000 n
-0000288969 00000 n
-0000289131 00000 n
-0000289293 00000 n
-0000289454 00000 n
-0000289616 00000 n
-0000289783 00000 n
-0000289950 00000 n
-0000290115 00000 n
-0000290277 00000 n
-0000290443 00000 n
-0000290605 00000 n
-0000290759 00000 n
-0000290916 00000 n
-0000291073 00000 n
-0000291229 00000 n
-0000291385 00000 n
-0000291542 00000 n
-0000291697 00000 n
-0000291854 00000 n
-0000292016 00000 n
-0000292178 00000 n
-0000292335 00000 n
-0000292490 00000 n
-0000292651 00000 n
-0000292818 00000 n
-0000292985 00000 n
-0000293147 00000 n
-0000293302 00000 n
-0000293459 00000 n
-0000293616 00000 n
-0000293778 00000 n
-0000293935 00000 n
-0000294092 00000 n
-0000294253 00000 n
-0000294410 00000 n
-0000294572 00000 n
-0000294739 00000 n
-0000294906 00000 n
-0000295068 00000 n
-0000295230 00000 n
-0000295392 00000 n
-0000295554 00000 n
-0000295716 00000 n
-0000295871 00000 n
-0000296026 00000 n
-0000309682 00000 n
-0000299635 00000 n
-0000296392 00000 n
-0000309619 00000 n
-0000933367 00000 n
-0000916286 00000 n
-0000933183 00000 n
-0000300225 00000 n
-0000300388 00000 n
-0000300550 00000 n
-0000300712 00000 n
-0000300870 00000 n
-0000301033 00000 n
-0000301196 00000 n
-0000301351 00000 n
-0000301509 00000 n
-0000301667 00000 n
-0000301823 00000 n
-0000301981 00000 n
-0000302144 00000 n
-0000302312 00000 n
-0000302480 00000 n
-0000302643 00000 n
-0000302811 00000 n
-0000302979 00000 n
-0000303136 00000 n
-0000303299 00000 n
-0000303462 00000 n
-0000303625 00000 n
-0000303787 00000 n
-0000303950 00000 n
-0000304112 00000 n
-0000304274 00000 n
-0000304437 00000 n
-0000304600 00000 n
-0000304763 00000 n
-0000304931 00000 n
-0000305100 00000 n
-0000305269 00000 n
-0000305433 00000 n
-0000305597 00000 n
-0000305761 00000 n
-0000305925 00000 n
-0000306089 00000 n
-0000306253 00000 n
-0000306421 00000 n
-0000306590 00000 n
-0000306759 00000 n
-0000306928 00000 n
-0000307097 00000 n
-0000307266 00000 n
-0000307435 00000 n
-0000307604 00000 n
-0000307773 00000 n
-0000307943 00000 n
-0000308113 00000 n
-0000308282 00000 n
-0000308452 00000 n
-0000308622 00000 n
-0000308790 00000 n
-0000308959 00000 n
-0000309129 00000 n
-0000309296 00000 n
-0000309457 00000 n
-0000322857 00000 n
-0000313314 00000 n
-0000309780 00000 n
-0000322794 00000 n
-0000313888 00000 n
-0000314051 00000 n
-0000314214 00000 n
-0000314377 00000 n
-0000314540 00000 n
-0000314703 00000 n
-0000314866 00000 n
-0000315029 00000 n
-0000315192 00000 n
-0000315360 00000 n
-0000315528 00000 n
-0000315696 00000 n
-0000315864 00000 n
-0000316021 00000 n
-0000316181 00000 n
-0000316347 00000 n
-0000316514 00000 n
-0000316676 00000 n
-0000316838 00000 n
-0000317000 00000 n
-0000317162 00000 n
-0000317329 00000 n
-0000317496 00000 n
-0000317663 00000 n
-0000317830 00000 n
-0000317992 00000 n
-0000318154 00000 n
-0000318311 00000 n
-0000318478 00000 n
-0000318639 00000 n
-0000318806 00000 n
-0000318973 00000 n
-0000319140 00000 n
-0000915397 00000 n
-0000894066 00000 n
-0000915223 00000 n
-0000319307 00000 n
-0000319473 00000 n
-0000319628 00000 n
-0000319784 00000 n
-0000319940 00000 n
-0000320102 00000 n
-0000320264 00000 n
-0000320421 00000 n
-0000320576 00000 n
-0000320733 00000 n
-0000320895 00000 n
-0000321052 00000 n
-0000321209 00000 n
-0000321365 00000 n
-0000321522 00000 n
-0000321684 00000 n
-0000321841 00000 n
-0000322002 00000 n
-0000322157 00000 n
-0000322319 00000 n
-0000322480 00000 n
-0000322640 00000 n
-0000326277 00000 n
-0000323933 00000 n
-0000322968 00000 n
-0000326214 00000 n
-0000324171 00000 n
-0000324328 00000 n
-0000324485 00000 n
-0000324641 00000 n
-0000324798 00000 n
-0000324955 00000 n
-0000325112 00000 n
-0000325269 00000 n
-0000325426 00000 n
-0000325582 00000 n
-0000325740 00000 n
-0000893100 00000 n
-0000873133 00000 n
-0000892927 00000 n
-0000325898 00000 n
-0000326056 00000 n
-0000329377 00000 n
-0000328630 00000 n
-0000326375 00000 n
-0000328813 00000 n
-0000328938 00000 n
-0000329063 00000 n
-0000329188 00000 n
-0000329251 00000 n
-0000329314 00000 n
-0000872339 00000 n
-0000854022 00000 n
-0000872166 00000 n
-0000991576 00000 n
-0000333885 00000 n
-0000332768 00000 n
-0000329501 00000 n
-0000333262 00000 n
-0000333325 00000 n
-0000333449 00000 n
-0000333574 00000 n
-0000333699 00000 n
-0000332918 00000 n
-0000333111 00000 n
-0000333822 00000 n
-0000595891 00000 n
-0000657612 00000 n
-0000338540 00000 n
-0000337504 00000 n
-0000334009 00000 n
-0000337977 00000 n
-0000338102 00000 n
-0000337654 00000 n
-0000337816 00000 n
-0000338227 00000 n
-0000338352 00000 n
-0000338477 00000 n
-0000354470 00000 n
-0000341761 00000 n
-0000341201 00000 n
-0000338664 00000 n
-0000341323 00000 n
-0000341448 00000 n
-0000341573 00000 n
-0000341698 00000 n
-0000345190 00000 n
-0000344049 00000 n
-0000341872 00000 n
-0000344503 00000 n
-0000344628 00000 n
-0000344753 00000 n
-0000344878 00000 n
-0000345003 00000 n
-0000344199 00000 n
-0000344351 00000 n
-0000345127 00000 n
-0000546105 00000 n
-0000346274 00000 n
-0000345961 00000 n
-0000345275 00000 n
-0000346084 00000 n
-0000346210 00000 n
-0000348371 00000 n
-0000347668 00000 n
-0000346372 00000 n
-0000347794 00000 n
-0000347922 00000 n
-0000348049 00000 n
-0000348177 00000 n
-0000348306 00000 n
-0000991694 00000 n
-0000351303 00000 n
-0000350414 00000 n
-0000348470 00000 n
-0000350722 00000 n
-0000350851 00000 n
-0000350916 00000 n
-0000350981 00000 n
-0000350561 00000 n
-0000351110 00000 n
-0000351239 00000 n
-0000530439 00000 n
-0000354663 00000 n
-0000354215 00000 n
-0000351415 00000 n
-0000354341 00000 n
-0000853347 00000 n
-0000841358 00000 n
-0000853168 00000 n
-0000354598 00000 n
-0000358487 00000 n
-0000358296 00000 n
-0000354789 00000 n
-0000358422 00000 n
-0000840817 00000 n
-0000831071 00000 n
-0000840638 00000 n
-0000363097 00000 n
-0000362698 00000 n
-0000358653 00000 n
-0000363032 00000 n
-0000362845 00000 n
-0000431895 00000 n
-0000365442 00000 n
-0000364992 00000 n
-0000363236 00000 n
-0000365118 00000 n
-0000365247 00000 n
-0000365312 00000 n
-0000365377 00000 n
-0000368173 00000 n
-0000370720 00000 n
-0000368017 00000 n
-0000365567 00000 n
-0000370139 00000 n
-0000370268 00000 n
-0000370397 00000 n
+0000655852 00000 n
+0001157871 00000 n
+0000015382 00000 n
+0000015444 00000 n
+0000655980 00000 n
+0001157792 00000 n
+0000015504 00000 n
+0000015543 00000 n
+0000664901 00000 n
+0001157699 00000 n
+0000015603 00000 n
+0000015637 00000 n
+0000665030 00000 n
+0001157606 00000 n
+0000015697 00000 n
+0000015738 00000 n
+0000685657 00000 n
+0001157527 00000 n
+0000015798 00000 n
+0000015850 00000 n
+0000692639 00000 n
+0001157395 00000 n
+0000015899 00000 n
+0000015932 00000 n
+0000692768 00000 n
+0001157277 00000 n
+0000015986 00000 n
+0000016058 00000 n
+0000692897 00000 n
+0001157198 00000 n
+0000016117 00000 n
+0000016161 00000 n
+0000703499 00000 n
+0001157119 00000 n
+0000016220 00000 n
+0000016273 00000 n
+0000703888 00000 n
+0001157026 00000 n
+0000016327 00000 n
+0000016377 00000 n
+0000707742 00000 n
+0001156933 00000 n
+0000016431 00000 n
+0000016469 00000 n
+0000708001 00000 n
+0001156840 00000 n
+0000016523 00000 n
+0000016572 00000 n
+0000710774 00000 n
+0001156708 00000 n
+0000016626 00000 n
+0000016678 00000 n
+0000710899 00000 n
+0001156629 00000 n
+0000016737 00000 n
+0000016782 00000 n
+0000711028 00000 n
+0001156536 00000 n
+0000016841 00000 n
+0000016893 00000 n
+0000711157 00000 n
+0001156443 00000 n
+0000016952 00000 n
+0000017005 00000 n
+0000713609 00000 n
+0001156364 00000 n
+0000017064 00000 n
+0000017113 00000 n
+0000713738 00000 n
+0001156271 00000 n
+0000017167 00000 n
+0000017247 00000 n
+0000718053 00000 n
+0001156192 00000 n
+0000017301 00000 n
+0000017350 00000 n
+0000721558 00000 n
+0001156074 00000 n
+0000017399 00000 n
+0000017439 00000 n
+0000721817 00000 n
+0001155995 00000 n
+0000017498 00000 n
+0000017545 00000 n
+0000725249 00000 n
+0001155877 00000 n
+0000017599 00000 n
+0000017644 00000 n
+0000725378 00000 n
+0001155798 00000 n
+0000017703 00000 n
+0000017762 00000 n
+0000728733 00000 n
+0001155705 00000 n
+0000017821 00000 n
+0000017885 00000 n
+0000728992 00000 n
+0001155612 00000 n
+0000017944 00000 n
+0000018000 00000 n
+0000733149 00000 n
+0001155519 00000 n
+0000018059 00000 n
+0000018117 00000 n
+0000735170 00000 n
+0001155440 00000 n
+0000018176 00000 n
+0000018238 00000 n
+0000737334 00000 n
+0001155307 00000 n
+0000018285 00000 n
+0000018337 00000 n
+0000737463 00000 n
+0001155228 00000 n
+0000018386 00000 n
+0000018430 00000 n
+0000741498 00000 n
+0001155096 00000 n
+0000018479 00000 n
+0000018520 00000 n
+0000741627 00000 n
+0001155017 00000 n
+0000018574 00000 n
+0000018622 00000 n
+0000741755 00000 n
+0001154938 00000 n
+0000018676 00000 n
+0000018727 00000 n
+0000741884 00000 n
+0001154859 00000 n
+0000018776 00000 n
+0000018823 00000 n
+0000746483 00000 n
+0001154726 00000 n
+0000018870 00000 n
+0000018907 00000 n
+0000746612 00000 n
+0001154608 00000 n
+0000018956 00000 n
+0000018995 00000 n
+0000746741 00000 n
+0001154543 00000 n
+0000019049 00000 n
+0000019127 00000 n
+0000746870 00000 n
+0001154450 00000 n
+0000019176 00000 n
+0000019243 00000 n
+0000746999 00000 n
+0001154371 00000 n
+0000019292 00000 n
+0000019337 00000 n
+0000750440 00000 n
+0001154238 00000 n
+0000019385 00000 n
+0000019417 00000 n
+0000750569 00000 n
+0001154120 00000 n
+0000019466 00000 n
+0000019505 00000 n
+0000750698 00000 n
+0001154055 00000 n
+0000019559 00000 n
+0000019620 00000 n
+0000754380 00000 n
+0001153923 00000 n
+0000019669 00000 n
+0000019726 00000 n
+0000754509 00000 n
+0001153858 00000 n
+0000019780 00000 n
+0000019829 00000 n
+0000754638 00000 n
+0001153726 00000 n
+0000019878 00000 n
+0000019940 00000 n
+0000754767 00000 n
+0001153647 00000 n
+0000019994 00000 n
+0000020049 00000 n
+0000779610 00000 n
+0001153554 00000 n
+0000020103 00000 n
+0000020144 00000 n
+0000779739 00000 n
+0001153475 00000 n
+0000020198 00000 n
+0000020250 00000 n
+0000780128 00000 n
+0001153357 00000 n
+0000020299 00000 n
+0000020349 00000 n
+0000782950 00000 n
+0001153278 00000 n
+0000020403 00000 n
+0000020441 00000 n
+0000783079 00000 n
+0001153185 00000 n
+0000020495 00000 n
+0000020532 00000 n
+0000783208 00000 n
+0001153092 00000 n
+0000020586 00000 n
+0000020624 00000 n
+0000783337 00000 n
+0001152999 00000 n
+0000020678 00000 n
+0000020730 00000 n
+0000786573 00000 n
+0001152906 00000 n
+0000020784 00000 n
+0000020827 00000 n
+0000786701 00000 n
+0001152774 00000 n
+0000020881 00000 n
+0000020926 00000 n
+0000786829 00000 n
+0001152695 00000 n
+0000020985 00000 n
+0000021051 00000 n
+0000789815 00000 n
+0001152602 00000 n
+0000021110 00000 n
+0000021198 00000 n
+0000789944 00000 n
+0001152509 00000 n
+0000021257 00000 n
+0000021332 00000 n
+0000790073 00000 n
+0001152416 00000 n
+0000021391 00000 n
+0000021476 00000 n
+0000792981 00000 n
+0001152323 00000 n
+0000021535 00000 n
+0000021616 00000 n
+0000795442 00000 n
+0001152244 00000 n
+0000021675 00000 n
+0000021759 00000 n
+0000795571 00000 n
+0001152165 00000 n
+0000021813 00000 n
+0000021857 00000 n
+0000798400 00000 n
+0001152045 00000 n
+0000021905 00000 n
+0000021939 00000 n
+0000798529 00000 n
+0001151966 00000 n
+0000021988 00000 n
+0000022015 00000 n
+0000816495 00000 n
+0001151873 00000 n
+0000022064 00000 n
+0000022092 00000 n
+0000824044 00000 n
+0001151780 00000 n
+0000022141 00000 n
+0000022181 00000 n
+0000830319 00000 n
+0001151687 00000 n
+0000022230 00000 n
+0000022273 00000 n
+0000836854 00000 n
+0001151594 00000 n
+0000022322 00000 n
+0000022359 00000 n
+0000850093 00000 n
+0001151501 00000 n
+0000022408 00000 n
+0000022445 00000 n
+0000853117 00000 n
+0001151408 00000 n
+0000022494 00000 n
+0000022532 00000 n
+0000859767 00000 n
+0001151315 00000 n
+0000022581 00000 n
+0000022620 00000 n
+0000873231 00000 n
+0001151222 00000 n
+0000022669 00000 n
+0000022708 00000 n
+0000876250 00000 n
+0001151129 00000 n
+0000022758 00000 n
+0000022798 00000 n
+0000885745 00000 n
+0001151036 00000 n
+0000022848 00000 n
+0000022878 00000 n
+0000894551 00000 n
+0001150943 00000 n
+0000022928 00000 n
+0000022971 00000 n
+0000895005 00000 n
+0001150850 00000 n
+0000023021 00000 n
+0000023054 00000 n
+0000909263 00000 n
+0001150757 00000 n
+0000023104 00000 n
+0000023133 00000 n
+0000916463 00000 n
+0001150664 00000 n
+0000023183 00000 n
+0000023217 00000 n
+0000922445 00000 n
+0001150571 00000 n
+0000023267 00000 n
+0000023304 00000 n
+0000925715 00000 n
+0001150478 00000 n
+0000023354 00000 n
+0000023391 00000 n
+0000931198 00000 n
+0001150385 00000 n
+0000023441 00000 n
+0000023474 00000 n
+0000931651 00000 n
+0001150292 00000 n
+0000023524 00000 n
+0000023558 00000 n
+0000934599 00000 n
+0001150199 00000 n
+0000023608 00000 n
+0000023647 00000 n
+0000936747 00000 n
+0001150120 00000 n
+0000023697 00000 n
+0000023731 00000 n
+0000024104 00000 n
+0000024226 00000 n
+0000289027 00000 n
+0000023784 00000 n
+0000288901 00000 n
+0000288964 00000 n
+0001144529 00000 n
+0001118444 00000 n
+0001144355 00000 n
+0001145567 00000 n
+0000025535 00000 n
+0000025728 00000 n
+0000025808 00000 n
+0000025845 00000 n
+0000025926 00000 n
+0000026050 00000 n
+0000026309 00000 n
+0000026668 00000 n
+0000026700 00000 n
+0000026794 00000 n
+0000027827 00000 n
+0000038963 00000 n
+0000104553 00000 n
+0000170143 00000 n
+0000235733 00000 n
+0000290455 00000 n
+0000290270 00000 n
+0000289127 00000 n
+0000290392 00000 n
+0001117208 00000 n
+0001090589 00000 n
+0001117034 00000 n
+0001089904 00000 n
+0001087759 00000 n
+0001089740 00000 n
+0000302181 00000 n
+0000293506 00000 n
+0000290540 00000 n
+0000302055 00000 n
+0000302118 00000 n
+0000294052 00000 n
+0000294206 00000 n
+0000294363 00000 n
+0000294520 00000 n
+0000294677 00000 n
+0000294834 00000 n
+0000294996 00000 n
+0000295158 00000 n
+0000295319 00000 n
+0000295481 00000 n
+0000295648 00000 n
+0000295815 00000 n
+0000295980 00000 n
+0000296142 00000 n
+0000296308 00000 n
+0000296470 00000 n
+0000296624 00000 n
+0000296781 00000 n
+0000296938 00000 n
+0000297094 00000 n
+0000297250 00000 n
+0000297407 00000 n
+0000297562 00000 n
+0000297719 00000 n
+0000297881 00000 n
+0000298043 00000 n
+0000298200 00000 n
+0000298355 00000 n
+0000298516 00000 n
+0000298683 00000 n
+0000298850 00000 n
+0000299011 00000 n
+0000299166 00000 n
+0000299323 00000 n
+0000299480 00000 n
+0000299642 00000 n
+0000299799 00000 n
+0000299956 00000 n
+0000300117 00000 n
+0000300275 00000 n
+0000300438 00000 n
+0000300606 00000 n
+0000300774 00000 n
+0000300937 00000 n
+0000301100 00000 n
+0000301263 00000 n
+0000301425 00000 n
+0000301588 00000 n
+0000301744 00000 n
+0000301900 00000 n
+0000315699 00000 n
+0000305636 00000 n
+0000302266 00000 n
+0000315634 00000 n
+0001087171 00000 n
+0001069750 00000 n
+0001086985 00000 n
+0000306286 00000 n
+0000306450 00000 n
+0000306613 00000 n
+0000306777 00000 n
+0000306936 00000 n
+0000307100 00000 n
+0000307264 00000 n
+0000307428 00000 n
+0000307592 00000 n
+0000307756 00000 n
+0000307920 00000 n
+0000308084 00000 n
+0000308248 00000 n
+0000308412 00000 n
+0000308577 00000 n
+0000308742 00000 n
+0000308907 00000 n
+0000309072 00000 n
+0000309232 00000 n
+0000309397 00000 n
+0000309561 00000 n
+0000309721 00000 n
+0000309886 00000 n
+0000310056 00000 n
+0000310226 00000 n
+0000310391 00000 n
+0000310560 00000 n
+0000310729 00000 n
+0000310894 00000 n
+0000311059 00000 n
+0000311223 00000 n
+0000311388 00000 n
+0000311548 00000 n
+0000311713 00000 n
+0000311878 00000 n
+0000312034 00000 n
+0000312193 00000 n
+0000312352 00000 n
+0000312509 00000 n
+0000312668 00000 n
+0000312832 00000 n
+0000313001 00000 n
+0000313170 00000 n
+0000313334 00000 n
+0000313503 00000 n
+0000313672 00000 n
+0000313831 00000 n
+0000313995 00000 n
+0000314159 00000 n
+0000314323 00000 n
+0000314487 00000 n
+0000314651 00000 n
+0000314815 00000 n
+0000314978 00000 n
+0000315142 00000 n
+0000315304 00000 n
+0000315466 00000 n
+0000329835 00000 n
+0000319302 00000 n
+0000315799 00000 n
+0000329770 00000 n
+0000319970 00000 n
+0000320139 00000 n
+0000320307 00000 n
+0000320471 00000 n
+0000320634 00000 n
+0000320798 00000 n
+0000320962 00000 n
+0000321126 00000 n
+0000321290 00000 n
+0000321459 00000 n
+0000321627 00000 n
+0000321796 00000 n
+0000321965 00000 n
+0000322133 00000 n
+0000322302 00000 n
+0000322471 00000 n
+0000322639 00000 n
+0000322808 00000 n
+0000322978 00000 n
+0000323147 00000 n
+0000323317 00000 n
+0000323487 00000 n
+0000323657 00000 n
+0000323827 00000 n
+0000323997 00000 n
+0000324167 00000 n
+0000324337 00000 n
+0000324507 00000 n
+0000324676 00000 n
+0000324840 00000 n
+0000325003 00000 n
+0000325167 00000 n
+0000325331 00000 n
+0000325495 00000 n
+0000325659 00000 n
+0000325823 00000 n
+0000325986 00000 n
+0000326150 00000 n
+0000326314 00000 n
+0000326477 00000 n
+0000326641 00000 n
+0000326809 00000 n
+0000326978 00000 n
+0000327147 00000 n
+0000327316 00000 n
+0000327473 00000 n
+0000327636 00000 n
+0000327804 00000 n
+0000327971 00000 n
+0000328134 00000 n
+0000328296 00000 n
+0000328459 00000 n
+0000328622 00000 n
+0000328790 00000 n
+0000328958 00000 n
+0000329126 00000 n
+0000329293 00000 n
+0000329454 00000 n
+0000329614 00000 n
+0000342999 00000 n
+0000333429 00000 n
+0000329935 00000 n
+0000342934 00000 n
+0000334061 00000 n
+0000334229 00000 n
+0000334392 00000 n
+0000334560 00000 n
+0000334728 00000 n
+0000334896 00000 n
+0001068859 00000 n
+0001047525 00000 n
+0001068683 00000 n
+0000335064 00000 n
+0000335231 00000 n
+0000335387 00000 n
+0000335545 00000 n
+0000335703 00000 n
+0000335866 00000 n
+0000336029 00000 n
+0000336187 00000 n
+0000336343 00000 n
+0000336501 00000 n
+0000336664 00000 n
+0000336822 00000 n
+0000336980 00000 n
+0000337136 00000 n
+0000337294 00000 n
+0000337457 00000 n
+0000337615 00000 n
+0000337778 00000 n
+0000337935 00000 n
+0000338097 00000 n
+0000338260 00000 n
+0000338423 00000 n
+0000338581 00000 n
+0000338744 00000 n
+0000338907 00000 n
+0000339070 00000 n
+0000339233 00000 n
+0000339396 00000 n
+0000339559 00000 n
+0000339727 00000 n
+0000339895 00000 n
+0000340062 00000 n
+0000340228 00000 n
+0000340395 00000 n
+0000340562 00000 n
+0000340725 00000 n
+0000340882 00000 n
+0000341040 00000 n
+0000341198 00000 n
+0000341356 00000 n
+0000341514 00000 n
+0000341672 00000 n
+0000341830 00000 n
+0000341988 00000 n
+0000342146 00000 n
+0000342304 00000 n
+0000342463 00000 n
+0000342620 00000 n
+0000342777 00000 n
+0000345400 00000 n
+0000343854 00000 n
+0000343113 00000 n
+0000345335 00000 n
+0000344064 00000 n
+0001046557 00000 n
+0001026587 00000 n
+0001046382 00000 n
+0000344223 00000 n
+0000344382 00000 n
+0000344540 00000 n
+0000344699 00000 n
+0000344858 00000 n
+0000345017 00000 n
+0000345176 00000 n
+0001145688 00000 n
+0000348523 00000 n
+0000347756 00000 n
+0000345501 00000 n
+0000347944 00000 n
+0000348072 00000 n
+0000348200 00000 n
+0000348328 00000 n
+0000348393 00000 n
+0000348458 00000 n
+0001025770 00000 n
+0001007305 00000 n
+0001025595 00000 n
+0000353060 00000 n
+0000351919 00000 n
+0000348651 00000 n
+0000352421 00000 n
+0000352486 00000 n
+0000352613 00000 n
+0000352741 00000 n
+0000352869 00000 n
+0000352075 00000 n
+0000352269 00000 n
+0000352995 00000 n
+0000692832 00000 n
+0000754831 00000 n
+0000357742 00000 n
+0000356684 00000 n
+0000353188 00000 n
+0000357165 00000 n
+0000357293 00000 n
+0000356840 00000 n
+0000357003 00000 n
+0000357421 00000 n
+0000357549 00000 n
+0000357677 00000 n
+0000373539 00000 n
+0000360983 00000 n
+0000360408 00000 n
+0000357870 00000 n
+0000360534 00000 n
+0000360662 00000 n
+0000360790 00000 n
+0000360918 00000 n
+0000364441 00000 n
+0000363275 00000 n
+0000361097 00000 n
+0000363737 00000 n
+0000363865 00000 n
+0000363993 00000 n
+0000364121 00000 n
+0000364249 00000 n
+0000363431 00000 n
+0000363584 00000 n
+0000364376 00000 n
+0000619806 00000 n
+0000365518 00000 n
+0000365199 00000 n
+0000364527 00000 n
+0000365325 00000 n
+0000365453 00000 n
+0001145813 00000 n
+0000367561 00000 n
+0000366858 00000 n
+0000365618 00000 n
+0000366984 00000 n
+0000367112 00000 n
+0000367239 00000 n
+0000367367 00000 n
+0000367496 00000 n
+0000370140 00000 n
+0000369510 00000 n
+0000367661 00000 n
0000369816 00000 n
-0000369978 00000 n
-0000830173 00000 n
-0000820377 00000 n
-0000829999 00000 n
-0000819813 00000 n
-0000810727 00000 n
-0000819638 00000 n
-0000370526 00000 n
-0000370655 00000 n
-0000991819 00000 n
-0000369645 00000 n
-0000369703 00000 n
-0000369793 00000 n
-0000472215 00000 n
-0000507341 00000 n
-0000375384 00000 n
-0000374449 00000 n
-0000370876 00000 n
-0000374933 00000 n
-0000375062 00000 n
-0000374605 00000 n
-0000374771 00000 n
-0000375191 00000 n
-0000375320 00000 n
-0000661639 00000 n
-0000379043 00000 n
-0000378663 00000 n
-0000375536 00000 n
-0000378978 00000 n
-0000378810 00000 n
-0000380266 00000 n
-0000380075 00000 n
-0000379168 00000 n
-0000380201 00000 n
-0000382969 00000 n
-0000382391 00000 n
-0000380365 00000 n
-0000382517 00000 n
-0000382646 00000 n
-0000382775 00000 n
-0000382904 00000 n
-0000386147 00000 n
-0000385440 00000 n
-0000383107 00000 n
-0000385566 00000 n
-0000385695 00000 n
-0000385824 00000 n
-0000385953 00000 n
-0000386082 00000 n
-0000390455 00000 n
-0000389557 00000 n
-0000386272 00000 n
-0000389875 00000 n
-0000390004 00000 n
-0000389704 00000 n
-0000390133 00000 n
-0000390262 00000 n
-0000390390 00000 n
-0000991944 00000 n
-0000592515 00000 n
-0000394491 00000 n
-0000393913 00000 n
-0000390580 00000 n
-0000394039 00000 n
-0000394168 00000 n
-0000394297 00000 n
-0000394426 00000 n
-0000398086 00000 n
-0000397766 00000 n
-0000394629 00000 n
-0000397892 00000 n
-0000398021 00000 n
-0000401532 00000 n
-0000401032 00000 n
-0000398198 00000 n
-0000401338 00000 n
-0000810452 00000 n
-0000807094 00000 n
-0000810273 00000 n
-0000401467 00000 n
-0000401179 00000 n
-0000657354 00000 n
-0000403260 00000 n
-0000402813 00000 n
-0000401714 00000 n
-0000402939 00000 n
-0000403068 00000 n
-0000403195 00000 n
-0000403713 00000 n
-0000403522 00000 n
-0000403372 00000 n
-0000403648 00000 n
-0000406327 00000 n
-0000405749 00000 n
-0000403755 00000 n
-0000405875 00000 n
-0000406004 00000 n
-0000406133 00000 n
-0000406262 00000 n
-0000992069 00000 n
-0000406767 00000 n
-0000406576 00000 n
-0000406426 00000 n
-0000406702 00000 n
-0000410769 00000 n
-0000410003 00000 n
-0000406809 00000 n
-0000410317 00000 n
-0000410446 00000 n
-0000410574 00000 n
-0000410639 00000 n
-0000410704 00000 n
-0000410150 00000 n
-0000415267 00000 n
-0000415459 00000 n
-0000415012 00000 n
-0000410868 00000 n
-0000415138 00000 n
-0000415394 00000 n
-0000419338 00000 n
-0000418761 00000 n
-0000415584 00000 n
-0000418887 00000 n
-0000419015 00000 n
-0000419144 00000 n
-0000419273 00000 n
-0000422155 00000 n
-0000423534 00000 n
-0000422029 00000 n
-0000419476 00000 n
-0000423081 00000 n
-0000423210 00000 n
-0000423339 00000 n
-0000423404 00000 n
-0000423469 00000 n
-0000426611 00000 n
-0000425904 00000 n
-0000423689 00000 n
-0000426030 00000 n
-0000426159 00000 n
-0000426287 00000 n
-0000426352 00000 n
-0000426417 00000 n
-0000426546 00000 n
-0000992194 00000 n
-0000432218 00000 n
-0000431300 00000 n
-0000426723 00000 n
-0000431766 00000 n
-0000431456 00000 n
-0000431607 00000 n
-0000432024 00000 n
-0000432153 00000 n
-0000785720 00000 n
-0000436057 00000 n
-0000434786 00000 n
-0000432356 00000 n
-0000435476 00000 n
-0000435605 00000 n
-0000435734 00000 n
-0000434951 00000 n
-0000435103 00000 n
-0000435289 00000 n
-0000435863 00000 n
-0000435992 00000 n
-0000440288 00000 n
-0000439968 00000 n
-0000436183 00000 n
-0000440094 00000 n
-0000440223 00000 n
-0000443763 00000 n
-0000443384 00000 n
-0000440413 00000 n
-0000443698 00000 n
-0000443531 00000 n
-0000446780 00000 n
-0000446975 00000 n
-0000446525 00000 n
-0000443875 00000 n
-0000446651 00000 n
-0000446845 00000 n
-0000446910 00000 n
-0000450344 00000 n
-0000450153 00000 n
-0000447087 00000 n
-0000450279 00000 n
-0000992319 00000 n
-0000454655 00000 n
-0000454077 00000 n
-0000450456 00000 n
-0000454203 00000 n
-0000454332 00000 n
-0000454397 00000 n
-0000454462 00000 n
-0000454591 00000 n
-0000457866 00000 n
-0000456824 00000 n
-0000454767 00000 n
-0000457285 00000 n
-0000457414 00000 n
-0000456980 00000 n
-0000457132 00000 n
-0000457543 00000 n
-0000457672 00000 n
-0000457801 00000 n
-0000459418 00000 n
-0000459227 00000 n
-0000457978 00000 n
-0000459353 00000 n
-0000460953 00000 n
-0000460762 00000 n
-0000459517 00000 n
-0000460888 00000 n
-0000463877 00000 n
-0000463557 00000 n
-0000461052 00000 n
-0000463683 00000 n
-0000463812 00000 n
-0000468308 00000 n
-0000467939 00000 n
-0000464015 00000 n
-0000468243 00000 n
-0000468086 00000 n
-0000992444 00000 n
-0000625982 00000 n
-0000472280 00000 n
-0000471960 00000 n
-0000468420 00000 n
-0000472086 00000 n
-0000476118 00000 n
-0000475798 00000 n
-0000472405 00000 n
-0000475924 00000 n
-0000475989 00000 n
-0000476053 00000 n
-0000481414 00000 n
-0000480122 00000 n
-0000476243 00000 n
-0000481349 00000 n
-0000480314 00000 n
-0000480468 00000 n
-0000480623 00000 n
-0000480808 00000 n
-0000480982 00000 n
-0000481167 00000 n
-0000554393 00000 n
-0000485716 00000 n
-0000485525 00000 n
-0000481595 00000 n
-0000485651 00000 n
-0000489480 00000 n
-0000489289 00000 n
-0000485841 00000 n
-0000489415 00000 n
-0000493794 00000 n
-0000492851 00000 n
-0000489592 00000 n
-0000493342 00000 n
-0000493471 00000 n
-0000493007 00000 n
-0000493600 00000 n
-0000493729 00000 n
-0000493176 00000 n
-0000992569 00000 n
-0000564129 00000 n
-0000497456 00000 n
-0000496894 00000 n
-0000493906 00000 n
-0000497391 00000 n
-0000497050 00000 n
-0000497221 00000 n
-0000645064 00000 n
-0000500710 00000 n
-0000500390 00000 n
-0000497625 00000 n
+0000369945 00000 n
+0000370010 00000 n
+0000370075 00000 n
+0000369657 00000 n
+0000603615 00000 n
+0000373733 00000 n
+0000373028 00000 n
+0000370254 00000 n
+0000373154 00000 n
+0000373283 00000 n
+0000373410 00000 n
+0001006622 00000 n
+0000994560 00000 n
+0001006443 00000 n
+0000373668 00000 n
+0000378400 00000 n
+0000377330 00000 n
+0000373861 00000 n
+0000378335 00000 n
+0000993987 00000 n
+0000983054 00000 n
+0000993808 00000 n
+0000377513 00000 n
+0000377668 00000 n
+0000377839 00000 n
+0000378010 00000 n
+0000378165 00000 n
+0000521253 00000 n
+0000685721 00000 n
+0000381927 00000 n
+0000381736 00000 n
+0000378569 00000 n
+0000381862 00000 n
+0000386399 00000 n
+0000386002 00000 n
+0000382069 00000 n
+0000386334 00000 n
+0000386149 00000 n
+0001145938 00000 n
+0000488637 00000 n
+0000388602 00000 n
+0000388152 00000 n
+0000386555 00000 n
+0000388278 00000 n
+0000388407 00000 n
+0000388472 00000 n
+0000388537 00000 n
+0000389071 00000 n
+0000388880 00000 n
+0000388730 00000 n
+0000389006 00000 n
+0000391766 00000 n
+0000394356 00000 n
+0000391601 00000 n
+0000389113 00000 n
+0000393904 00000 n
+0000394033 00000 n
+0000394162 00000 n
+0000393409 00000 n
+0000393571 00000 n
+0000982148 00000 n
+0000972128 00000 n
+0000981974 00000 n
+0000971564 00000 n
+0000962478 00000 n
+0000971389 00000 n
+0000394291 00000 n
+0000393733 00000 n
+0000393238 00000 n
+0000393296 00000 n
+0000393386 00000 n
+0000541088 00000 n
+0000581042 00000 n
+0000399123 00000 n
+0000398187 00000 n
+0000394527 00000 n
+0000398671 00000 n
+0000398800 00000 n
+0000398929 00000 n
+0000398343 00000 n
+0000398509 00000 n
+0000399058 00000 n
+0000758863 00000 n
+0000403041 00000 n
+0000402532 00000 n
+0000399279 00000 n
+0000402847 00000 n
+0000402976 00000 n
+0000402679 00000 n
+0000404189 00000 n
+0000403998 00000 n
+0000403182 00000 n
+0000404124 00000 n
+0001146063 00000 n
+0000406055 00000 n
+0000405735 00000 n
+0000404290 00000 n
+0000405861 00000 n
+0000405990 00000 n
+0000409350 00000 n
+0000408515 00000 n
+0000406169 00000 n
+0000408641 00000 n
+0000408770 00000 n
+0000408899 00000 n
+0000409027 00000 n
+0000409156 00000 n
+0000409285 00000 n
+0000413404 00000 n
+0000412508 00000 n
+0000409492 00000 n
+0000412825 00000 n
+0000412954 00000 n
+0000413082 00000 n
+0000412655 00000 n
+0000413210 00000 n
+0000413339 00000 n
+0000417431 00000 n
+0000416853 00000 n
+0000413545 00000 n
+0000416979 00000 n
+0000417108 00000 n
+0000417237 00000 n
+0000417366 00000 n
+0000421358 00000 n
+0000420909 00000 n
+0000417573 00000 n
+0000421035 00000 n
+0000421164 00000 n
+0000421293 00000 n
+0000423671 00000 n
+0000423480 00000 n
+0000421486 00000 n
+0000423606 00000 n
+0001146188 00000 n
+0000426939 00000 n
+0000426361 00000 n
+0000423815 00000 n
+0000426487 00000 n
+0000962203 00000 n
+0000958846 00000 n
+0000962024 00000 n
+0000426616 00000 n
+0000426745 00000 n
+0000426874 00000 n
+0000431006 00000 n
+0000430199 00000 n
+0000427110 00000 n
+0000430684 00000 n
+0000430813 00000 n
+0000958491 00000 n
+0000956494 00000 n
+0000958326 00000 n
+0000430355 00000 n
+0000430519 00000 n
+0000430941 00000 n
+0000836918 00000 n
+0000853181 00000 n
+0000434543 00000 n
+0000433836 00000 n
+0000431134 00000 n
+0000433962 00000 n
+0000434091 00000 n
+0000434220 00000 n
+0000434349 00000 n
+0000434478 00000 n
+0000438230 00000 n
+0000436960 00000 n
+0000434657 00000 n
+0000437263 00000 n
+0000437392 00000 n
+0000437521 00000 n
+0000437650 00000 n
+0000437779 00000 n
+0000437908 00000 n
+0000438037 00000 n
+0000438166 00000 n
+0000437107 00000 n
+0000643881 00000 n
+0000441952 00000 n
+0000441503 00000 n
+0000438358 00000 n
+0000441629 00000 n
+0000441758 00000 n
+0000441887 00000 n
+0000444959 00000 n
+0000444639 00000 n
+0000442066 00000 n
+0000444765 00000 n
+0000444894 00000 n
+0001146313 00000 n
+0000447976 00000 n
+0000447527 00000 n
+0000445129 00000 n
+0000447653 00000 n
+0000447782 00000 n
+0000447911 00000 n
+0000450825 00000 n
+0000450118 00000 n
+0000448133 00000 n
+0000450244 00000 n
+0000450373 00000 n
+0000450502 00000 n
+0000450631 00000 n
+0000450760 00000 n
+0000453634 00000 n
+0000453314 00000 n
+0000450939 00000 n
+0000453440 00000 n
+0000453569 00000 n
+0000459347 00000 n
+0000456562 00000 n
+0000456113 00000 n
+0000453748 00000 n
+0000456239 00000 n
+0000456368 00000 n
+0000456497 00000 n
+0000460886 00000 n
+0000459200 00000 n
+0000456690 00000 n
+0000460434 00000 n
+0000460563 00000 n
+0000460273 00000 n
+0000460692 00000 n
+0000460821 00000 n
+0000754573 00000 n
+0000461398 00000 n
+0000461207 00000 n
+0000461057 00000 n
+0000461333 00000 n
+0001146438 00000 n
+0000464012 00000 n
+0000463434 00000 n
+0000461440 00000 n
+0000463560 00000 n
+0000463689 00000 n
+0000463818 00000 n
+0000463947 00000 n
+0000464453 00000 n
+0000464262 00000 n
+0000464112 00000 n
+0000464388 00000 n
+0000468540 00000 n
+0000467774 00000 n
+0000464495 00000 n
+0000468088 00000 n
+0000468217 00000 n
+0000468345 00000 n
+0000468410 00000 n
+0000468475 00000 n
+0000467921 00000 n
+0000473038 00000 n
+0000473230 00000 n
+0000472783 00000 n
+0000468640 00000 n
+0000472909 00000 n
+0000473165 00000 n
+0000477082 00000 n
+0000476504 00000 n
+0000473358 00000 n
+0000476630 00000 n
+0000476759 00000 n
+0000476888 00000 n
+0000477017 00000 n
+0000480192 00000 n
+0000479614 00000 n
+0000477223 00000 n
+0000479740 00000 n
+0000479869 00000 n
+0000479998 00000 n
+0000480063 00000 n
+0000480127 00000 n
+0001146563 00000 n
+0000483517 00000 n
+0000482813 00000 n
+0000480349 00000 n
+0000482939 00000 n
+0000483068 00000 n
+0000483196 00000 n
+0000483261 00000 n
+0000483326 00000 n
+0000483452 00000 n
+0000488830 00000 n
+0000488042 00000 n
+0000483631 00000 n
+0000488508 00000 n
+0000488198 00000 n
+0000488349 00000 n
+0000488766 00000 n
+0000937473 00000 n
+0000492695 00000 n
+0000491424 00000 n
+0000488971 00000 n
+0000492114 00000 n
+0000492243 00000 n
+0000492372 00000 n
+0000492501 00000 n
+0000491589 00000 n
+0000491741 00000 n
+0000491927 00000 n
+0000492630 00000 n
+0000496842 00000 n
+0000496393 00000 n
+0000492823 00000 n
+0000496519 00000 n
+0000496648 00000 n
+0000496777 00000 n
+0000500748 00000 n
+0000500369 00000 n
+0000496970 00000 n
+0000500683 00000 n
0000500516 00000 n
-0000500645 00000 n
-0000504226 00000 n
-0000503906 00000 n
-0000500835 00000 n
-0000504032 00000 n
-0000504161 00000 n
-0000507406 00000 n
-0000507086 00000 n
-0000504338 00000 n
-0000507212 00000 n
-0000511216 00000 n
-0000511025 00000 n
-0000507562 00000 n
-0000511151 00000 n
-0000515098 00000 n
-0000514469 00000 n
-0000511371 00000 n
-0000514776 00000 n
-0000514905 00000 n
-0000514616 00000 n
-0000515034 00000 n
-0000992694 00000 n
-0000519292 00000 n
-0000518613 00000 n
-0000515267 00000 n
-0000519098 00000 n
-0000518769 00000 n
-0000519227 00000 n
-0000518943 00000 n
-0000523314 00000 n
-0000522865 00000 n
-0000519404 00000 n
-0000522991 00000 n
-0000523120 00000 n
-0000523249 00000 n
-0000527347 00000 n
-0000526681 00000 n
-0000523469 00000 n
-0000527154 00000 n
-0000527283 00000 n
-0000526837 00000 n
-0000526999 00000 n
-0000530634 00000 n
-0000529995 00000 n
-0000527516 00000 n
-0000530310 00000 n
-0000530142 00000 n
-0000530504 00000 n
-0000530569 00000 n
-0000534443 00000 n
-0000533940 00000 n
-0000530760 00000 n
-0000534249 00000 n
-0000534378 00000 n
-0000534087 00000 n
-0000539058 00000 n
-0000538684 00000 n
-0000534625 00000 n
-0000538993 00000 n
-0000538831 00000 n
-0000806739 00000 n
-0000804741 00000 n
-0000806574 00000 n
-0000992819 00000 n
-0000622257 00000 n
-0000542988 00000 n
-0000542351 00000 n
-0000539184 00000 n
-0000542665 00000 n
-0000542794 00000 n
-0000542498 00000 n
-0000542923 00000 n
-0000562318 00000 n
-0000546169 00000 n
-0000545850 00000 n
-0000543113 00000 n
-0000545976 00000 n
-0000549396 00000 n
-0000549076 00000 n
-0000546337 00000 n
-0000549202 00000 n
-0000549331 00000 n
-0000554458 00000 n
-0000553796 00000 n
-0000549508 00000 n
-0000554264 00000 n
-0000553952 00000 n
-0000554104 00000 n
-0000558566 00000 n
-0000557687 00000 n
-0000554570 00000 n
-0000557987 00000 n
-0000558116 00000 n
-0000558244 00000 n
-0000558373 00000 n
-0000558501 00000 n
-0000557834 00000 n
-0000562512 00000 n
-0000562063 00000 n
-0000558678 00000 n
-0000562189 00000 n
-0000562447 00000 n
-0000992944 00000 n
-0000564194 00000 n
-0000563874 00000 n
-0000562624 00000 n
-0000564000 00000 n
-0000565754 00000 n
-0000565563 00000 n
-0000564306 00000 n
-0000565689 00000 n
-0000567473 00000 n
-0000566965 00000 n
-0000565853 00000 n
-0000567091 00000 n
-0000567220 00000 n
-0000567347 00000 n
-0000567410 00000 n
-0000571388 00000 n
-0000571132 00000 n
-0000567585 00000 n
-0000571258 00000 n
-0000571323 00000 n
-0000576424 00000 n
-0000574584 00000 n
-0000571500 00000 n
-0000576101 00000 n
-0000574794 00000 n
-0000576230 00000 n
-0000576359 00000 n
-0000574961 00000 n
-0000575122 00000 n
-0000575284 00000 n
-0000575446 00000 n
-0000575607 00000 n
-0000575768 00000 n
-0000575939 00000 n
-0000785687 00000 n
-0000581569 00000 n
-0000579821 00000 n
-0000576536 00000 n
-0000581504 00000 n
-0000580040 00000 n
-0000580203 00000 n
-0000580364 00000 n
-0000580524 00000 n
-0000580687 00000 n
-0000580849 00000 n
-0000581012 00000 n
-0000581174 00000 n
-0000581337 00000 n
-0000993069 00000 n
-0000587912 00000 n
-0000584338 00000 n
-0000581694 00000 n
-0000587847 00000 n
-0000584656 00000 n
-0000584825 00000 n
-0000584987 00000 n
-0000585149 00000 n
-0000585311 00000 n
-0000585473 00000 n
-0000585636 00000 n
-0000585789 00000 n
-0000585952 00000 n
-0000586105 00000 n
-0000586258 00000 n
-0000586409 00000 n
-0000586563 00000 n
-0000586725 00000 n
-0000586887 00000 n
-0000587049 00000 n
-0000587210 00000 n
-0000587372 00000 n
-0000587534 00000 n
-0000587695 00000 n
-0000592710 00000 n
-0000591581 00000 n
-0000588024 00000 n
-0000592386 00000 n
-0000591755 00000 n
-0000591918 00000 n
-0000592069 00000 n
-0000592232 00000 n
-0000592580 00000 n
-0000592645 00000 n
-0000596083 00000 n
-0000595508 00000 n
-0000592849 00000 n
-0000595634 00000 n
-0000595762 00000 n
-0000596019 00000 n
-0000600404 00000 n
-0000599591 00000 n
-0000596252 00000 n
-0000600079 00000 n
-0000599747 00000 n
-0000599917 00000 n
-0000600144 00000 n
-0000600209 00000 n
-0000600274 00000 n
-0000600339 00000 n
-0000603670 00000 n
-0000603349 00000 n
-0000600503 00000 n
-0000603475 00000 n
-0000603540 00000 n
-0000603605 00000 n
-0000607574 00000 n
-0000606995 00000 n
-0000603782 00000 n
-0000607121 00000 n
-0000607250 00000 n
-0000607315 00000 n
-0000607380 00000 n
-0000607444 00000 n
-0000607509 00000 n
-0000993194 00000 n
-0000611415 00000 n
-0000610706 00000 n
+0000503598 00000 n
+0000503793 00000 n
+0000503343 00000 n
+0000500862 00000 n
+0000503469 00000 n
+0000503663 00000 n
+0000503728 00000 n
+0001146688 00000 n
+0000506597 00000 n
+0000506406 00000 n
+0000503907 00000 n
+0000506532 00000 n
+0000510197 00000 n
+0000509748 00000 n
+0000506711 00000 n
+0000509874 00000 n
+0000510003 00000 n
+0000510068 00000 n
+0000510132 00000 n
+0000513155 00000 n
+0000512836 00000 n
+0000510311 00000 n
+0000512962 00000 n
+0000513090 00000 n
+0000516398 00000 n
+0000515358 00000 n
+0000513269 00000 n
+0000515819 00000 n
+0000515948 00000 n
+0000515514 00000 n
+0000515668 00000 n
+0000516076 00000 n
+0000516204 00000 n
+0000516333 00000 n
+0000517919 00000 n
+0000517728 00000 n
+0000516512 00000 n
+0000517854 00000 n
+0000519479 00000 n
+0000519288 00000 n
+0000518020 00000 n
+0000519414 00000 n
+0001146813 00000 n
+0000521317 00000 n
+0000520998 00000 n
+0000519580 00000 n
+0000521124 00000 n
+0000524735 00000 n
+0000524544 00000 n
+0000521431 00000 n
+0000524670 00000 n
+0000529206 00000 n
+0000528838 00000 n
+0000524863 00000 n
+0000529141 00000 n
+0000528985 00000 n
+0000721881 00000 n
+0000533299 00000 n
+0000532918 00000 n
+0000529348 00000 n
+0000533234 00000 n
+0000533065 00000 n
+0000537534 00000 n
+0000537169 00000 n
+0000533427 00000 n
+0000537469 00000 n
+0000537316 00000 n
+0000541282 00000 n
+0000540833 00000 n
+0000537676 00000 n
+0000540959 00000 n
+0000541153 00000 n
+0000541217 00000 n
+0001146938 00000 n
+0000545583 00000 n
+0000545217 00000 n
+0000541410 00000 n
+0000545518 00000 n
+0000545364 00000 n
+0000550667 00000 n
+0000549534 00000 n
+0000545711 00000 n
+0000550602 00000 n
+0000549717 00000 n
+0000549873 00000 n
+0000550058 00000 n
+0000550232 00000 n
+0000550417 00000 n
+0000635525 00000 n
+0000554943 00000 n
+0000554752 00000 n
+0000550865 00000 n
+0000554878 00000 n
+0000558896 00000 n
+0000558705 00000 n
+0000555057 00000 n
+0000558831 00000 n
+0000562750 00000 n
+0000562430 00000 n
+0000559010 00000 n
+0000562556 00000 n
+0000562685 00000 n
+0000566514 00000 n
+0000565698 00000 n
+0000562864 00000 n
+0000566191 00000 n
+0000565854 00000 n
+0000566320 00000 n
+0000566449 00000 n
+0000566024 00000 n
+0001147063 00000 n
+0000650412 00000 n
+0000570932 00000 n
+0000570241 00000 n
+0000566671 00000 n
+0000570738 00000 n
+0000570397 00000 n
+0000570567 00000 n
+0000570867 00000 n
+0000741948 00000 n
+0000574280 00000 n
+0000573960 00000 n
+0000571060 00000 n
+0000574086 00000 n
+0000574215 00000 n
+0000577233 00000 n
+0000577042 00000 n
+0000574394 00000 n
+0000577168 00000 n
+0000581107 00000 n
+0000580787 00000 n
+0000577404 00000 n
+0000580913 00000 n
+0000584762 00000 n
+0000584571 00000 n
+0000581264 00000 n
+0000584697 00000 n
+0000589124 00000 n
+0000588312 00000 n
+0000584933 00000 n
+0000588801 00000 n
+0000588930 00000 n
+0000588468 00000 n
+0000589059 00000 n
+0000588628 00000 n
+0001147188 00000 n
+0000593286 00000 n
+0000592661 00000 n
+0000589281 00000 n
+0000592963 00000 n
+0000593092 00000 n
+0000592808 00000 n
+0000593221 00000 n
+0000596450 00000 n
+0000596130 00000 n
+0000593414 00000 n
+0000596256 00000 n
+0000596385 00000 n
+0000600387 00000 n
+0000599720 00000 n
+0000596621 00000 n
+0000600194 00000 n
+0000600323 00000 n
+0000599876 00000 n
+0000600038 00000 n
+0000603938 00000 n
+0000603169 00000 n
+0000600501 00000 n
+0000603486 00000 n
+0000603316 00000 n
+0000603680 00000 n
+0000603745 00000 n
+0000603873 00000 n
+0000607913 00000 n
+0000607539 00000 n
+0000604123 00000 n
+0000607848 00000 n
0000607686 00000 n
-0000610832 00000 n
-0000610961 00000 n
-0000611026 00000 n
-0000611091 00000 n
-0000611220 00000 n
-0000611285 00000 n
-0000611350 00000 n
-0000614945 00000 n
-0000614108 00000 n
-0000611540 00000 n
-0000614234 00000 n
-0000614363 00000 n
-0000614428 00000 n
-0000614493 00000 n
-0000614622 00000 n
-0000614751 00000 n
-0000614880 00000 n
-0000618118 00000 n
-0000617411 00000 n
-0000615155 00000 n
-0000617537 00000 n
-0000617666 00000 n
-0000617794 00000 n
-0000617923 00000 n
-0000617988 00000 n
-0000618053 00000 n
-0000622579 00000 n
-0000622002 00000 n
-0000618301 00000 n
-0000622128 00000 n
-0000622386 00000 n
-0000622451 00000 n
-0000622515 00000 n
-0000626176 00000 n
-0000625546 00000 n
-0000622704 00000 n
-0000625853 00000 n
-0000625693 00000 n
-0000626111 00000 n
-0000629951 00000 n
-0000629317 00000 n
-0000626288 00000 n
-0000629627 00000 n
-0000629756 00000 n
-0000629821 00000 n
-0000629886 00000 n
-0000629464 00000 n
-0000993319 00000 n
-0000785654 00000 n
-0000633220 00000 n
-0000632514 00000 n
-0000630063 00000 n
-0000632640 00000 n
-0000632769 00000 n
-0000632834 00000 n
-0000632899 00000 n
-0000633027 00000 n
-0000633091 00000 n
-0000633155 00000 n
-0000637089 00000 n
-0000636640 00000 n
-0000633332 00000 n
-0000636766 00000 n
-0000636895 00000 n
-0000636959 00000 n
-0000637024 00000 n
-0000638567 00000 n
-0000638247 00000 n
-0000637215 00000 n
-0000638373 00000 n
-0000804460 00000 n
-0000797176 00000 n
-0000804280 00000 n
-0000638502 00000 n
-0000640543 00000 n
-0000640095 00000 n
-0000638693 00000 n
-0000640221 00000 n
-0000640350 00000 n
-0000640479 00000 n
-0000645129 00000 n
-0000644186 00000 n
-0000640655 00000 n
-0000644549 00000 n
-0000796855 00000 n
-0000787642 00000 n
-0000796669 00000 n
-0000644333 00000 n
-0000644678 00000 n
-0000644806 00000 n
-0000644935 00000 n
-0000646171 00000 n
-0000645980 00000 n
-0000645366 00000 n
-0000646106 00000 n
-0000993444 00000 n
-0000646598 00000 n
-0000646407 00000 n
-0000646257 00000 n
-0000646533 00000 n
-0000649911 00000 n
-0000648685 00000 n
-0000646640 00000 n
-0000649202 00000 n
-0000649331 00000 n
-0000649460 00000 n
-0000649589 00000 n
-0000649718 00000 n
-0000649847 00000 n
-0000648841 00000 n
-0000649013 00000 n
-0000650365 00000 n
-0000650174 00000 n
-0000650024 00000 n
-0000650300 00000 n
-0000653609 00000 n
-0000653031 00000 n
-0000650407 00000 n
-0000653157 00000 n
-0000653286 00000 n
-0000653415 00000 n
-0000653544 00000 n
-0000657804 00000 n
-0000656586 00000 n
-0000653695 00000 n
-0000657096 00000 n
-0000657225 00000 n
-0000657483 00000 n
-0000656742 00000 n
-0000656921 00000 n
-0000657676 00000 n
-0000657740 00000 n
-0000664691 00000 n
-0000660863 00000 n
-0000657957 00000 n
-0000660989 00000 n
-0000661054 00000 n
-0000661119 00000 n
-0000661184 00000 n
-0000661249 00000 n
-0000661314 00000 n
-0000661379 00000 n
-0000661444 00000 n
-0000661509 00000 n
-0000661574 00000 n
-0000661704 00000 n
-0000661769 00000 n
-0000661834 00000 n
-0000661899 00000 n
-0000661964 00000 n
-0000662029 00000 n
-0000662094 00000 n
-0000662159 00000 n
-0000662224 00000 n
-0000662289 00000 n
-0000662354 00000 n
-0000662419 00000 n
-0000662484 00000 n
-0000662549 00000 n
-0000662614 00000 n
-0000662679 00000 n
-0000662744 00000 n
-0000662809 00000 n
-0000662874 00000 n
-0000662939 00000 n
-0000663004 00000 n
-0000663069 00000 n
-0000663134 00000 n
-0000663199 00000 n
-0000663263 00000 n
-0000663328 00000 n
-0000663393 00000 n
-0000663458 00000 n
-0000663523 00000 n
-0000663588 00000 n
-0000663653 00000 n
-0000663718 00000 n
-0000663783 00000 n
-0000663848 00000 n
-0000663913 00000 n
-0000663978 00000 n
-0000664043 00000 n
-0000664108 00000 n
-0000664173 00000 n
-0000664238 00000 n
-0000664303 00000 n
-0000664368 00000 n
-0000664433 00000 n
-0000664498 00000 n
-0000664563 00000 n
-0000664627 00000 n
-0000993569 00000 n
-0000671337 00000 n
-0000667773 00000 n
-0000664803 00000 n
-0000667899 00000 n
-0000667964 00000 n
-0000668029 00000 n
-0000668094 00000 n
-0000668159 00000 n
-0000668224 00000 n
-0000668289 00000 n
-0000668354 00000 n
-0000668419 00000 n
-0000668484 00000 n
-0000668549 00000 n
-0000668614 00000 n
-0000668678 00000 n
-0000668743 00000 n
-0000668808 00000 n
-0000668873 00000 n
-0000668938 00000 n
-0000669003 00000 n
-0000669068 00000 n
-0000669133 00000 n
-0000669198 00000 n
-0000669263 00000 n
-0000669328 00000 n
-0000669393 00000 n
-0000669457 00000 n
-0000669522 00000 n
-0000669587 00000 n
-0000669652 00000 n
-0000669717 00000 n
-0000669782 00000 n
-0000669847 00000 n
-0000669912 00000 n
-0000669977 00000 n
-0000670042 00000 n
-0000670107 00000 n
-0000670172 00000 n
-0000670237 00000 n
-0000670302 00000 n
-0000670367 00000 n
-0000670432 00000 n
-0000670496 00000 n
-0000670560 00000 n
-0000670624 00000 n
-0000670689 00000 n
-0000670754 00000 n
-0000670819 00000 n
-0000670884 00000 n
-0000670949 00000 n
-0000671014 00000 n
-0000671079 00000 n
-0000671144 00000 n
-0000671209 00000 n
-0000671273 00000 n
-0000677513 00000 n
-0000674075 00000 n
-0000671449 00000 n
-0000674201 00000 n
-0000674266 00000 n
-0000674331 00000 n
-0000674396 00000 n
-0000674461 00000 n
-0000674526 00000 n
-0000674591 00000 n
-0000674656 00000 n
-0000674721 00000 n
-0000674786 00000 n
-0000674851 00000 n
-0000674916 00000 n
-0000674981 00000 n
-0000675046 00000 n
-0000675111 00000 n
-0000675176 00000 n
-0000675241 00000 n
-0000675306 00000 n
-0000675371 00000 n
-0000675436 00000 n
-0000675501 00000 n
-0000675566 00000 n
-0000675631 00000 n
-0000675696 00000 n
-0000675761 00000 n
-0000675826 00000 n
-0000675891 00000 n
-0000675956 00000 n
-0000676021 00000 n
-0000676086 00000 n
-0000676151 00000 n
-0000676216 00000 n
-0000676281 00000 n
-0000676346 00000 n
-0000676410 00000 n
-0000676475 00000 n
-0000676540 00000 n
-0000676605 00000 n
-0000676670 00000 n
-0000676735 00000 n
-0000676800 00000 n
-0000676865 00000 n
-0000676930 00000 n
-0000676995 00000 n
-0000677060 00000 n
-0000677125 00000 n
-0000677190 00000 n
-0000677255 00000 n
-0000677320 00000 n
-0000677385 00000 n
-0000677449 00000 n
-0000682091 00000 n
-0000679827 00000 n
-0000677625 00000 n
-0000679953 00000 n
-0000680018 00000 n
-0000680083 00000 n
-0000680148 00000 n
-0000680213 00000 n
-0000680278 00000 n
-0000680343 00000 n
-0000680408 00000 n
-0000680473 00000 n
-0000680538 00000 n
-0000680603 00000 n
-0000680668 00000 n
-0000680733 00000 n
-0000680798 00000 n
-0000680860 00000 n
-0000680924 00000 n
-0000680989 00000 n
-0000681053 00000 n
-0000681118 00000 n
-0000681183 00000 n
-0000681248 00000 n
-0000681313 00000 n
-0000681378 00000 n
-0000681443 00000 n
-0000681508 00000 n
-0000681637 00000 n
-0000681766 00000 n
-0000681831 00000 n
-0000681896 00000 n
-0000681961 00000 n
-0000682026 00000 n
-0000684886 00000 n
-0000684242 00000 n
-0000682216 00000 n
-0000684368 00000 n
-0000684497 00000 n
-0000684626 00000 n
-0000684691 00000 n
-0000684756 00000 n
-0000684821 00000 n
-0000689225 00000 n
-0000688905 00000 n
-0000684999 00000 n
-0000689031 00000 n
-0000689096 00000 n
-0000689161 00000 n
-0000692825 00000 n
-0000692570 00000 n
-0000689378 00000 n
-0000692696 00000 n
-0000692761 00000 n
-0000993694 00000 n
-0000696073 00000 n
-0000695882 00000 n
-0000692964 00000 n
-0000696008 00000 n
-0000699802 00000 n
-0000699546 00000 n
-0000696199 00000 n
-0000699672 00000 n
-0000699737 00000 n
-0000702643 00000 n
-0000701935 00000 n
-0000699941 00000 n
-0000702061 00000 n
-0000702126 00000 n
-0000702191 00000 n
-0000702256 00000 n
-0000702321 00000 n
-0000702450 00000 n
-0000702515 00000 n
-0000702579 00000 n
-0000707309 00000 n
-0000707053 00000 n
-0000702782 00000 n
-0000707179 00000 n
-0000707244 00000 n
-0000710261 00000 n
-0000709488 00000 n
-0000707435 00000 n
-0000709614 00000 n
-0000709679 00000 n
-0000709744 00000 n
-0000709809 00000 n
-0000709938 00000 n
-0000710003 00000 n
-0000710066 00000 n
-0000710131 00000 n
-0000710196 00000 n
-0000712863 00000 n
-0000712154 00000 n
-0000710414 00000 n
-0000712280 00000 n
-0000712345 00000 n
-0000712410 00000 n
-0000712475 00000 n
-0000712540 00000 n
-0000712605 00000 n
-0000712734 00000 n
-0000712799 00000 n
-0000993819 00000 n
-0000716107 00000 n
-0000715721 00000 n
-0000713015 00000 n
-0000715847 00000 n
-0000715912 00000 n
-0000715977 00000 n
-0000716042 00000 n
-0000719241 00000 n
-0000718468 00000 n
-0000716247 00000 n
-0000718594 00000 n
-0000718659 00000 n
-0000718724 00000 n
-0000718788 00000 n
-0000718916 00000 n
-0000718981 00000 n
-0000719046 00000 n
-0000719111 00000 n
-0000719176 00000 n
-0000722628 00000 n
-0000722437 00000 n
-0000719407 00000 n
-0000722563 00000 n
-0000725737 00000 n
-0000725027 00000 n
-0000722754 00000 n
-0000725153 00000 n
-0000725218 00000 n
-0000725283 00000 n
-0000725348 00000 n
-0000725413 00000 n
-0000725542 00000 n
-0000725607 00000 n
-0000725672 00000 n
-0000729289 00000 n
-0000728968 00000 n
-0000725902 00000 n
-0000729094 00000 n
-0000729159 00000 n
-0000729224 00000 n
-0000732735 00000 n
-0000732544 00000 n
-0000729415 00000 n
-0000732670 00000 n
-0000993944 00000 n
-0000735807 00000 n
-0000735488 00000 n
-0000732861 00000 n
-0000735614 00000 n
-0000735679 00000 n
-0000735743 00000 n
-0000738378 00000 n
-0000737540 00000 n
-0000735960 00000 n
-0000737666 00000 n
-0000737731 00000 n
-0000737796 00000 n
-0000737925 00000 n
-0000737990 00000 n
-0000738055 00000 n
-0000738120 00000 n
-0000738185 00000 n
-0000738249 00000 n
-0000738314 00000 n
-0000741345 00000 n
-0000740701 00000 n
-0000738531 00000 n
-0000740827 00000 n
-0000740892 00000 n
-0000741021 00000 n
-0000741086 00000 n
-0000741150 00000 n
-0000741215 00000 n
-0000741280 00000 n
-0000744817 00000 n
-0000744626 00000 n
-0000741485 00000 n
-0000744752 00000 n
-0000747625 00000 n
-0000746851 00000 n
-0000744943 00000 n
-0000746977 00000 n
-0000747042 00000 n
-0000747107 00000 n
-0000747172 00000 n
-0000747301 00000 n
-0000747366 00000 n
-0000747431 00000 n
-0000747495 00000 n
-0000747560 00000 n
-0000751027 00000 n
-0000750836 00000 n
-0000747778 00000 n
-0000750962 00000 n
-0000994069 00000 n
-0000754063 00000 n
-0000753743 00000 n
-0000751238 00000 n
-0000753869 00000 n
-0000753934 00000 n
-0000753999 00000 n
-0000757373 00000 n
-0000756664 00000 n
-0000754287 00000 n
-0000756790 00000 n
-0000756855 00000 n
-0000756920 00000 n
-0000756984 00000 n
-0000757113 00000 n
-0000757178 00000 n
-0000757243 00000 n
-0000757308 00000 n
-0000761790 00000 n
-0000761534 00000 n
-0000757525 00000 n
-0000761660 00000 n
-0000761725 00000 n
-0000765404 00000 n
-0000765213 00000 n
-0000761916 00000 n
-0000765339 00000 n
-0000768186 00000 n
-0000767802 00000 n
-0000765530 00000 n
-0000767928 00000 n
-0000767993 00000 n
-0000768058 00000 n
-0000768122 00000 n
-0000771670 00000 n
-0000771025 00000 n
-0000768338 00000 n
-0000771151 00000 n
-0000771216 00000 n
-0000771345 00000 n
-0000771410 00000 n
-0000771475 00000 n
-0000771540 00000 n
-0000771605 00000 n
-0000994194 00000 n
-0000774735 00000 n
+0000612763 00000 n
+0000612086 00000 n
+0000608084 00000 n
+0000612570 00000 n
+0000612242 00000 n
+0000612699 00000 n
+0000612405 00000 n
+0001147313 00000 n
+0000718117 00000 n
+0000648136 00000 n
+0000616110 00000 n
+0000615790 00000 n
+0000612891 00000 n
+0000615916 00000 n
+0000616045 00000 n
+0000619871 00000 n
+0000619551 00000 n
+0000616237 00000 n
+0000619677 00000 n
+0000624199 00000 n
+0000623707 00000 n
+0000620028 00000 n
+0000624005 00000 n
+0000624134 00000 n
+0000623854 00000 n
+0000628499 00000 n
+0000628179 00000 n
+0000624327 00000 n
+0000628305 00000 n
+0000628434 00000 n
+0000631067 00000 n
+0000630747 00000 n
+0000628640 00000 n
+0000630873 00000 n
+0000631002 00000 n
+0000635590 00000 n
+0000635100 00000 n
+0000631181 00000 n
+0000635396 00000 n
+0000635247 00000 n
+0001147438 00000 n
+0000639531 00000 n
+0000638772 00000 n
+0000635704 00000 n
+0000639081 00000 n
+0000638919 00000 n
+0000639210 00000 n
+0000639339 00000 n
+0000639467 00000 n
+0000643946 00000 n
+0000643194 00000 n
+0000639645 00000 n
+0000643495 00000 n
+0000643624 00000 n
+0000643341 00000 n
+0000643752 00000 n
+0000648330 00000 n
+0000647881 00000 n
+0000644074 00000 n
+0000648007 00000 n
+0000648265 00000 n
+0000650477 00000 n
+0000650157 00000 n
+0000648472 00000 n
+0000650283 00000 n
+0000651970 00000 n
+0000651779 00000 n
+0000650591 00000 n
+0000651905 00000 n
+0000653427 00000 n
+0000653236 00000 n
+0000652071 00000 n
+0000653362 00000 n
+0001147563 00000 n
+0000656238 00000 n
+0000655661 00000 n
+0000653528 00000 n
+0000655787 00000 n
+0000655916 00000 n
+0000656043 00000 n
+0000656108 00000 n
+0000656173 00000 n
+0000659903 00000 n
+0000659712 00000 n
+0000656352 00000 n
+0000659838 00000 n
+0000665159 00000 n
+0000663316 00000 n
+0000660017 00000 n
+0000664836 00000 n
+0000663526 00000 n
+0000664965 00000 n
+0000665094 00000 n
+0000663694 00000 n
+0000663856 00000 n
+0000664018 00000 n
+0000664180 00000 n
+0000664342 00000 n
+0000664504 00000 n
+0000664675 00000 n
+0000937440 00000 n
+0000670438 00000 n
+0000668518 00000 n
+0000665273 00000 n
+0000670373 00000 n
+0000668746 00000 n
+0000668909 00000 n
+0000669072 00000 n
+0000669235 00000 n
+0000669397 00000 n
+0000669560 00000 n
+0000669722 00000 n
+0000669885 00000 n
+0000670044 00000 n
+0000670205 00000 n
+0000675059 00000 n
+0000673487 00000 n
+0000670566 00000 n
+0000674994 00000 n
+0000673697 00000 n
+0000673866 00000 n
+0000674028 00000 n
+0000674190 00000 n
+0000674352 00000 n
+0000674514 00000 n
+0000674677 00000 n
+0000674831 00000 n
+0000681361 00000 n
+0000678470 00000 n
+0000675187 00000 n
+0000681296 00000 n
+0000678752 00000 n
+0000678904 00000 n
+0000679058 00000 n
+0000679209 00000 n
+0000679363 00000 n
+0000679525 00000 n
+0000679687 00000 n
+0000679848 00000 n
+0000680010 00000 n
+0000680172 00000 n
+0000680334 00000 n
+0000680496 00000 n
+0000680649 00000 n
+0000680812 00000 n
+0000680967 00000 n
+0000681131 00000 n
+0001147688 00000 n
+0000685786 00000 n
+0000684948 00000 n
+0000681489 00000 n
+0000685592 00000 n
+0000685113 00000 n
+0000685276 00000 n
+0000685430 00000 n
+0000688940 00000 n
+0000688620 00000 n
+0000685928 00000 n
+0000688746 00000 n
+0000688811 00000 n
+0000688875 00000 n
+0000693156 00000 n
+0000692086 00000 n
+0000689111 00000 n
+0000692574 00000 n
+0000692703 00000 n
+0000692961 00000 n
+0000692242 00000 n
+0000692412 00000 n
+0000693026 00000 n
+0000693091 00000 n
+0000696607 00000 n
+0000696287 00000 n
+0000693284 00000 n
+0000696413 00000 n
+0000696478 00000 n
+0000696542 00000 n
+0000700096 00000 n
+0000699775 00000 n
+0000696708 00000 n
+0000699901 00000 n
+0000699966 00000 n
+0000700031 00000 n
+0000704017 00000 n
+0000703308 00000 n
+0000700211 00000 n
+0000703434 00000 n
+0000703563 00000 n
+0000703628 00000 n
+0000703693 00000 n
+0000703758 00000 n
+0000703823 00000 n
+0000703952 00000 n
+0001147813 00000 n
+0000708258 00000 n
+0000707421 00000 n
+0000704131 00000 n
+0000707547 00000 n
+0000707612 00000 n
+0000707677 00000 n
+0000707806 00000 n
+0000707871 00000 n
+0000707936 00000 n
+0000708065 00000 n
+0000708130 00000 n
+0000708194 00000 n
+0000711285 00000 n
+0000710583 00000 n
+0000708386 00000 n
+0000710709 00000 n
+0000710836 00000 n
+0000710963 00000 n
+0000711092 00000 n
+0000711220 00000 n
+0000713995 00000 n
+0000713418 00000 n
+0000711484 00000 n
+0000713544 00000 n
+0000713673 00000 n
+0000713802 00000 n
+0000713867 00000 n
+0000713931 00000 n
+0000718182 00000 n
+0000717862 00000 n
+0000714180 00000 n
+0000717988 00000 n
+0000721946 00000 n
+0000721186 00000 n
+0000718309 00000 n
+0000721493 00000 n
+0000721622 00000 n
+0000721687 00000 n
+0000721752 00000 n
+0000721333 00000 n
+0000725637 00000 n
+0000725058 00000 n
+0000722060 00000 n
+0000725184 00000 n
+0000725313 00000 n
+0000725442 00000 n
+0000725507 00000 n
+0000725572 00000 n
+0001147938 00000 n
+0000729251 00000 n
+0000728356 00000 n
+0000725751 00000 n
+0000728668 00000 n
+0000728503 00000 n
+0000728797 00000 n
+0000728862 00000 n
+0000728927 00000 n
+0000729056 00000 n
+0000729121 00000 n
+0000729186 00000 n
+0000937407 00000 n
+0000733408 00000 n
+0000732958 00000 n
+0000729365 00000 n
+0000733084 00000 n
+0000733213 00000 n
+0000733278 00000 n
+0000733343 00000 n
+0000735299 00000 n
+0000734979 00000 n
+0000733536 00000 n
+0000735105 00000 n
+0000956213 00000 n
+0000948929 00000 n
+0000956033 00000 n
+0000735234 00000 n
+0000735782 00000 n
+0000735591 00000 n
+0000735441 00000 n
+0000735717 00000 n
+0000737592 00000 n
+0000737143 00000 n
+0000735824 00000 n
+0000737269 00000 n
+0000737398 00000 n
+0000737527 00000 n
+0000742013 00000 n
+0000741070 00000 n
+0000737706 00000 n
+0000741433 00000 n
+0000948608 00000 n
+0000939395 00000 n
+0000948422 00000 n
+0000741217 00000 n
+0000741562 00000 n
+0000741690 00000 n
+0000741819 00000 n
+0001148063 00000 n
+0000743372 00000 n
+0000743181 00000 n
+0000742254 00000 n
+0000743307 00000 n
+0000743813 00000 n
+0000743622 00000 n
+0000743472 00000 n
+0000743748 00000 n
+0000747127 00000 n
+0000745901 00000 n
+0000743855 00000 n
+0000746418 00000 n
+0000746547 00000 n
+0000746676 00000 n
+0000746805 00000 n
+0000746934 00000 n
+0000747063 00000 n
+0000746057 00000 n
+0000746229 00000 n
+0000747582 00000 n
+0000747391 00000 n
+0000747241 00000 n
+0000747517 00000 n
+0000750827 00000 n
+0000750249 00000 n
+0000747624 00000 n
+0000750375 00000 n
+0000750504 00000 n
+0000750633 00000 n
+0000750762 00000 n
+0000755024 00000 n
+0000753805 00000 n
+0000750913 00000 n
+0000754315 00000 n
+0000754444 00000 n
+0000754702 00000 n
+0000753961 00000 n
+0000754140 00000 n
+0000754896 00000 n
+0000754960 00000 n
+0001148188 00000 n
+0000761915 00000 n
+0000758087 00000 n
+0000755180 00000 n
+0000758213 00000 n
+0000758278 00000 n
+0000758343 00000 n
+0000758408 00000 n
+0000758473 00000 n
+0000758538 00000 n
+0000758603 00000 n
+0000758668 00000 n
+0000758733 00000 n
+0000758798 00000 n
+0000758928 00000 n
+0000758993 00000 n
+0000759058 00000 n
+0000759123 00000 n
+0000759188 00000 n
+0000759253 00000 n
+0000759318 00000 n
+0000759383 00000 n
+0000759448 00000 n
+0000759513 00000 n
+0000759578 00000 n
+0000759643 00000 n
+0000759708 00000 n
+0000759773 00000 n
+0000759838 00000 n
+0000759903 00000 n
+0000759968 00000 n
+0000760033 00000 n
+0000760098 00000 n
+0000760163 00000 n
+0000760228 00000 n
+0000760293 00000 n
+0000760358 00000 n
+0000760423 00000 n
+0000760487 00000 n
+0000760552 00000 n
+0000760617 00000 n
+0000760682 00000 n
+0000760747 00000 n
+0000760812 00000 n
+0000760877 00000 n
+0000760942 00000 n
+0000761007 00000 n
+0000761072 00000 n
+0000761137 00000 n
+0000761202 00000 n
+0000761267 00000 n
+0000761332 00000 n
+0000761397 00000 n
+0000761462 00000 n
+0000761527 00000 n
+0000761592 00000 n
+0000761657 00000 n
+0000761722 00000 n
+0000761787 00000 n
+0000761851 00000 n
+0000768563 00000 n
+0000764999 00000 n
+0000762029 00000 n
+0000765125 00000 n
+0000765190 00000 n
+0000765255 00000 n
+0000765320 00000 n
+0000765385 00000 n
+0000765450 00000 n
+0000765515 00000 n
+0000765580 00000 n
+0000765645 00000 n
+0000765710 00000 n
+0000765775 00000 n
+0000765840 00000 n
+0000765904 00000 n
+0000765969 00000 n
+0000766034 00000 n
+0000766099 00000 n
+0000766164 00000 n
+0000766229 00000 n
+0000766294 00000 n
+0000766359 00000 n
+0000766424 00000 n
+0000766489 00000 n
+0000766554 00000 n
+0000766619 00000 n
+0000766683 00000 n
+0000766748 00000 n
+0000766813 00000 n
+0000766878 00000 n
+0000766943 00000 n
+0000767008 00000 n
+0000767073 00000 n
+0000767138 00000 n
+0000767203 00000 n
+0000767268 00000 n
+0000767333 00000 n
+0000767398 00000 n
+0000767463 00000 n
+0000767528 00000 n
+0000767593 00000 n
+0000767658 00000 n
+0000767722 00000 n
+0000767786 00000 n
+0000767850 00000 n
+0000767915 00000 n
+0000767980 00000 n
+0000768045 00000 n
+0000768110 00000 n
+0000768175 00000 n
+0000768240 00000 n
+0000768305 00000 n
+0000768370 00000 n
+0000768435 00000 n
+0000768499 00000 n
+0000774738 00000 n
+0000771300 00000 n
+0000768677 00000 n
+0000771426 00000 n
+0000771491 00000 n
+0000771556 00000 n
+0000771621 00000 n
+0000771686 00000 n
+0000771751 00000 n
+0000771816 00000 n
+0000771881 00000 n
+0000771946 00000 n
+0000772011 00000 n
+0000772076 00000 n
+0000772141 00000 n
+0000772206 00000 n
+0000772271 00000 n
+0000772336 00000 n
+0000772401 00000 n
+0000772466 00000 n
+0000772531 00000 n
+0000772596 00000 n
+0000772661 00000 n
+0000772726 00000 n
+0000772791 00000 n
+0000772856 00000 n
+0000772921 00000 n
+0000772986 00000 n
+0000773051 00000 n
+0000773116 00000 n
+0000773181 00000 n
+0000773246 00000 n
+0000773311 00000 n
+0000773376 00000 n
+0000773441 00000 n
+0000773506 00000 n
+0000773571 00000 n
+0000773635 00000 n
+0000773700 00000 n
+0000773765 00000 n
+0000773830 00000 n
+0000773895 00000 n
+0000773960 00000 n
0000774025 00000 n
-0000771810 00000 n
-0000774151 00000 n
-0000774216 00000 n
-0000774281 00000 n
-0000774346 00000 n
-0000774475 00000 n
-0000774540 00000 n
-0000774605 00000 n
-0000774670 00000 n
-0000777831 00000 n
-0000777575 00000 n
-0000774901 00000 n
-0000777701 00000 n
-0000777766 00000 n
-0000780973 00000 n
-0000780264 00000 n
-0000777957 00000 n
-0000780390 00000 n
-0000780455 00000 n
-0000780520 00000 n
-0000780585 00000 n
-0000780713 00000 n
-0000780778 00000 n
-0000780843 00000 n
-0000780908 00000 n
-0000784563 00000 n
-0000784242 00000 n
-0000781125 00000 n
-0000784368 00000 n
-0000784433 00000 n
-0000784498 00000 n
-0000785542 00000 n
-0000785221 00000 n
-0000784702 00000 n
-0000785347 00000 n
-0000785412 00000 n
-0000785477 00000 n
-0000785753 00000 n
-0000797097 00000 n
-0000804686 00000 n
-0000806986 00000 n
-0000806955 00000 n
-0000810672 00000 n
-0000820112 00000 n
-0000830619 00000 n
-0000841105 00000 n
-0000853729 00000 n
-0000872794 00000 n
-0000893681 00000 n
-0000915824 00000 n
-0000933719 00000 n
-0000936550 00000 n
-0000936320 00000 n
-0000963857 00000 n
-0000990968 00000 n
-0000994319 00000 n
-0000994443 00000 n
-0000994569 00000 n
-0000994695 00000 n
-0000994812 00000 n
-0000994904 00000 n
-0001011519 00000 n
-0001030788 00000 n
-0001030829 00000 n
-0001030869 00000 n
-0001031003 00000 n
+0000774090 00000 n
+0000774155 00000 n
+0000774220 00000 n
+0000774285 00000 n
+0000774350 00000 n
+0000774415 00000 n
+0000774480 00000 n
+0000774545 00000 n
+0000774610 00000 n
+0000774674 00000 n
+0000780257 00000 n
+0000777861 00000 n
+0000774852 00000 n
+0000777987 00000 n
+0000778052 00000 n
+0000778117 00000 n
+0000778182 00000 n
+0000778247 00000 n
+0000778312 00000 n
+0000778377 00000 n
+0000778442 00000 n
+0000778507 00000 n
+0000778572 00000 n
+0000778637 00000 n
+0000778702 00000 n
+0000778767 00000 n
+0000778831 00000 n
+0000778896 00000 n
+0000778961 00000 n
+0000779026 00000 n
+0000779091 00000 n
+0000779156 00000 n
+0000779221 00000 n
+0000779286 00000 n
+0000779351 00000 n
+0000779416 00000 n
+0000779481 00000 n
+0000779546 00000 n
+0000779674 00000 n
+0000779803 00000 n
+0000779868 00000 n
+0000779933 00000 n
+0000779998 00000 n
+0000780063 00000 n
+0000780192 00000 n
+0000783466 00000 n
+0000782759 00000 n
+0000780384 00000 n
+0000782885 00000 n
+0000783014 00000 n
+0000783143 00000 n
+0000783272 00000 n
+0000783401 00000 n
+0000786958 00000 n
+0000786201 00000 n
+0000783593 00000 n
+0000786508 00000 n
+0000786637 00000 n
+0000786348 00000 n
+0000786765 00000 n
+0000786893 00000 n
+0001148313 00000 n
+0000790202 00000 n
+0000789624 00000 n
+0000787085 00000 n
+0000789750 00000 n
+0000789879 00000 n
+0000790008 00000 n
+0000790137 00000 n
+0000793110 00000 n
+0000792790 00000 n
+0000790316 00000 n
+0000792916 00000 n
+0000793045 00000 n
+0000795700 00000 n
+0000795251 00000 n
+0000793280 00000 n
+0000795377 00000 n
+0000795506 00000 n
+0000795635 00000 n
+0000796141 00000 n
+0000795950 00000 n
+0000795800 00000 n
+0000796076 00000 n
+0000798853 00000 n
+0000798209 00000 n
+0000796183 00000 n
+0000798335 00000 n
+0000798464 00000 n
+0000798593 00000 n
+0000798658 00000 n
+0000798723 00000 n
+0000798788 00000 n
+0000803193 00000 n
+0000802873 00000 n
+0000798967 00000 n
+0000802999 00000 n
+0000803064 00000 n
+0000803129 00000 n
+0001148438 00000 n
+0000806796 00000 n
+0000806541 00000 n
+0000803349 00000 n
+0000806667 00000 n
+0000806732 00000 n
+0000810047 00000 n
+0000809856 00000 n
+0000806938 00000 n
+0000809982 00000 n
+0000813767 00000 n
+0000813511 00000 n
+0000810175 00000 n
+0000813637 00000 n
+0000813702 00000 n
+0000816752 00000 n
+0000816044 00000 n
+0000813909 00000 n
+0000816170 00000 n
+0000816235 00000 n
+0000816300 00000 n
+0000816365 00000 n
+0000816430 00000 n
+0000816559 00000 n
+0000816624 00000 n
+0000816688 00000 n
+0000821421 00000 n
+0000821165 00000 n
+0000816894 00000 n
+0000821291 00000 n
+0000821356 00000 n
+0000824431 00000 n
+0000823658 00000 n
+0000821549 00000 n
+0000823784 00000 n
+0000823849 00000 n
+0000823914 00000 n
+0000823979 00000 n
+0000824108 00000 n
+0000824173 00000 n
+0000824236 00000 n
+0000824301 00000 n
+0000824366 00000 n
+0001148563 00000 n
+0000827345 00000 n
+0000826830 00000 n
+0000824587 00000 n
+0000826956 00000 n
+0000827021 00000 n
+0000827086 00000 n
+0000827151 00000 n
+0000827216 00000 n
+0000827281 00000 n
+0000830708 00000 n
+0000830128 00000 n
+0000827501 00000 n
+0000830254 00000 n
+0000830383 00000 n
+0000830448 00000 n
+0000830513 00000 n
+0000830578 00000 n
+0000830643 00000 n
+0000834160 00000 n
+0000833904 00000 n
+0000830850 00000 n
+0000834030 00000 n
+0000834095 00000 n
+0000837112 00000 n
+0000836468 00000 n
+0000834288 00000 n
+0000836594 00000 n
+0000836659 00000 n
+0000836724 00000 n
+0000836789 00000 n
+0000836983 00000 n
+0000837048 00000 n
+0000840705 00000 n
+0000840384 00000 n
+0000837281 00000 n
+0000840510 00000 n
+0000840575 00000 n
+0000840640 00000 n
+0000844296 00000 n
+0000844105 00000 n
+0000840833 00000 n
+0000844231 00000 n
+0001148688 00000 n
+0000847762 00000 n
+0000847441 00000 n
+0000844424 00000 n
+0000847567 00000 n
+0000847632 00000 n
+0000847697 00000 n
+0000850416 00000 n
+0000849707 00000 n
+0000847903 00000 n
+0000849833 00000 n
+0000849898 00000 n
+0000849963 00000 n
+0000850028 00000 n
+0000850157 00000 n
+0000850222 00000 n
+0000850287 00000 n
+0000850352 00000 n
+0000853441 00000 n
+0000852732 00000 n
+0000850572 00000 n
+0000852858 00000 n
+0000852923 00000 n
+0000852987 00000 n
+0000853052 00000 n
+0000853246 00000 n
+0000853311 00000 n
+0000853376 00000 n
+0000856922 00000 n
+0000856601 00000 n
+0000853597 00000 n
+0000856727 00000 n
+0000856792 00000 n
+0000856857 00000 n
+0000860091 00000 n
+0000859381 00000 n
+0000857036 00000 n
+0000859507 00000 n
+0000859572 00000 n
+0000859637 00000 n
+0000859702 00000 n
+0000859831 00000 n
+0000859896 00000 n
+0000859961 00000 n
+0000860026 00000 n
+0000863741 00000 n
+0000863485 00000 n
+0000860247 00000 n
+0000863611 00000 n
+0000863676 00000 n
+0001148813 00000 n
+0000867398 00000 n
+0000867207 00000 n
+0000863883 00000 n
+0000867333 00000 n
+0000870723 00000 n
+0000870532 00000 n
+0000867526 00000 n
+0000870658 00000 n
+0000873552 00000 n
+0000872845 00000 n
+0000870865 00000 n
+0000872971 00000 n
+0000873036 00000 n
+0000873101 00000 n
+0000873166 00000 n
+0000873295 00000 n
+0000873358 00000 n
+0000873423 00000 n
+0000873488 00000 n
+0000876509 00000 n
+0000875799 00000 n
+0000873708 00000 n
+0000875925 00000 n
+0000875990 00000 n
+0000876055 00000 n
+0000876120 00000 n
+0000876185 00000 n
+0000876314 00000 n
+0000876379 00000 n
+0000876444 00000 n
+0000879808 00000 n
+0000879487 00000 n
+0000876665 00000 n
+0000879613 00000 n
+0000879678 00000 n
+0000879743 00000 n
+0000883039 00000 n
+0000882784 00000 n
+0000879950 00000 n
+0000882910 00000 n
+0000882975 00000 n
+0001148938 00000 n
+0000886134 00000 n
+0000885424 00000 n
+0000883167 00000 n
+0000885550 00000 n
+0000885615 00000 n
+0000885680 00000 n
+0000885809 00000 n
+0000885874 00000 n
+0000885939 00000 n
+0000886004 00000 n
+0000886069 00000 n
+0000889435 00000 n
+0000889244 00000 n
+0000886290 00000 n
+0000889370 00000 n
+0000892497 00000 n
+0000892112 00000 n
+0000889648 00000 n
+0000892238 00000 n
+0000892303 00000 n
+0000892368 00000 n
+0000892433 00000 n
+0000895198 00000 n
+0000894230 00000 n
+0000892738 00000 n
+0000894356 00000 n
+0000894421 00000 n
+0000894486 00000 n
+0000894615 00000 n
+0000894680 00000 n
+0000894745 00000 n
+0000894810 00000 n
+0000894875 00000 n
+0000894940 00000 n
+0000895069 00000 n
+0000895134 00000 n
+0000899701 00000 n
+0000899380 00000 n
+0000895340 00000 n
+0000899506 00000 n
+0000899571 00000 n
+0000899636 00000 n
+0000903445 00000 n
+0000903189 00000 n
+0000899829 00000 n
+0000903315 00000 n
+0000903380 00000 n
+0001149063 00000 n
+0000906877 00000 n
+0000906621 00000 n
+0000903573 00000 n
+0000906747 00000 n
+0000906812 00000 n
+0000909456 00000 n
+0000908878 00000 n
+0000907005 00000 n
+0000909004 00000 n
+0000909069 00000 n
+0000909134 00000 n
+0000909198 00000 n
+0000909327 00000 n
+0000909392 00000 n
+0000913457 00000 n
+0000913006 00000 n
+0000909611 00000 n
+0000913132 00000 n
+0000913197 00000 n
+0000913262 00000 n
+0000913327 00000 n
+0000913392 00000 n
+0000916787 00000 n
+0000916142 00000 n
+0000913599 00000 n
+0000916268 00000 n
+0000916333 00000 n
+0000916398 00000 n
+0000916527 00000 n
+0000916592 00000 n
+0000916657 00000 n
+0000916722 00000 n
+0000919348 00000 n
+0000919092 00000 n
+0000916943 00000 n
+0000919218 00000 n
+0000919283 00000 n
+0000922833 00000 n
+0000922059 00000 n
+0000919490 00000 n
+0000922185 00000 n
+0000922250 00000 n
+0000922315 00000 n
+0000922380 00000 n
+0000922508 00000 n
+0000922573 00000 n
+0000922638 00000 n
+0000922703 00000 n
+0000922768 00000 n
+0001149188 00000 n
+0000925908 00000 n
+0000925329 00000 n
+0000922989 00000 n
+0000925455 00000 n
+0000925520 00000 n
+0000925585 00000 n
+0000925650 00000 n
+0000925779 00000 n
+0000925844 00000 n
+0000929734 00000 n
+0000929286 00000 n
+0000926064 00000 n
+0000929412 00000 n
+0000929477 00000 n
+0000929542 00000 n
+0000929607 00000 n
+0000929671 00000 n
+0000931972 00000 n
+0000930942 00000 n
+0000929890 00000 n
+0000931068 00000 n
+0000931133 00000 n
+0000931262 00000 n
+0000931327 00000 n
+0000931392 00000 n
+0000931456 00000 n
+0000931521 00000 n
+0000931586 00000 n
+0000931715 00000 n
+0000931780 00000 n
+0000931845 00000 n
+0000931910 00000 n
+0000934986 00000 n
+0000934213 00000 n
+0000932114 00000 n
+0000934339 00000 n
+0000934404 00000 n
+0000934469 00000 n
+0000934534 00000 n
+0000934663 00000 n
+0000934727 00000 n
+0000934792 00000 n
+0000934857 00000 n
+0000934921 00000 n
+0000937265 00000 n
+0000936426 00000 n
+0000935128 00000 n
+0000936552 00000 n
+0000936617 00000 n
+0000936682 00000 n
+0000936810 00000 n
+0000936875 00000 n
+0000936940 00000 n
+0000937005 00000 n
+0000937070 00000 n
+0000937135 00000 n
+0000937200 00000 n
+0000937506 00000 n
+0000948850 00000 n
+0000956439 00000 n
+0000958738 00000 n
+0000958707 00000 n
+0000962423 00000 n
+0000971863 00000 n
+0000982598 00000 n
+0000994293 00000 n
+0001007010 00000 n
+0001026244 00000 n
+0001047140 00000 n
+0001069288 00000 n
+0001087544 00000 n
+0001090391 00000 n
+0001090161 00000 n
+0001117809 00000 n
+0001145075 00000 n
+0001149313 00000 n
+0001149438 00000 n
+0001149564 00000 n
+0001149690 00000 n
+0001149816 00000 n
+0001149942 00000 n
+0001150043 00000 n
+0001171759 00000 n
+0001195784 00000 n
+0001195825 00000 n
+0001195865 00000 n
+0001195999 00000 n
trailer
<<
-/Size 2169
-/Root 2167 0 R
-/Info 2168 0 R
-/ID [<0C97D45D411E72A60BD825BAD36788D6> <0C97D45D411E72A60BD825BAD36788D6>]
+/Size 2735
+/Root 2733 0 R
+/Info 2734 0 R
+/ID [<1DE9D6805D55864A9314F6997A97E945> <1DE9D6805D55864A9314F6997A97E945>]
>>
startxref
-1031261
+1196257
%%EOF
diff --git a/doc/arm/Makefile.in b/doc/arm/Makefile.in
index 5098528b71e3..d9eb8fe0d0ac 100644
--- a/doc/arm/Makefile.in
+++ b/doc/arm/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.20.332.2 2009-02-12 23:47:22 tbox Exp $
+# $Id: Makefile.in,v 1.22 2009-02-12 23:47:56 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/doc/arm/dnssec.xml b/doc/arm/dnssec.xml
new file mode 100644
index 000000000000..a678b8c7ec38
--- /dev/null
+++ b/doc/arm/dnssec.xml
@@ -0,0 +1,268 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ - Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.xml,v 1.4 2010-08-16 22:21:06 marka Exp $ -->
+
+<sect1 id="dnssec.dynamic.zones">
+ <title>DNSSEC, Dynamic Zones, and Automatic Signing</title>
+ <para>As of BIND 9.7.0 it is possible to change a dynamic zone
+ from insecure to signed and back again. A secure zone can use
+ either NSEC or NSEC3 chains.</para>
+ <sect2>
+ <title>Converting from insecure to secure</title>
+ </sect2>
+ <para>Changing a zone from insecure to secure can be done in two
+ ways: using a dynamic DNS update, or the
+ <command>auto-dnssec</command> zone option.</para>
+ <para>For either method, you need to configure
+ <command>named</command> so that it can see the
+ <filename>K*</filename> files which contain the public and private
+ parts of the keys that will be used to sign the zone. These files
+ will have been generated by
+ <command>dnssec-keygen</command>. You can do this by placing them
+ in the key-directory, as specified in
+ <filename>named.conf</filename>:</para>
+ <programlisting>
+ zone example.net {
+ type master;
+ update-policy local;
+ file "dynamic/example.net/example.net";
+ key-directory "dynamic/example.net";
+ };
+</programlisting>
+ <para>If one KSK and one ZSK DNSKEY key have been generated, this
+ configuration will cause all records in the zone to be signed
+ with the ZSK, and the DNSKEY RRset to be signed with the KSK as
+ well. An NSEC chain will be generated as part of the initial
+ signing process.</para>
+ <sect2>
+ <title>Dynamic DNS update method</title>
+ </sect2>
+ <para>To insert the keys via dynamic update:</para>
+ <screen>
+ % nsupdate
+ &gt; ttl 3600
+ &gt; update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
+ &gt; update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
+ &gt; send
+</screen>
+ <para>While the update request will complete almost immediately,
+ the zone will not be completely signed until
+ <command>named</command> has had time to walk the zone and
+ generate the NSEC and RRSIG records. The NSEC record at the apex
+ will be added last, to signal that there is a complete NSEC
+ chain.</para>
+ <para>If you wish to sign using NSEC3 instead of NSEC, you should
+ add an NSEC3PARAM record to the initial update request. If you
+ wish the NSEC3 chain to have the OPTOUT bit set, set it in the
+ flags field of the NSEC3PARAM record.</para>
+ <screen>
+ % nsupdate
+ &gt; ttl 3600
+ &gt; update add example.net DNSKEY 256 3 7 AwEAAZn17pUF0KpbPA2c7Gz76Vb18v0teKT3EyAGfBfL8eQ8al35zz3Y I1m/SAQBxIqMfLtIwqWPdgthsu36azGQAX8=
+ &gt; update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
+ &gt; update add example.net NSEC3PARAM 1 1 100 1234567890
+ &gt; send
+</screen>
+ <para>Again, this update request will complete almost
+ immediately; however, the record won't show up until
+ <command>named</command> has had a chance to build/remove the
+ relevant chain. A private type record will be created to record
+ the state of the operation (see below for more details), and will
+ be removed once the operation completes.</para>
+ <para>While the initial signing and NSEC/NSEC3 chain generation
+ is happening, other updates are possible as well.</para>
+ <sect2>
+ <title>Fully automatic zone signing</title>
+ </sect2>
+ <para>To enable automatic signing, add the
+ <command>auto-dnssec</command> option to the zone statement in
+ <filename>named.conf</filename>.
+ <command>auto-dnssec</command> has two possible arguments:
+ <constant>allow</constant> or
+ <constant>maintain</constant>.</para>
+ <para>With
+ <command>auto-dnssec allow</command>,
+ <command>named</command> can search the key directory for keys
+ matching the zone, insert them into the zone, and use them to
+ sign the zone. It will do so only when it receives an
+ <command>rndc sign &lt;zonename&gt;</command> or
+ <command>rndc loadkeys &lt;zonename&gt;</command> command.</para>
+ <para>
+ <!-- TODO: this is repeated in the ARM -->
+ <command>auto-dnssec maintain</command> includes the above
+ functionality, but will also automatically adjust the zone's
+ DNSKEY records on schedule according to the keys' timing metadata.
+ (See <xref linkend="man.dnssec-keygen"/> and
+ <xref linkend="man.dnssec-settime"/> for more information.)
+ If keys are present in the key directory the first time the zone
+ is loaded, it will be signed immediately, without waiting for an
+ <command>rndc sign</command> or <command>rndc loadkeys</command>
+ command. (Those commands can still be used when there are unscheduled
+ key changes, however.)
+ </para>
+ <para>Using the
+ <command>auto-dnssec</command> option requires the zone to be
+ configured to allow dynamic updates, by adding an
+ <command>allow-update</command> or
+ <command>update-policy</command> statement to the zone
+ configuration. If this has not been done, the configuration will
+ fail.</para>
+ <sect2>
+ <title>Private-type records</title>
+ </sect2>
+ <para>The state of the signing process is signaled by
+ private-type records (with a default type value of 65534). When
+ signing is complete, these records will have a nonzero value for
+ the final octet (for those records which have a nonzero initial
+ octet).</para>
+ <para>The private type record format: If the first octet is
+ non-zero then the record indicates that the zone needs to be
+ signed with the key matching the record, or that all signatures
+ that match the record should be removed.</para>
+ <para>
+ <literallayout>
+<!-- TODO: how to format this? -->
+ algorithm (octet 1)
+ key id in network order (octet 2 and 3)
+ removal flag (octet 4)
+ complete flag (octet 5)
+</literallayout>
+ </para>
+ <para>Only records flagged as "complete" can be removed via
+ dynamic update. Attempts to remove other private type records
+ will be silently ignored.</para>
+ <para>If the first octet is zero (this is a reserved algorithm
+ number that should never appear in a DNSKEY record) then the
+ record indicates changes to the NSEC3 chains are in progress. The
+ rest of the record contains an NSEC3PARAM record. The flag field
+ tells what operation to perform based on the flag bits.</para>
+ <para>
+ <literallayout>
+<!-- TODO: how to format this? -->
+ 0x01 OPTOUT
+ 0x80 CREATE
+ 0x40 REMOVE
+ 0x20 NONSEC
+</literallayout>
+ </para>
+ <sect2>
+ <title>DNSKEY rollovers</title>
+ </sect2>
+ <para>As with insecure-to-secure conversions, rolling DNSSEC
+ keys can be done in two ways: using a dynamic DNS update, or the
+ <command>auto-dnssec</command> zone option.</para>
+ <sect2>
+ <title>Dynamic DNS update method</title>
+ </sect2>
+ <para> To perform key rollovers via dynamic update, you need to add
+ the <filename>K*</filename> files for the new keys so that
+ <command>named</command> can find them. You can then add the new
+ DNSKEY RRs via dynamic update.
+ <command>named</command> will then cause the zone to be signed
+ with the new keys. When the signing is complete the private type
+ records will be updated so that the last octet is non
+ zero.</para>
+ <para>If this is for a KSK you need to inform the parent and any
+ trust anchor repositories of the new KSK.</para>
+ <para>You should then wait for the maximum TTL in the zone before
+ removing the old DNSKEY. If it is a KSK that is being updated,
+ you also need to wait for the DS RRset in the parent to be
+ updated and its TTL to expire. This ensures that all clients will
+ be able to verify at least one signature when you remove the old
+ DNSKEY.</para>
+ <para>The old DNSKEY can be removed via UPDATE. Take care to
+ specify the correct key.
+ <command>named</command> will clean out any signatures generated
+ by the old key after the update completes.</para>
+ <sect2>
+ <title>Automatic key rollovers</title>
+ </sect2>
+ <para>When a new key reaches its activation date (as set by
+ <command>dnssec-keygen</command> or <command>dnssec-settime</command>),
+ if the <command>auto-dnssec</command> zone option is set to
+ <constant>maintain</constant>, <command>named</command> will
+ automatically carry out the key rollover. If the key's algorithm
+ has not previously been used to sign the zone, then the zone will
+ be fully signed as quickly as possible. However, if the new key
+ is replacing an existing key of the same algorithm, then the
+ zone will be re-signed incrementally, with signatures from the
+ old key being replaced with signatures from the new key as their
+ signature validity periods expire. By default, this rollover
+ completes in 30 days, after which it will be safe to remove the
+ old key from the DNSKEY RRset.</para>
+ <sect2>
+ <title>NSEC3PARAM rollovers via UPDATE</title>
+ </sect2>
+ <para>Add the new NSEC3PARAM record via dynamic update. When the
+ new NSEC3 chain has been generated, the NSEC3PARAM flag field
+ will be zero. At this point you can remove the old NSEC3PARAM
+ record. The old chain will be removed after the update request
+ completes.</para>
+ <sect2>
+ <title>Converting from NSEC to NSEC3</title>
+ </sect2>
+ <para>To do this, you just need to add an NSEC3PARAM record. When
+ the conversion is complete, the NSEC chain will have been removed
+ and the NSEC3PARAM record will have a zero flag field. The NSEC3
+ chain will be generated before the NSEC chain is
+ destroyed.</para>
+ <sect2>
+ <title>Converting from NSEC3 to NSEC</title>
+ </sect2>
+ <para>To do this, use <command>nsupdate</command> to
+ remove all NSEC3PARAM records with a zero flag
+ field. The NSEC chain will be generated before the NSEC3 chain is
+ removed.</para>
+ <sect2>
+ <title>Converting from secure to insecure</title>
+ </sect2>
+ <para>To convert a signed zone to unsigned using dynamic DNS,
+ delete all the DNSKEY records from the zone apex using
+ <command>nsupdate</command>. All signatures, NSEC or NSEC3 chains,
+ and associated NSEC3PARAM records will be removed automatically.
+ This will take place after the update request completes.</para>
+ <para> This requires the
+ <command>dnssec-secure-to-insecure</command> option to be set to
+ <userinput>yes</userinput> in
+ <filename>named.conf</filename>.</para>
+ <para>In addition, if the <command>auto-dnssec maintain</command>
+ zone statement is used, it should be removed or changed to
+ <command>allow</command> instead (or it will re-sign).
+ </para>
+ <sect2>
+ <title>Periodic re-signing</title>
+ </sect2>
+ <para>In any secure zone which supports dynamic updates, named
+ will periodically re-sign RRsets which have not been re-signed as
+ a result of some update action. The signature lifetimes will be
+ adjusted so as to spread the re-sign load over time rather than
+ all at once.</para>
+ <sect2>
+ <title>NSEC3 and OPTOUT</title>
+ </sect2>
+ <para>
+ <command>named</command> only supports creating new NSEC3 chains
+ where all the NSEC3 records in the zone have the same OPTOUT
+ state.
+ <command>named</command> supports UPDATES to zones where the NSEC3
+ records in the chain have mixed OPTOUT state.
+ <command>named</command> does not support changing the OPTOUT
+ state of an individual NSEC3 record, the entire chain needs to be
+ changed if the OPTOUT state of an individual NSEC3 needs to be
+ changed.</para>
+</sect1>
diff --git a/doc/arm/libdns.xml b/doc/arm/libdns.xml
new file mode 100644
index 000000000000..8861f2ca45f7
--- /dev/null
+++ b/doc/arm/libdns.xml
@@ -0,0 +1,530 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ - Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<sect1 id="bind9.library">
+ <title>BIND 9 DNS Library Support</title>
+ <para>This version of BIND 9 "exports" its internal libraries so
+ that they can be used by third-party applications more easily (we
+ call them "export" libraries in this document). In addition to
+ all major DNS-related APIs BIND 9 is currently using, the export
+ libraries provide the following features:</para>
+ <itemizedlist>
+ <listitem>
+ <para>The newly created "DNS client" module. This is a higher
+ level API that provides an interface to name resolution,
+ single DNS transaction with a particular server, and dynamic
+ update. Regarding name resolution, it supports advanced
+ features such as DNSSEC validation and caching. This module
+ supports both synchronous and asynchronous mode.</para>
+ </listitem>
+ <listitem>
+ <para>The new "IRS" (Information Retrieval System) library.
+ It provides an interface to parse the traditional resolv.conf
+ file and more advanced, DNS-specific configuration file for
+ the rest of this package (see the description for the
+ dns.conf file below).</para>
+ </listitem>
+ <listitem>
+ <para>As part of the IRS library, newly implemented standard
+ address-name mapping functions, getaddrinfo() and
+ getnameinfo(), are provided. They use the DNSSEC-aware
+ validating resolver backend, and could use other advanced
+ features of the BIND 9 libraries such as caching. The
+ getaddrinfo() function resolves both A and AAAA RRs
+ concurrently (when the address family is unspecified).</para>
+ </listitem>
+ <listitem>
+ <para>An experimental framework to support other event
+ libraries than BIND 9's internal event task system.</para>
+ </listitem>
+ </itemizedlist>
+ <sect2>
+ <title>Prerequisite</title>
+ <para>GNU make is required to build the export libraries (other
+ part of BIND 9 can still be built with other types of make). In
+ the reminder of this document, "make" means GNU make. Note that
+ in some platforms you may need to invoke a different command name
+ than "make" (e.g. "gmake") to indicate it's GNU make.</para>
+ </sect2>
+ <sect2>
+ <title>Compilation</title>
+ <screen>
+$ <userinput>./configure --enable-exportlib <replaceable>[other flags]</replaceable></userinput>
+$ <userinput>make</userinput>
+</screen>
+ <para>
+ This will create (in addition to usual BIND 9 programs) and a
+ separate set of libraries under the lib/export directory. For
+ example, <filename>lib/export/dns/libdns.a</filename> is the archive file of the
+ export version of the BIND 9 DNS library. Sample application
+ programs using the libraries will also be built under the
+ lib/export/samples directory (see below).</para>
+ </sect2>
+ <sect2>
+ <title>Installation</title>
+ <screen>
+$ <userinput>cd lib/export</userinput>
+$ <userinput>make install</userinput>
+</screen>
+ <para>
+ This will install library object files under the directory
+ specified by the --with-export-libdir configure option (default:
+ EPREFIX/lib/bind9), and header files under the directory
+ specified by the --with-export-includedir configure option
+ (default: PREFIX/include/bind9).
+ Root privilege is normally required.
+ "<command>make install</command>" at the top directory will do the
+ same.
+ </para>
+ <para>
+ To see how to build your own
+ application after the installation, see
+ <filename>lib/export/samples/Makefile-postinstall.in</filename>.</para>
+ </sect2>
+ <sect2>
+ <title>Known Defects/Restrictions</title>
+ <itemizedlist>
+ <listitem>
+<!-- TODO: what about AIX? -->
+ <para>Currently, win32 is not supported for the export
+ library. (Normal BIND 9 application can be built as
+ before).</para>
+ </listitem>
+ <listitem>
+ <para>The "fixed" RRset order is not (currently) supported in
+ the export library. If you want to use "fixed" RRset order
+ for, e.g. <command>named</command> while still building the
+ export library even without the fixed order support, build
+ them separately:
+ <screen>
+$ <userinput>./configure --enable-fixed-rrset <replaceable>[other flags, but not --enable-exportlib]</replaceable></userinput>
+$ <userinput>make</userinput>
+$ <userinput>./configure --enable-exportlib <replaceable>[other flags, but not --enable-fixed-rrset]</replaceable></userinput>
+$ <userinput>cd lib/export</userinput>
+$ <userinput>make</userinput>
+</screen>
+ </para>
+ </listitem>
+ <listitem>
+ <para>The client module and the IRS library currently do not
+ support DNSSEC validation using DLV (the underlying modules
+ can handle it, but there is no tunable interface to enable
+ the feature).</para>
+ </listitem>
+ <listitem>
+ <para>RFC 5011 is not supported in the validating stub
+ resolver of the export library. In fact, it is not clear
+ whether it should: trust anchors would be a system-wide
+ configuration which would be managed by an administrator,
+ while the stub resolver will be used by ordinary applications
+ run by a normal user.</para>
+ </listitem>
+ <listitem>
+ <para>Not all common <filename>/etc/resolv.conf</filename>
+ options are supported
+ in the IRS library. The only available options in this
+ version are "debug" and "ndots".</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ <sect2>
+ <title>The dns.conf File</title>
+ <para>The IRS library supports an "advanced" configuration file
+ related to the DNS library for configuration parameters that
+ would be beyond the capability of the
+ <filename>resolv.conf</filename> file.
+ Specifically, it is intended to provide DNSSEC related
+ configuration parameters. By default the path to this
+ configuration file is <filename>/etc/dns.conf</filename>.
+ This module is very
+ experimental and the configuration syntax or library interfaces
+ may change in future versions. Currently, only the
+ <command>trusted-keys</command>
+ statement is supported, whose syntax is the same as the same name
+ of statement for <filename>named.conf</filename>. (See
+ <xref linkend="trusted-keys" /> for details.)</para>
+ </sect2>
+ <sect2>
+ <title>Sample Applications</title>
+ <para>Some sample application programs using this API are
+ provided for reference. The following is a brief description of
+ these applications.
+ </para>
+ <sect3>
+ <title>sample: a simple stub resolver utility</title>
+ <para>
+ It sends a query of a given name (of a given optional RR type) to a
+ specified recursive server, and prints the result as a list of
+ RRs. It can also act as a validating stub resolver if a trust
+ anchor is given via a set of command line options.</para>
+ <para>
+ Usage: sample [options] server_address hostname
+ </para>
+ <para>
+ Options and Arguments:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ -t RRtype
+ </term>
+ <listitem><para>
+ specify the RR type of the query. The default is the A RR.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ [-a algorithm] [-e] -k keyname -K keystring
+ </term>
+ <listitem><para>
+ specify a command-line DNS key to validate the answer. For
+ example, to specify the following DNSKEY of example.com:
+<literallayout>
+ example.com. 3600 IN DNSKEY 257 3 5 xxx
+</literallayout>
+ specify the options as follows:
+<screen>
+<userinput>
+ -e -k example.com -K "xxx"
+</userinput>
+</screen>
+ -e means that this key is a zone's "key signing key" (as known
+ as "secure Entry point").
+ When -a is omitted rsasha1 will be used by default.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ -s domain:alt_server_address
+ </term>
+ <listitem><para>
+ specify a separate recursive server address for the specific
+ "domain". Example: -s example.com:2001:db8::1234
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>server_address</term>
+ <listitem><para>
+ an IP(v4/v6) address of the recursive server to which queries
+ are sent.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>hostname</term>
+ <listitem><para>
+ the domain name for the query
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+ <sect3>
+ <title>sample-async: a simple stub resolver, working asynchronously</title>
+ <para>
+ Similar to "sample", but accepts a list
+ of (query) domain names as a separate file and resolves the names
+ asynchronously.</para>
+ <para>
+ Usage: sample-async [-s server_address] [-t RR_type] input_file</para>
+ <para>
+ Options and Arguments:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ -s server_address
+ </term>
+ <listitem>
+ an IPv4 address of the recursive server to which queries are sent.
+ (IPv6 addresses are not supported in this implementation)
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ -t RR_type
+ </term>
+ <listitem>
+ specify the RR type of the queries. The default is the A
+ RR.
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ input_file
+ </term>
+ <listitem>
+ a list of domain names to be resolved. each line
+ consists of a single domain name. Example:
+ <literallayout>
+ www.example.com
+ mx.examle.net
+ ns.xxx.example
+</literallayout>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+ <sect3>
+ <title>sample-request: a simple DNS transaction client</title>
+ <para>
+ It sends a query to a specified server, and
+ prints the response with minimal processing. It doesn't act as a
+ "stub resolver": it stops the processing once it gets any
+ response from the server, whether it's a referral or an alias
+ (CNAME or DNAME) that would require further queries to get the
+ ultimate answer. In other words, this utility acts as a very
+ simplified <command>dig</command>.
+ </para>
+ <para>
+ Usage: sample-request [-t RRtype] server_address hostname
+ </para>
+ <para>
+ Options and Arguments:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ -t RRtype
+ </term>
+ <listitem>
+ <para>
+ specify the RR type of
+ the queries. The default is the A RR.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ server_address
+ </term>
+ <listitem>
+ <para>
+ an IP(v4/v6)
+ address of the recursive server to which the query is sent.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ hostname
+ </term>
+ <listitem>
+ <para>
+ the domain name for the query
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+ <sect3>
+ <title>sample-gai: getaddrinfo() and getnameinfo() test code</title>
+ <para>
+ This is a test program
+ to check getaddrinfo() and getnameinfo() behavior. It takes a
+ host name as an argument, calls getaddrinfo() with the given host
+ name, and calls getnameinfo() with the resulting IP addresses
+ returned by getaddrinfo(). If the dns.conf file exists and
+ defines a trust anchor, the underlying resolver will act as a
+ validating resolver, and getaddrinfo()/getnameinfo() will fail
+ with an EAI_INSECUREDATA error when DNSSEC validation fails.
+ </para>
+ <para>
+ Usage: sample-gai hostname
+ </para>
+ </sect3>
+ <sect3>
+ <title>sample-update: a simple dynamic update client program</title>
+ <para>
+ It accepts a single update command as a
+ command-line argument, sends an update request message to the
+ authoritative server, and shows the response from the server. In
+ other words, this is a simplified <command>nsupdate</command>.
+ </para>
+ <para>
+ Usage: sample-update [options] (add|delete) "update data"
+ </para>
+ <para>
+ Options and Arguments:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ -a auth_server
+ </term>
+ <listitem><para>
+ An IP address of the authoritative server that has authority
+ for the zone containing the update name. This should normally
+ be the primary authoritative server that accepts dynamic
+ updates. It can also be a secondary server that is configured
+ to forward update requests to the primary server.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ -k keyfile
+ </term>
+ <listitem><para>
+ A TSIG key file to secure the update transaction. The keyfile
+ format is the same as that for the nsupdate utility.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ -p prerequisite
+ </term>
+ <listitem><para>
+ A prerequisite for the update (only one prerequisite can be
+ specified). The prerequisite format is the same as that is
+ accepted by the nsupdate utility.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ -r recursive_server
+ </term>
+ <listitem><para>
+ An IP address of a recursive server that this utility will
+ use. A recursive server may be necessary to identify the
+ authoritative server address to which the update request is
+ sent.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ -z zonename
+ </term>
+ <listitem><para>
+ The domain name of the zone that contains
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ (add|delete)
+ </term>
+ <listitem><para>
+ Specify the type of update operation. Either "add" or "delete"
+ must be specified.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ "update data"
+ </term>
+ <listitem><para>
+ Specify the data to be updated. A typical example of the data
+ would look like "name TTL RRtype RDATA".
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <note>In practice, either -a or -r must be specified. Others can
+ be optional; the underlying library routine tries to identify the
+ appropriate server and the zone name for the update.</note>
+
+ <para>
+ Examples: assuming the primary authoritative server of the
+ dynamic.example.com zone has an IPv6 address 2001:db8::1234,
+ </para>
+ <screen>
+$ <userinput>sample-update -a sample-update -k Kxxx.+nnn+mmmm.key add "foo.dynamic.example.com 30 IN A 192.168.2.1"</userinput></screen>
+ <para>
+ adds an A RR for foo.dynamic.example.com using the given key.
+ </para>
+ <screen>
+$ <userinput>sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com 30 IN A"</userinput></screen>
+ <para>
+ removes all A RRs for foo.dynamic.example.com using the given key.
+ </para>
+ <screen>
+$ <userinput>sample-update -a sample-update -k Kxxx.+nnn+mmmm.key delete "foo.dynamic.example.com"</userinput></screen>
+ <para>
+ removes all RRs for foo.dynamic.example.com using the given key.
+ </para>
+ </sect3>
+ <sect3>
+ <title>nsprobe: domain/name server checker in terms of RFC 4074</title>
+ <para>
+ It checks a set
+ of domains to see the name servers of the domains behave
+ correctly in terms of RFC 4074. This is included in the set of
+ sample programs to show how the export library can be used in a
+ DNS-related application.
+ </para>
+ <para>
+ Usage: nsprobe [-d] [-v [-v...]] [-c cache_address] [input_file]
+ </para>
+ <para>
+ Options
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ -d
+ </term>
+ <listitem><para>
+ run in the "debug" mode. with this option nsprobe will dump
+ every RRs it receives.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ -v
+ </term>
+ <listitem><para>
+ increase verbosity of other normal log messages. This can be
+ specified multiple times
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ -c cache_address
+ </term>
+ <listitem><para>
+ specify an IP address of a recursive (caching) name server.
+ nsprobe uses this server to get the NS RRset of each domain and
+ the A and/or AAAA RRsets for the name servers. The default
+ value is 127.0.0.1.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ input_file
+ </term>
+ <listitem><para>
+ a file name containing a list of domain (zone) names to be
+ probed. when omitted the standard input will be used. Each
+ line of the input file specifies a single domain name such as
+ "example.com". In general this domain name must be the apex
+ name of some DNS zone (unlike normal "host names" such as
+ "www.example.com"). nsprobe first identifies the NS RRsets for
+ the given domain name, and sends A and AAAA queries to these
+ servers for some "widely used" names under the zone;
+ specifically, adding "www" and "ftp" to the zone name.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>Library References</title>
+ <para>As of this writing, there is no formal "manual" of the
+ libraries, except this document, header files (some of them
+ provide pretty detailed explanations), and sample application
+ programs.</para>
+ </sect2>
+</sect1>
+<!-- $Id: libdns.xml,v 1.3 2010-02-03 23:49:07 tbox Exp $ -->
diff --git a/doc/arm/man.arpaname.html b/doc/arm/man.arpaname.html
new file mode 100644
index 000000000000..8f0d98c35f5b
--- /dev/null
+++ b/doc/arm/man.arpaname.html
@@ -0,0 +1,91 @@
+<!--
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2000-2003 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: man.arpaname.html,v 1.33.8.1.2.1 2011-06-09 03:41:11 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>arpaname</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
+<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
+<link rel="prev" href="man.ddns-confgen.html" title="ddns-confgen">
+<link rel="next" href="man.genrandom.html" title="genrandom">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table width="100%" summary="Navigation header">
+<tr><th colspan="3" align="center"><span class="application">arpaname</span></th></tr>
+<tr>
+<td width="20%" align="left">
+<a accesskey="p" href="man.ddns-confgen.html">Prev</a> </td>
+<th width="60%" align="center">Manual pages</th>
+<td width="20%" align="right"> <a accesskey="n" href="man.genrandom.html">Next</a>
+</td>
+</tr>
+</table>
+<hr>
+</div>
+<div class="refentry" lang="en">
+<a name="man.arpaname"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">arpaname</span> &#8212; translate IP addresses to the corresponding ARPA names</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">arpaname</code> {<em class="replaceable"><code>ipaddress </code></em>...}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2616630"></a><h2>DESCRIPTION</h2>
+<p>
+ <span><strong class="command">arpaname</strong></span> translates IP addresses (IPv4 and
+ IPv6) to the corresponding IN-ADDR.ARPA or IP6.ARPA names.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2616645"></a><h2>SEE ALSO</h2>
+<p>
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2616659"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div>
+<div class="navfooter">
+<hr>
+<table width="100%" summary="Navigation footer">
+<tr>
+<td width="40%" align="left">
+<a accesskey="p" href="man.ddns-confgen.html">Prev</a> </td>
+<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
+<td width="40%" align="right"> <a accesskey="n" href="man.genrandom.html">Next</a>
+</td>
+</tr>
+<tr>
+<td width="40%" align="left" valign="top">
+<span class="application">ddns-confgen</span> </td>
+<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
+<td width="40%" align="right" valign="top"> <span class="application">genrandom</span>
+</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/arm/man.ddns-confgen.html b/doc/arm/man.ddns-confgen.html
new file mode 100644
index 000000000000..0155dbf658ed
--- /dev/null
+++ b/doc/arm/man.ddns-confgen.html
@@ -0,0 +1,180 @@
+<!--
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2000-2003 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: man.ddns-confgen.html,v 1.69.8.1.2.1 2011-06-09 03:41:11 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>ddns-confgen</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
+<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
+<link rel="prev" href="man.rndc-confgen.html" title="rndc-confgen">
+<link rel="next" href="man.arpaname.html" title="arpaname">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table width="100%" summary="Navigation header">
+<tr><th colspan="3" align="center"><span class="application">ddns-confgen</span></th></tr>
+<tr>
+<td width="20%" align="left">
+<a accesskey="p" href="man.rndc-confgen.html">Prev</a> </td>
+<th width="60%" align="center">Manual pages</th>
+<td width="20%" align="right"> <a accesskey="n" href="man.arpaname.html">Next</a>
+</td>
+</tr>
+</table>
+<hr>
+</div>
+<div class="refentry" lang="en">
+<a name="man.ddns-confgen"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">ddns-confgen</span> &#8212; ddns key generation tool</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">ddns-confgen</code> [<code class="option">-a <em class="replaceable"><code>algorithm</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>keyname</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomfile</code></em></code>] [ -s <em class="replaceable"><code>name</code></em> | -z <em class="replaceable"><code>zone</code></em> ] [<code class="option">-q</code>] [name]</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2645803"></a><h2>DESCRIPTION</h2>
+<p><span><strong class="command">ddns-confgen</strong></span>
+ generates a key for use by <span><strong class="command">nsupdate</strong></span>
+ and <span><strong class="command">named</strong></span>. It simplifies configuration
+ of dynamic zones by generating a key and providing the
+ <span><strong class="command">nsupdate</strong></span> and <span><strong class="command">named.conf</strong></span>
+ syntax that will be needed to use it, including an example
+ <span><strong class="command">update-policy</strong></span> statement.
+ </p>
+<p>
+ If a domain name is specified on the command line, it will
+ be used in the name of the generated key and in the sample
+ <span><strong class="command">named.conf</strong></span> syntax. For example,
+ <span><strong class="command">ddns-confgen example.com</strong></span> would
+ generate a key called "ddns-key.example.com", and sample
+ <span><strong class="command">named.conf</strong></span> command that could be used
+ in the zone definition for "example.com".
+ </p>
+<p>
+ Note that <span><strong class="command">named</strong></span> itself can configure a
+ local DDNS key for use with <span><strong class="command">nsupdate -l</strong></span>.
+ <span><strong class="command">ddns-confgen</strong></span> is only needed when a
+ more elaborate configuration is required: for instance, if
+ <span><strong class="command">nsupdate</strong></span> is to be used from a remote system.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2645959"></a><h2>OPTIONS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
+<dd><p>
+ Specifies the algorithm to use for the TSIG key. Available
+ choices are: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256,
+ hmac-sha384 and hmac-sha512. The default is hmac-sha256.
+ </p></dd>
+<dt><span class="term">-h</span></dt>
+<dd><p>
+ Prints a short summary of the options and arguments to
+ <span><strong class="command">ddns-confgen</strong></span>.
+ </p></dd>
+<dt><span class="term">-k <em class="replaceable"><code>keyname</code></em></span></dt>
+<dd><p>
+ Specifies the key name of the DDNS authentication key.
+ The default is <code class="constant">ddns-key</code> when neither
+ the <code class="option">-s</code> nor <code class="option">-z</code> option is
+ specified; otherwise, the default
+ is <code class="constant">ddns-key</code> as a separate label
+ followed by the argument of the option, e.g.,
+ <code class="constant">ddns-key.example.com.</code>
+ The key name must have the format of a valid domain name,
+ consisting of letters, digits, hyphens and periods.
+ </p></dd>
+<dt><span class="term">-q</span></dt>
+<dd><p>
+ Quiet mode: Print only the key, with no explanatory text or
+ usage examples.
+ </p></dd>
+<dt><span class="term">-r <em class="replaceable"><code>randomfile</code></em></span></dt>
+<dd><p>
+ Specifies a source of random data for generating the
+ authorization. If the operating system does not provide a
+ <code class="filename">/dev/random</code> or equivalent device, the
+ default source of randomness is keyboard input.
+ <code class="filename">randomdev</code> specifies the name of a
+ character device or file containing random data to be used
+ instead of the default. The special value
+ <code class="filename">keyboard</code> indicates that keyboard input
+ should be used.
+ </p></dd>
+<dt><span class="term">-s <em class="replaceable"><code>name</code></em></span></dt>
+<dd><p>
+ Single host mode: The example <span><strong class="command">named.conf</strong></span> text
+ shows how to set an update policy for the specified
+ <em class="replaceable"><code>name</code></em>
+ using the "name" nametype.
+ The default key name is
+ ddns-key.<em class="replaceable"><code>name</code></em>.
+ Note that the "self" nametype cannot be used, since
+ the name to be updated may differ from the key name.
+ This option cannot be used with the <code class="option">-z</code> option.
+ </p></dd>
+<dt><span class="term">-z <em class="replaceable"><code>zone</code></em></span></dt>
+<dd><p>
+ zone mode: The example <span><strong class="command">named.conf</strong></span> text
+ shows how to set an update policy for the specified
+ <em class="replaceable"><code>zone</code></em>
+ using the "zonesub" nametype, allowing updates to all subdomain
+ names within
+ that <em class="replaceable"><code>zone</code></em>.
+ This option cannot be used with the <code class="option">-s</code> option.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2646569"></a><h2>SEE ALSO</h2>
+<p><span class="citerefentry"><span class="refentrytitle">nsupdate</span>(1)</span>,
+ <span class="citerefentry"><span class="refentrytitle">named.conf</span>(5)</span>,
+ <span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2646608"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div>
+<div class="navfooter">
+<hr>
+<table width="100%" summary="Navigation footer">
+<tr>
+<td width="40%" align="left">
+<a accesskey="p" href="man.rndc-confgen.html">Prev</a> </td>
+<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
+<td width="40%" align="right"> <a accesskey="n" href="man.arpaname.html">Next</a>
+</td>
+</tr>
+<tr>
+<td width="40%" align="left" valign="top">
+<span class="application">rndc-confgen</span> </td>
+<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
+<td width="40%" align="right" valign="top"> <span class="application">arpaname</span>
+</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/arm/man.dig.html b/doc/arm/man.dig.html
index 6afc34bc7997..73b2b887c249 100644
--- a/doc/arm/man.dig.html
+++ b/doc/arm/man.dig.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dig.html,v 1.93.14.17 2010-08-20 02:05:39 tbox Exp $ -->
+<!-- $Id: man.dig.html,v 1.162.8.1.2.1 2011-06-09 03:41:09 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -52,7 +52,7 @@
<div class="cmdsynopsis"><p><code class="command">dig</code> [global-queryopt...] [query...]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2575940"></a><h2>DESCRIPTION</h2>
+<a name="id2609278"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dig</strong></span>
(domain information groper) is a flexible tool
for interrogating DNS name servers. It performs DNS lookups and
@@ -98,7 +98,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2576035"></a><h2>SIMPLE USAGE</h2>
+<a name="id2609373"></a><h2>SIMPLE USAGE</h2>
<p>
A typical invocation of <span><strong class="command">dig</strong></span> looks like:
</p>
@@ -144,7 +144,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2576146"></a><h2>OPTIONS</h2>
+<a name="id2610167"></a><h2>OPTIONS</h2>
<p>
The <code class="option">-b</code> option sets the source IP address of the query
to <em class="parameter"><code>address</code></em>. This must be a valid
@@ -248,7 +248,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2630214"></a><h2>QUERY OPTIONS</h2>
+<a name="id2662324"></a><h2>QUERY OPTIONS</h2>
<p><span><strong class="command">dig</strong></span>
provides a number of query options which affect
the way in which lookups are made and the results displayed. Some of
@@ -517,6 +517,12 @@
each record on a single line, to facilitate machine parsing
of the <span><strong class="command">dig</strong></span> output.
</p></dd>
+<dt><span class="term"><code class="option">+[no]onesoa</code></span></dt>
+<dd><p>
+ Print only one (starting) SOA record when performing
+ an AXFR. The default is to print both the starting and
+ ending SOA records.
+ </p></dd>
<dt><span class="term"><code class="option">+[no]fail</code></span></dt>
<dd><p>
Do not try the next server if you receive a SERVFAIL. The
@@ -573,7 +579,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631283"></a><h2>MULTIPLE QUERIES</h2>
+<a name="id2663338"></a><h2>MULTIPLE QUERIES</h2>
<p>
The BIND 9 implementation of <span><strong class="command">dig </strong></span>
supports
@@ -619,7 +625,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631436"></a><h2>IDN SUPPORT</h2>
+<a name="id2663424"></a><h2>IDN SUPPORT</h2>
<p>
If <span><strong class="command">dig</strong></span> has been built with IDN (internationalized
domain name) support, it can accept and display non-ASCII domain names.
@@ -633,14 +639,14 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631465"></a><h2>FILES</h2>
+<a name="id2663452"></a><h2>FILES</h2>
<p><code class="filename">/etc/resolv.conf</code>
</p>
<p><code class="filename">${HOME}/.digrc</code>
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631486"></a><h2>SEE ALSO</h2>
+<a name="id2663474"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">host</span>(1)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
@@ -648,7 +654,7 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2631524"></a><h2>BUGS</h2>
+<a name="id2663579"></a><h2>BUGS</h2>
<p>
There are probably too many query options.
</p>
diff --git a/doc/arm/man.dnssec-dsfromkey.html b/doc/arm/man.dnssec-dsfromkey.html
index 245d387a9ee1..133bfbc65473 100644
--- a/doc/arm/man.dnssec-dsfromkey.html
+++ b/doc/arm/man.dnssec-dsfromkey.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-dsfromkey.html,v 1.6.14.16 2010-08-20 02:05:40 tbox Exp $ -->
+<!-- $Id: man.dnssec-dsfromkey.html,v 1.74.8.1.2.1 2011-06-09 03:41:09 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,18 +47,18 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] {keyfile}</p></div>
-<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>dir</code></em></code>] {dnsname}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] {keyfile}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> {-s} [<code class="option">-1</code>] [<code class="option">-2</code>] [<code class="option">-a <em class="replaceable"><code>alg</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-s</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>file</code></em></code>] [<code class="option">-A</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {dnsname}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2604158"></a><h2>DESCRIPTION</h2>
+<a name="id2611192"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-dsfromkey</strong></span>
outputs the Delegation Signer (DS) resource record (RR), as defined in
RFC 3658 and RFC 4509, for the given key(s).
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604172"></a><h2>OPTIONS</h2>
+<a name="id2611411"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-1</span></dt>
<dd><p>
@@ -72,34 +72,54 @@
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd><p>
Select the digest algorithm. The value of
- <code class="option">algorithm</code> must be one of SHA-1 (SHA1) or
- SHA-256 (SHA256). These values are case insensitive.
+ <code class="option">algorithm</code> must be one of SHA-1 (SHA1),
+ SHA-256 (SHA256) or GOST. These values are case insensitive.
</p></dd>
-<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
<dd><p>
- Sets the debugging level.
+ Look for key files (or, in keyset mode,
+ <code class="filename">keyset-</code> files) in
+ <code class="option">directory</code>.
+ </p></dd>
+<dt><span class="term">-f <em class="replaceable"><code>file</code></em></span></dt>
+<dd><p>
+ Zone file mode: in place of the keyfile name, the argument is
+ the DNS domain name of a zone master file, which can be read
+ from <code class="option">file</code>. If the zone name is the same as
+ <code class="option">file</code>, then it may be omitted.
+ </p></dd>
+<dt><span class="term">-A</span></dt>
+<dd><p>
+ Include ZSK's when generating DS records. Without this option,
+ only keys which have the KSK flag set will be converted to DS
+ records and printed. Useful only in zone file mode.
+ </p></dd>
+<dt><span class="term">-l <em class="replaceable"><code>domain</code></em></span></dt>
+<dd><p>
+ Generate a DLV set instead of a DS set. The specified
+ <code class="option">domain</code> is appended to the name for each
+ record in the set.
+ The DNSSEC Lookaside Validation (DLV) RR is described
+ in RFC 4431.
</p></dd>
<dt><span class="term">-s</span></dt>
<dd><p>
Keyset mode: in place of the keyfile name, the argument is
- the DNS domain name of a keyset file. Following options make sense
- only in this mode.
+ the DNS domain name of a keyset file.
</p></dd>
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
<dd><p>
- Specifies the DNS class (default is IN), useful only
- in the keyset mode.
+ Specifies the DNS class (default is IN). Useful only
+ in keyset or zone file mode.
</p></dd>
-<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
+<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
<dd><p>
- Look for <code class="filename">keyset</code> files in
- <code class="option">directory</code> as the directory, ignored when
- not in the keyset mode.
+ Sets the debugging level.
</p></dd>
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2604302"></a><h2>EXAMPLE</h2>
+<a name="id2611600"></a><h2>EXAMPLE</h2>
<p>
To build the SHA-256 DS RR from the
<strong class="userinput"><code>Kexample.com.+003+26160</code></strong>
@@ -114,7 +134,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604407"></a><h2>FILES</h2>
+<a name="id2612114"></a><h2>FILES</h2>
<p>
The keyfile can be designed by the key identification
<code class="filename">Knnnn.+aaa+iiiii</code> or the full file name
@@ -128,22 +148,23 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604449"></a><h2>CAVEAT</h2>
+<a name="id2612155"></a><h2>CAVEAT</h2>
<p>
A keyfile error can give a "file not found" even if the file exists.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604458"></a><h2>SEE ALSO</h2>
+<a name="id2612165"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 3658</em>,
+ <em class="citetitle">RFC 4431</em>.
<em class="citetitle">RFC 4509</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604494"></a><h2>AUTHOR</h2>
+<a name="id2612204"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.dnssec-keyfromlabel.html b/doc/arm/man.dnssec-keyfromlabel.html
index 4a28c5e99531..670c85a2d3ce 100644
--- a/doc/arm/man.dnssec-keyfromlabel.html
+++ b/doc/arm/man.dnssec-keyfromlabel.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-keyfromlabel.html,v 1.31.14.19 2010-08-20 02:05:37 tbox Exp $ -->
+<!-- $Id: man.dnssec-keyfromlabel.html,v 1.110.8.1.2.1 2011-06-09 03:41:09 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,26 +47,30 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-k</code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-keyfromlabel</code> {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-3</code>] [<code class="option">-a <em class="replaceable"><code>algorithm</code></em></code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-G</code>] [<code class="option">-I <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-k</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-y</code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2604823"></a><h2>DESCRIPTION</h2>
+<a name="id2612785"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keyfromlabel</strong></span>
gets keys with the given label from a crypto hardware and builds
key files for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034.
</p>
+<p>
+ The <code class="option">name</code> of the key is specified on the command
+ line. This must match the name of the zone for which the key is
+ being generated.
+ </p>
</div>
<div class="refsect1" lang="en">
-<a name="id2604837"></a><h2>OPTIONS</h2>
+<a name="id2612805"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
<p>
Selects the cryptographic algorithm. The value of
- <code class="option">algorithm</code> must be one of RSAMD5,
- RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256,
- RSASHA512 or DH (Diffie Hellman).
+ <code class="option">algorithm</code> must be one of RSAMD5, RSASHA1,
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
These values are case insensitive.
</p>
<p>
@@ -84,10 +88,23 @@
Note 2: DH automatically sets the -k flag.
</p>
</dd>
+<dt><span class="term">-3</span></dt>
+<dd><p>
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default.
+ </p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Specifies the name of the crypto hardware (OpenSSL engine).
+ When compiled with PKCS#11 support it defaults to "pkcs11".
+ </p></dd>
<dt><span class="term">-l <em class="replaceable"><code>label</code></em></span></dt>
<dd><p>
- Specifies the label of keys in the crypto hardware
- (PKCS#11 device).
+ Specifies the label of the key pair in the crypto hardware.
+ The label may be preceded by an optional OpenSSL engine name,
+ separated by a colon, as in "pkcs11:keylabel".
</p></dd>
<dt><span class="term">-n <em class="replaceable"><code>nametype</code></em></span></dt>
<dd><p>
@@ -96,8 +113,17 @@
zone key (KEY/DNSKEY)), HOST or ENTITY (for a key associated with
a host (KEY)),
USER (for a key associated with a user(KEY)) or OTHER (DNSKEY).
- These values are
- case insensitive.
+ These values are case insensitive.
+ </p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <span><strong class="command">dnssec-keyfromlabel</strong></span>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <code class="option">-C</code> option suppresses them.
</p></dd>
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
<dd><p>
@@ -107,12 +133,21 @@
<dt><span class="term">-f <em class="replaceable"><code>flag</code></em></span></dt>
<dd><p>
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+ </p></dd>
+<dt><span class="term">-G</span></dt>
+<dd><p>
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
</p></dd>
<dt><span class="term">-h</span></dt>
<dd><p>
Prints a short summary of the options and arguments to
- <span><strong class="command">dnssec-keygen</strong></span>.
+ <span><strong class="command">dnssec-keyfromlabel</strong></span>.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to be written.
</p></dd>
<dt><span class="term">-k</span></dt>
<dd><p>
@@ -120,7 +155,7 @@
</p></dd>
<dt><span class="term">-p <em class="replaceable"><code>protocol</code></em></span></dt>
<dd><p>
- Sets the protocol value for the generated key. The protocol
+ Sets the protocol value for the key. The protocol
is a number between 0 and 255. The default is 3 (DNSSEC).
Other possible values for this argument are listed in
RFC 2535 and its successors.
@@ -136,10 +171,65 @@
<dd><p>
Sets the debugging level.
</p></dd>
+<dt><span class="term">-y</span></dt>
+<dd><p>
+ Allows DNSSEC key files to be generated even if the key ID
+ would collide with that of an existing key, in the event of
+ either key being revoked. (This is only safe to use if you
+ are sure you won't be using RFC 5011 trust anchor maintenance
+ with either of the keys involved.)
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2613241"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-I <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </p></dd>
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2605316"></a><h2>GENERATED KEY FILES</h2>
+<a name="id2615114"></a><h2>GENERATED KEY FILES</h2>
<p>
When <span><strong class="command">dnssec-keyfromlabel</strong></span> completes
successfully,
@@ -151,8 +241,7 @@
<li><p><code class="filename">nnnn</code> is the key name.
</p></li>
<li><p><code class="filename">aaa</code> is the numeric representation
- of the
- algorithm.
+ of the algorithm.
</p></li>
<li><p><code class="filename">iiiii</code> is the key identifier (or
footprint).
@@ -163,8 +252,7 @@
on the printed string. <code class="filename">Knnnn.+aaa+iiiii.key</code>
contains the public key, and
<code class="filename">Knnnn.+aaa+iiiii.private</code> contains the
- private
- key.
+ private key.
</p>
<p>
The <code class="filename">.key</code> file contains a DNS KEY record
@@ -173,14 +261,14 @@
statement).
</p>
<p>
- The <code class="filename">.private</code> file contains algorithm
- specific
+ The <code class="filename">.private</code> file contains
+ algorithm-specific
fields. For obvious security reasons, this file does not have
general read permission.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605410"></a><h2>SEE ALSO</h2>
+<a name="id2666203"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
@@ -188,7 +276,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605443"></a><h2>AUTHOR</h2>
+<a name="id2666236"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.dnssec-keygen.html b/doc/arm/man.dnssec-keygen.html
index d775f564a2d4..3d63f8e32d1d 100644
--- a/doc/arm/man.dnssec-keygen.html
+++ b/doc/arm/man.dnssec-keygen.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-keygen.html,v 1.97.14.19 2010-08-20 02:05:37 tbox Exp $ -->
+<!-- $Id: man.dnssec-keygen.html,v 1.179.8.1.2.1 2011-06-09 03:41:09 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -23,7 +23,7 @@
<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
<link rel="prev" href="man.dnssec-keyfromlabel.html" title="dnssec-keyfromlabel">
-<link rel="next" href="man.dnssec-signzone.html" title="dnssec-signzone">
+<link rel="next" href="man.dnssec-revoke.html" title="dnssec-revoke">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
@@ -33,7 +33,7 @@
<td width="20%" align="left">
<a accesskey="p" href="man.dnssec-keyfromlabel.html">Prev</a> </td>
<th width="60%" align="center">Manual pages</th>
-<td width="20%" align="right"> <a accesskey="n" href="man.dnssec-signzone.html">Next</a>
+<td width="20%" align="right"> <a accesskey="n" href="man.dnssec-revoke.html">Next</a>
</td>
</tr>
</table>
@@ -47,14 +47,15 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-keygen</code> {-a <em class="replaceable"><code>algorithm</code></em>} {-b <em class="replaceable"><code>keysize</code></em>} {-n <em class="replaceable"><code>nametype</code></em>} [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-e</code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-g <em class="replaceable"><code>generator</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k</code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>strength</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] {name}</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-keygen</code> [<code class="option">-a <em class="replaceable"><code>algorithm</code></em></code>] [<code class="option">-b <em class="replaceable"><code>keysize</code></em></code>] [<code class="option">-n <em class="replaceable"><code>nametype</code></em></code>] [<code class="option">-3</code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-C</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-e</code>] [<code class="option">-f <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-G</code>] [<code class="option">-g <em class="replaceable"><code>generator</code></em></code>] [<code class="option">-h</code>] [<code class="option">-I <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-k</code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-p <em class="replaceable"><code>protocol</code></em></code>] [<code class="option">-q</code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-S <em class="replaceable"><code>key</code></em></code>] [<code class="option">-s <em class="replaceable"><code>strength</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] {name}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2605897"></a><h2>DESCRIPTION</h2>
+<a name="id2614215"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-keygen</strong></span>
generates keys for DNSSEC (Secure DNS), as defined in RFC 2535
and RFC 4034. It can also generate keys for use with
- TSIG (Transaction Signatures), as defined in RFC 2845.
+ TSIG (Transaction Signatures) as defined in RFC 2845, or TKEY
+ (Transaction Key) as defined in RFC 2930.
</p>
<p>
The <code class="option">name</code> of the key is specified on the command
@@ -63,37 +64,56 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2605917"></a><h2>OPTIONS</h2>
+<a name="id2614235"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt>
<dd>
<p>
Selects the cryptographic algorithm. For DNSSEC keys, the value
of <code class="option">algorithm</code> must be one of RSAMD5, RSASHA1,
- DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512.
- For TSIG/TKEY, the value must
+ DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST.
+ For TSIG/TKEY, the value must
be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224,
HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are
case insensitive.
</p>
<p>
+ If no algorithm is specified, then RSASHA1 will be used by
+ default, unless the <code class="option">-3</code> option is specified,
+ in which case NSEC3RSASHA1 will be used instead. (If
+ <code class="option">-3</code> is used and an algorithm is specified,
+ that algorithm will be checked for compatibility with NSEC3.)
+ </p>
+<p>
Note 1: that for DNSSEC, RSASHA1 is a mandatory to implement
algorithm, and DSA is recommended. For TSIG, HMAC-MD5 is
mandatory.
</p>
<p>
- Note 2: HMAC-MD5 and DH automatically set the -k flag.
+ Note 2: DH, HMAC-MD5, and HMAC-SHA1 through HMAC-SHA512
+ automatically set the -T KEY option.
</p>
</dd>
<dt><span class="term">-b <em class="replaceable"><code>keysize</code></em></span></dt>
-<dd><p>
+<dd>
+<p>
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 keys must be
between 1 and 512 bits.
- </p></dd>
+ </p>
+<p>
+ The key size does not need to be specified if using a default
+ algorithm. The default key size is 1024 bits for zone signing
+ keys (ZSK's) and 2048 bits for key signing keys (KSK's,
+ generated with <code class="option">-f KSK</code>). However, if an
+ algorithm is explicitly specified with the <code class="option">-a</code>,
+ then there is no default key size, and the <code class="option">-b</code>
+ must be used.
+ </p>
+</dd>
<dt><span class="term">-n <em class="replaceable"><code>nametype</code></em></span></dt>
<dd><p>
Specifies the owner type of the key. The value of
@@ -104,11 +124,36 @@
These values are case insensitive. Defaults to ZONE for DNSKEY
generation.
</p></dd>
+<dt><span class="term">-3</span></dt>
+<dd><p>
+ Use an NSEC3-capable algorithm to generate a DNSSEC key.
+ If this option is used and no algorithm is explicitly
+ set on the command line, NSEC3RSASHA1 will be used by
+ default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms
+ are NSEC3-capable.
+ </p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: generates an old-style key, without
+ any metadata. By default, <span><strong class="command">dnssec-keygen</strong></span>
+ will include the key's creation date in the metadata stored
+ with the private key, and other dates may be set there as well
+ (publication date, activation date, etc). Keys that include
+ this data may be incompatible with older versions of BIND; the
+ <code class="option">-C</code> option suppresses them.
+ </p></dd>
<dt><span class="term">-c <em class="replaceable"><code>class</code></em></span></dt>
<dd><p>
Indicates that the DNS record containing the key should have
the specified class. If not specified, class IN is used.
</p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Uses a crypto hardware (OpenSSL engine) for random number
+ and, when supported, key generation. When compiled with PKCS#11
+ support it defaults to pkcs11; the empty name resets it to
+ no engine.
+ </p></dd>
<dt><span class="term">-e</span></dt>
<dd><p>
If generating an RSAMD5/RSASHA1 key, use a large exponent.
@@ -116,7 +161,12 @@
<dt><span class="term">-f <em class="replaceable"><code>flag</code></em></span></dt>
<dd><p>
Set the specified flag in the flag field of the KEY/DNSKEY record.
- The only recognized flag is KSK (Key Signing Key) DNSKEY.
+ The only recognized flags are KSK (Key Signing Key) and REVOKE.
+ </p></dd>
+<dt><span class="term">-G</span></dt>
+<dd><p>
+ Generate a key, but do not publish it or sign with it. This
+ option is incompatible with -P and -A.
</p></dd>
<dt><span class="term">-g <em class="replaceable"><code>generator</code></em></span></dt>
<dd><p>
@@ -130,9 +180,13 @@
Prints a short summary of the options and arguments to
<span><strong class="command">dnssec-keygen</strong></span>.
</p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to be written.
+ </p></dd>
<dt><span class="term">-k</span></dt>
<dd><p>
- Generate KEY records rather than DNSKEY records.
+ Deprecated in favor of -T KEY.
</p></dd>
<dt><span class="term">-p <em class="replaceable"><code>protocol</code></em></span></dt>
<dd><p>
@@ -141,6 +195,20 @@
Other possible values for this argument are listed in
RFC 2535 and its successors.
</p></dd>
+<dt><span class="term">-q</span></dt>
+<dd><p>
+ Quiet mode: Suppresses unnecessary output, including
+ progress indication. Without this option, when
+ <span><strong class="command">dnssec-keygen</strong></span> is run interactively
+ to generate an RSA or DSA key pair, it will print a string
+ of symbols to <code class="filename">stderr</code> indicating the
+ progress of the key generation. A '.' indicates that a
+ random number has been found which passed an initial
+ sieve test; '+' means a number has passed a single
+ round of the Miller-Rabin primality test; a space
+ means that the number has passed all the tests and is
+ a satisfactory key.
+ </p></dd>
<dt><span class="term">-r <em class="replaceable"><code>randomdev</code></em></span></dt>
<dd><p>
Specifies the source of randomness. If the operating
@@ -153,12 +221,37 @@
<code class="filename">keyboard</code> indicates that keyboard
input should be used.
</p></dd>
+<dt><span class="term">-S <em class="replaceable"><code>key</code></em></span></dt>
+<dd><p>
+ Create a new key which is an explicit successor to an
+ existing key. The name, algorithm, size, and type of the
+ key will be set to match the existing key. The activation
+ date of the new key will be set to the inactivation date of
+ the existing one. The publication date will be set to the
+ activation date minus the prepublication interval, which
+ defaults to 30 days.
+ </p></dd>
<dt><span class="term">-s <em class="replaceable"><code>strength</code></em></span></dt>
<dd><p>
Specifies the strength value of the key. The strength is
a number between 0 and 15, and currently has no defined
purpose in DNSSEC.
</p></dd>
+<dt><span class="term">-T <em class="replaceable"><code>rrtype</code></em></span></dt>
+<dd>
+<p>
+ Specifies the resource record type to use for the key.
+ <code class="option">rrtype</code> must be either DNSKEY or KEY. The
+ default is DNSKEY when using a DNSSEC algorithm, but it can be
+ overridden to KEY for use with SIG(0).
+ </p>
+<p>
+ </p>
+<p>
+ Using any TSIG algorithm (HMAC-* or DH) forces this option
+ to KEY.
+ </p>
+</dd>
<dt><span class="term">-t <em class="replaceable"><code>type</code></em></span></dt>
<dd><p>
Indicates the use of the key. <code class="option">type</code> must be
@@ -173,7 +266,78 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2606397"></a><h2>GENERATED KEYS</h2>
+<a name="id2667657"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it. If not set, and if the -G option has
+ not been used, the default is "now".
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it. If not set, and if the -G option has not been used, the
+ default is "now".
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-I <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </p></dd>
+<dt><span class="term">-i <em class="replaceable"><code>interval</code></em></span></dt>
+<dd>
+<p>
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+ </p>
+<p>
+ If the key is being created as an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+ </p>
+<p>
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+ </p>
+</dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2667847"></a><h2>GENERATED KEYS</h2>
<p>
When <span><strong class="command">dnssec-keygen</strong></span> completes
successfully,
@@ -219,7 +383,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2606505"></a><h2>EXAMPLE</h2>
+<a name="id2667955"></a><h2>EXAMPLE</h2>
<p>
To generate a 768-bit DSA key for the domain
<strong class="userinput"><code>example.com</code></strong>, the following command would be
@@ -240,7 +404,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608814"></a><h2>SEE ALSO</h2>
+<a name="id2668080"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 2539</em>,
@@ -249,7 +413,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608845"></a><h2>AUTHOR</h2>
+<a name="id2668110"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
@@ -261,14 +425,14 @@
<td width="40%" align="left">
<a accesskey="p" href="man.dnssec-keyfromlabel.html">Prev</a> </td>
<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
-<td width="40%" align="right"> <a accesskey="n" href="man.dnssec-signzone.html">Next</a>
+<td width="40%" align="right"> <a accesskey="n" href="man.dnssec-revoke.html">Next</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">
<span class="application">dnssec-keyfromlabel</span> </td>
<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
-<td width="40%" align="right" valign="top"> <span class="application">dnssec-signzone</span>
+<td width="40%" align="right" valign="top"> <span class="application">dnssec-revoke</span>
</td>
</tr>
</table>
diff --git a/doc/arm/man.dnssec-revoke.html b/doc/arm/man.dnssec-revoke.html
new file mode 100644
index 000000000000..1c9ba5a8184d
--- /dev/null
+++ b/doc/arm/man.dnssec-revoke.html
@@ -0,0 +1,126 @@
+<!--
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2000-2003 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: man.dnssec-revoke.html,v 1.62.8.1.2.1 2011-06-09 03:41:09 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>dnssec-revoke</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
+<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
+<link rel="prev" href="man.dnssec-keygen.html" title="dnssec-keygen">
+<link rel="next" href="man.dnssec-settime.html" title="dnssec-settime">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table width="100%" summary="Navigation header">
+<tr><th colspan="3" align="center"><span class="application">dnssec-revoke</span></th></tr>
+<tr>
+<td width="20%" align="left">
+<a accesskey="p" href="man.dnssec-keygen.html">Prev</a> </td>
+<th width="60%" align="center">Manual pages</th>
+<td width="20%" align="right"> <a accesskey="n" href="man.dnssec-settime.html">Next</a>
+</td>
+</tr>
+</table>
+<hr>
+</div>
+<div class="refentry" lang="en">
+<a name="man.dnssec-revoke"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">dnssec-revoke</span> &#8212; Set the REVOKED bit on a DNSSEC key</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">dnssec-revoke</code> [<code class="option">-hr</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-f</code>] {keyfile}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2614277"></a><h2>DESCRIPTION</h2>
+<p><span><strong class="command">dnssec-revoke</strong></span>
+ reads a DNSSEC key file, sets the REVOKED bit on the key as defined
+ in RFC 5011, and creates a new pair of key files containing the
+ now-revoked key.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2614291"></a><h2>OPTIONS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-h</span></dt>
+<dd><p>
+ Emit usage message and exit.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to reside.
+ </p></dd>
+<dt><span class="term">-r</span></dt>
+<dd><p>
+ After writing the new keyset files remove the original keyset
+ files.
+ </p></dd>
+<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
+<dd><p>
+ Sets the debugging level.
+ </p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </p></dd>
+<dt><span class="term">-f</span></dt>
+<dd><p>
+ Force overwrite: Causes <span><strong class="command">dnssec-revoke</strong></span> to
+ write the new key pair even if a file already exists matching
+ the algorithm and key ID of the revoked key.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2614398"></a><h2>SEE ALSO</h2>
+<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>,
+ <em class="citetitle">RFC 5011</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2614423"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div>
+<div class="navfooter">
+<hr>
+<table width="100%" summary="Navigation footer">
+<tr>
+<td width="40%" align="left">
+<a accesskey="p" href="man.dnssec-keygen.html">Prev</a> </td>
+<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
+<td width="40%" align="right"> <a accesskey="n" href="man.dnssec-settime.html">Next</a>
+</td>
+</tr>
+<tr>
+<td width="40%" align="left" valign="top">
+<span class="application">dnssec-keygen</span> </td>
+<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
+<td width="40%" align="right" valign="top"> <span class="application">dnssec-settime</span>
+</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/arm/man.dnssec-settime.html b/doc/arm/man.dnssec-settime.html
new file mode 100644
index 000000000000..19e467e2bbfd
--- /dev/null
+++ b/doc/arm/man.dnssec-settime.html
@@ -0,0 +1,247 @@
+<!--
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2000-2003 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: man.dnssec-settime.html,v 1.58.8.1.2.1 2011-06-09 03:41:10 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>dnssec-settime</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
+<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
+<link rel="prev" href="man.dnssec-revoke.html" title="dnssec-revoke">
+<link rel="next" href="man.dnssec-signzone.html" title="dnssec-signzone">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table width="100%" summary="Navigation header">
+<tr><th colspan="3" align="center"><span class="application">dnssec-settime</span></th></tr>
+<tr>
+<td width="20%" align="left">
+<a accesskey="p" href="man.dnssec-revoke.html">Prev</a> </td>
+<th width="60%" align="center">Manual pages</th>
+<td width="20%" align="right"> <a accesskey="n" href="man.dnssec-signzone.html">Next</a>
+</td>
+</tr>
+</table>
+<hr>
+</div>
+<div class="refentry" lang="en">
+<a name="man.dnssec-settime"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">dnssec-settime</span> &#8212; Set the key timing metadata for a DNSSEC key</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">dnssec-settime</code> [<code class="option">-f</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-P <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-A <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-R <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-I <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-D <em class="replaceable"><code>date/offset</code></em></code>] [<code class="option">-h</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] {keyfile}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2614556"></a><h2>DESCRIPTION</h2>
+<p><span><strong class="command">dnssec-settime</strong></span>
+ reads a DNSSEC private key file and sets the key timing metadata
+ as specified by the <code class="option">-P</code>, <code class="option">-A</code>,
+ <code class="option">-R</code>, <code class="option">-I</code>, and <code class="option">-D</code>
+ options. The metadata can then be used by
+ <span><strong class="command">dnssec-signzone</strong></span> or other signing software to
+ determine when a key is to be published, whether it should be
+ used for signing a zone, etc.
+ </p>
+<p>
+ If none of these options is set on the command line,
+ then <span><strong class="command">dnssec-settime</strong></span> simply prints the key timing
+ metadata already stored in the key.
+ </p>
+<p>
+ When key metadata fields are changed, both files of a key
+ pair (<code class="filename">Knnnn.+aaa+iiiii.key</code> and
+ <code class="filename">Knnnn.+aaa+iiiii.private</code>) are regenerated.
+ Metadata fields are stored in the private file. A human-readable
+ description of the metadata is also placed in comments in the key
+ file.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2614615"></a><h2>OPTIONS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-f</span></dt>
+<dd><p>
+ Force an update of an old-format key with no metadata fields.
+ Without this option, <span><strong class="command">dnssec-settime</strong></span> will
+ fail when attempting to update a legacy key. With this option,
+ the key will be recreated in the new format, but with the
+ original key data retained. The key's creation date will be
+ set to the present time.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Sets the directory in which the key files are to reside.
+ </p></dd>
+<dt><span class="term">-h</span></dt>
+<dd><p>
+ Emit usage message and exit.
+ </p></dd>
+<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
+<dd><p>
+ Sets the debugging level.
+ </p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Use the given OpenSSL engine. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2615323"></a><h2>TIMING OPTIONS</h2>
+<p>
+ Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS.
+ If the argument begins with a '+' or '-', it is interpreted as
+ an offset from the present time. For convenience, if such an offset
+ is followed by one of the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi',
+ then the offset is computed in years (defined as 365 24-hour days,
+ ignoring leap years), months (defined as 30 24-hour days), weeks,
+ days, hours, or minutes, respectively. Without a suffix, the offset
+ is computed in seconds. To unset a date, use 'none'.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-P <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which a key is to be published to the zone.
+ After that date, the key will be included in the zone but will
+ not be used to sign it.
+ </p></dd>
+<dt><span class="term">-A <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be activated. After that
+ date, the key will be included in the zone and used to sign
+ it.
+ </p></dd>
+<dt><span class="term">-R <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be revoked. After that
+ date, the key will be flagged as revoked. It will be included
+ in the zone and will be used to sign it.
+ </p></dd>
+<dt><span class="term">-I <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be retired. After that
+ date, the key will still be included in the zone, but it
+ will not be used to sign it.
+ </p></dd>
+<dt><span class="term">-D <em class="replaceable"><code>date/offset</code></em></span></dt>
+<dd><p>
+ Sets the date on which the key is to be deleted. After that
+ date, the key will no longer be included in the zone. (It
+ may remain in the key repository, however.)
+ </p></dd>
+<dt><span class="term">-S <em class="replaceable"><code>predecessor key</code></em></span></dt>
+<dd><p>
+ Select a key for which the key being modified will be an
+ explicit successor. The name, algorithm, size, and type of the
+ predecessor key must exactly match those of the key being
+ modified. The activation date of the successor key will be set
+ to the inactivation date of the predecessor. The publication
+ date will be set to the activation date minus the prepublication
+ interval, which defaults to 30 days.
+ </p></dd>
+<dt><span class="term">-i <em class="replaceable"><code>interval</code></em></span></dt>
+<dd>
+<p>
+ Sets the prepublication interval for a key. If set, then
+ the publication and activation dates must be separated by at least
+ this much time. If the activation date is specified but the
+ publication date isn't, then the publication date will default
+ to this much time before the activation date; conversely, if
+ the publication date is specified but activation date isn't,
+ then activation will be set to this much time after publication.
+ </p>
+<p>
+ If the key is being set to be an explicit successor to another
+ key, then the default prepublication interval is 30 days;
+ otherwise it is zero.
+ </p>
+<p>
+ As with date offsets, if the argument is followed by one of
+ the suffixes 'y', 'mo', 'w', 'd', 'h', or 'mi', then the
+ interval is measured in years, months, weeks, days, hours,
+ or minutes, respectively. Without a suffix, the interval is
+ measured in seconds.
+ </p>
+</dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2615598"></a><h2>PRINTING OPTIONS</h2>
+<p>
+ <span><strong class="command">dnssec-settime</strong></span> can also be used to print the
+ timing metadata associated with a key.
+ </p>
+<div class="variablelist"><dl>
+<dt><span class="term">-u</span></dt>
+<dd><p>
+ Print times in UNIX epoch format.
+ </p></dd>
+<dt><span class="term">-p <em class="replaceable"><code>C/P/A/R/I/D/all</code></em></span></dt>
+<dd><p>
+ Print a specific metadata value or set of metadata values.
+ The <code class="option">-p</code> option may be followed by one or more
+ of the following letters to indicate which value or values to print:
+ <code class="option">C</code> for the creation date,
+ <code class="option">P</code> for the publication date,
+ <code class="option">A</code> for the activation date,
+ <code class="option">R</code> for the revocation date,
+ <code class="option">I</code> for the inactivation date, or
+ <code class="option">D</code> for the deletion date.
+ To print all of the metadata, use <code class="option">-p all</code>.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2615678"></a><h2>SEE ALSO</h2>
+<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
+ <span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>,
+ <em class="citetitle">RFC 5011</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2615712"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div>
+<div class="navfooter">
+<hr>
+<table width="100%" summary="Navigation footer">
+<tr>
+<td width="40%" align="left">
+<a accesskey="p" href="man.dnssec-revoke.html">Prev</a> </td>
+<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
+<td width="40%" align="right"> <a accesskey="n" href="man.dnssec-signzone.html">Next</a>
+</td>
+</tr>
+<tr>
+<td width="40%" align="left" valign="top">
+<span class="application">dnssec-revoke</span> </td>
+<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
+<td width="40%" align="right" valign="top"> <span class="application">dnssec-signzone</span>
+</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/arm/man.dnssec-signzone.html b/doc/arm/man.dnssec-signzone.html
index 42bf06849b95..05cea6e9c4ba 100644
--- a/doc/arm/man.dnssec-signzone.html
+++ b/doc/arm/man.dnssec-signzone.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.dnssec-signzone.html,v 1.94.14.25 2010-08-20 02:05:39 tbox Exp $ -->
+<!-- $Id: man.dnssec-signzone.html,v 1.179.8.1.2.1 2011-06-09 03:41:10 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
-<link rel="prev" href="man.dnssec-keygen.html" title="dnssec-keygen">
+<link rel="prev" href="man.dnssec-settime.html" title="dnssec-settime">
<link rel="next" href="man.named-checkconf.html" title="named-checkconf">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@@ -31,7 +31,7 @@
<tr><th colspan="3" align="center"><span class="application">dnssec-signzone</span></th></tr>
<tr>
<td width="20%" align="left">
-<a accesskey="p" href="man.dnssec-keygen.html">Prev</a> </td>
+<a accesskey="p" href="man.dnssec-settime.html">Prev</a> </td>
<th width="60%" align="center">Manual pages</th>
<td width="20%" align="right"> <a accesskey="n" href="man.named-checkconf.html">Next</a>
</td>
@@ -47,21 +47,21 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-P</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-t</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-z</code>] [<code class="option">-3 <em class="replaceable"><code>salt</code></em></code>] [<code class="option">-H <em class="replaceable"><code>iterations</code></em></code>] [<code class="option">-A</code>] {zonefile} [key...]</p></div>
+<div class="cmdsynopsis"><p><code class="command">dnssec-signzone</code> [<code class="option">-a</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-d <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine</code></em></code>] [<code class="option">-e <em class="replaceable"><code>end-time</code></em></code>] [<code class="option">-f <em class="replaceable"><code>output-file</code></em></code>] [<code class="option">-g</code>] [<code class="option">-h</code>] [<code class="option">-K <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-k <em class="replaceable"><code>key</code></em></code>] [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-i <em class="replaceable"><code>interval</code></em></code>] [<code class="option">-I <em class="replaceable"><code>input-format</code></em></code>] [<code class="option">-j <em class="replaceable"><code>jitter</code></em></code>] [<code class="option">-N <em class="replaceable"><code>soa-serial-format</code></em></code>] [<code class="option">-o <em class="replaceable"><code>origin</code></em></code>] [<code class="option">-O <em class="replaceable"><code>output-format</code></em></code>] [<code class="option">-p</code>] [<code class="option">-P</code>] [<code class="option">-r <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-S</code>] [<code class="option">-s <em class="replaceable"><code>start-time</code></em></code>] [<code class="option">-T <em class="replaceable"><code>ttl</code></em></code>] [<code class="option">-t</code>] [<code class="option">-u</code>] [<code class="option">-v <em class="replaceable"><code>level</code></em></code>] [<code class="option">-x</code>] [<code class="option">-z</code>] [<code class="option">-3 <em class="replaceable"><code>salt</code></em></code>] [<code class="option">-H <em class="replaceable"><code>iterations</code></em></code>] [<code class="option">-A</code>] {zonefile} [key...]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2607637"></a><h2>DESCRIPTION</h2>
+<a name="id2616507"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">dnssec-signzone</strong></span>
signs a zone. It generates
NSEC and RRSIG records and produces a signed version of the
- zone. It also generates a <code class="filename">keyset-</code> file containing
- the key-signing keys for the zone, and if signing a zone which
- contains delegations, it can optionally generate DS records for
- the child zones from their <code class="filename">keyset-</code> files.
+ zone. The security status of delegations from the signed zone
+ (that is, whether the child zones are secure or not) is
+ determined by the presence or absence of a
+ <code class="filename">keyset</code> file for each child zone.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2607661"></a><h2>OPTIONS</h2>
+<a name="id2617346"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd><p>
@@ -71,6 +71,38 @@
<dd><p>
Specifies the DNS class of the zone.
</p></dd>
+<dt><span class="term">-C</span></dt>
+<dd><p>
+ Compatibility mode: Generate a
+ <code class="filename">keyset-<em class="replaceable"><code>zonename</code></em></code>
+ file in addition to
+ <code class="filename">dsset-<em class="replaceable"><code>zonename</code></em></code>
+ when signing a zone, for use by older versions of
+ <span><strong class="command">dnssec-signzone</strong></span>.
+ </p></dd>
+<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Look for <code class="filename">dsset-</code> or
+ <code class="filename">keyset-</code> files in <code class="option">directory</code>.
+ </p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine</code></em></span></dt>
+<dd><p>
+ Uses a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ it defaults to pkcs11; the empty name resets it to no engine.
+ </p></dd>
+<dt><span class="term">-g</span></dt>
+<dd><p>
+ Generate DS records for child zones from
+ <code class="filename">dsset-</code> or <code class="filename">keyset-</code>
+ file. Existing DS records will be removed.
+ </p></dd>
+<dt><span class="term">-K <em class="replaceable"><code>directory</code></em></span></dt>
+<dd><p>
+ Key repository: Specify a directory to search for DNSSEC keys.
+ If not specified, defaults to the current directory.
+ </p></dd>
<dt><span class="term">-k <em class="replaceable"><code>key</code></em></span></dt>
<dd><p>
Treat specified key as a key signing key ignoring any
@@ -81,18 +113,6 @@
Generate a DLV set in addition to the key (DNSKEY) and DS sets.
The domain is appended to the name of the records.
</p></dd>
-<dt><span class="term">-d <em class="replaceable"><code>directory</code></em></span></dt>
-<dd><p>
- Look for <code class="filename">keyset</code> files in
- <code class="option">directory</code> as the directory
- </p></dd>
-<dt><span class="term">-g</span></dt>
-<dd><p>
- If the zone contains any delegations, and there are
- <code class="filename">keyset-</code> files for any of the child zones,
- then DS records for the child zones will be generated from the
- keys in those files. Existing DS records will be removed.
- </p></dd>
<dt><span class="term">-s <em class="replaceable"><code>start-time</code></em></span></dt>
<dd><p>
Specify the date and time when the generated RRSIG records
@@ -113,6 +133,8 @@
the start time. A time relative to the current time is
indicated with now+N. If no <code class="option">end-time</code> is
specified, 30 days from the start time is used as a default.
+ <code class="option">end-time</code> must be later than
+ <code class="option">start-time</code>.
</p></dd>
<dt><span class="term">-f <em class="replaceable"><code>output-file</code></em></span></dt>
<dd><p>
@@ -247,35 +269,119 @@
<code class="filename">keyboard</code> indicates that keyboard
input should be used.
</p></dd>
+<dt><span class="term">-S</span></dt>
+<dd>
+<p>
+ Smart signing: Instructs <span><strong class="command">dnssec-signzone</strong></span> to
+ search the key repository for keys that match the zone being
+ signed, and to include them in the zone if appropriate.
+ </p>
+<p>
+ When a key is found, its timing metadata is examined to
+ determine how it should be used, according to the following
+ rules. Each successive rule takes priority over the prior
+ ones:
+ </p>
+<div class="variablelist"><dl>
+<dt></dt>
+<dd><p>
+ If no timing metadata has been set for the key, the key is
+ published in the zone and used to sign the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If the key's publication date is set and is in the past, the
+ key is published in the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If the key's activation date is set and in the past, the
+ key is published (regardless of publication date) and
+ used to sign the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If the key's revocation date is set and in the past, and the
+ key is published, then the key is revoked, and the revoked key
+ is used to sign the zone.
+ </p></dd>
+<dt></dt>
+<dd><p>
+ If either of the key's unpublication or deletion dates are set
+ and in the past, the key is NOT published or used to sign the
+ zone, regardless of any other metadata.
+ </p></dd>
+</dl></div>
+</dd>
+<dt><span class="term">-T <em class="replaceable"><code>ttl</code></em></span></dt>
+<dd><p>
+ Specifies the TTL to be used for new DNSKEY records imported
+ into the zone from the key repository. If not specified,
+ the default is the minimum TTL value from the zone's SOA
+ record. This option is ignored when signing without
+ <code class="option">-S</code>, since DNSKEY records are not imported
+ from the key repository in that case. It is also ignored if
+ there are any pre-existing DNSKEY records at the zone apex,
+ in which case new records' TTL values will be set to match
+ them.
+ </p></dd>
<dt><span class="term">-t</span></dt>
<dd><p>
Print statistics at completion.
</p></dd>
+<dt><span class="term">-u</span></dt>
+<dd><p>
+ Update NSEC/NSEC3 chain when re-signing a previously signed
+ zone. With this option, a zone signed with NSEC can be
+ switched to NSEC3, or a zone signed with NSEC3 can
+ be switch to NSEC or to NSEC3 with different parameters.
+ Without this option, <span><strong class="command">dnssec-signzone</strong></span> will
+ retain the existing chain when re-signing.
+ </p></dd>
<dt><span class="term">-v <em class="replaceable"><code>level</code></em></span></dt>
<dd><p>
Sets the debugging level.
</p></dd>
+<dt><span class="term">-x</span></dt>
+<dd><p>
+ Only sign the DNSKEY RRset with key-signing keys, and omit
+ signatures from zone-signing keys. (This is similar to the
+ <span><strong class="command">dnssec-dnskey-kskonly yes;</strong></span> zone option in
+ <span><strong class="command">named</strong></span>.)
+ </p></dd>
<dt><span class="term">-z</span></dt>
<dd><p>
- Ignore KSK flag on key when determining what to sign.
+ Ignore KSK flag on key when determining what to sign. This
+ causes KSK-flagged keys to sign all records, not just the
+ DNSKEY RRset. (This is similar to the
+ <span><strong class="command">update-check-ksk no;</strong></span> zone option in
+ <span><strong class="command">named</strong></span>.)
</p></dd>
<dt><span class="term">-3 <em class="replaceable"><code>salt</code></em></span></dt>
<dd><p>
- Generate a NSEC3 chain with the given hex encoded salt.
+ Generate an NSEC3 chain with the given hex encoded salt.
A dash (<em class="replaceable"><code>salt</code></em>) can
be used to indicate that no salt is to be used when generating the NSEC3 chain.
</p></dd>
<dt><span class="term">-H <em class="replaceable"><code>iterations</code></em></span></dt>
<dd><p>
- When generating a NSEC3 chain use this many interations. The
- default is 100.
+ When generating an NSEC3 chain, use this many interations. The
+ default is 10.
</p></dd>
<dt><span class="term">-A</span></dt>
-<dd><p>
- When generating a NSEC3 chain set the OPTOUT flag on all
+<dd>
+<p>
+ When generating an NSEC3 chain set the OPTOUT flag on all
NSEC3 records and do not generate NSEC3 records for insecure
delegations.
- </p></dd>
+ </p>
+<p>
+ Using this option twice (i.e., <code class="option">-AA</code>)
+ turns the OPTOUT flag off for all records. This is useful
+ when using the <code class="option">-u</code> option to modify an NSEC3
+ chain which previously had OPTOUT set.
+ </p>
+</dd>
<dt><span class="term">zonefile</span></dt>
<dd><p>
The file containing the zone to be signed.
@@ -291,14 +397,15 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2659554"></a><h2>EXAMPLE</h2>
+<a name="id2671803"></a><h2>EXAMPLE</h2>
<p>
The following command signs the <strong class="userinput"><code>example.com</code></strong>
zone with the DSA key generated by <span><strong class="command">dnssec-keygen</strong></span>
- (Kexample.com.+003+17247). The zone's keys must be in the master
- file (<code class="filename">db.example.com</code>). This invocation looks
- for <code class="filename">keyset</code> files, in the current directory,
- so that DS records can be generated from them (<span><strong class="command">-g</strong></span>).
+ (Kexample.com.+003+17247). Because the <span><strong class="command">-S</strong></span> option
+ is not being used, the zone's keys must be in the master file
+ (<code class="filename">db.example.com</code>). This invocation looks
+ for <code class="filename">dsset</code> files, in the current directory,
+ so that DS records can be imported from them (<span><strong class="command">-g</strong></span>).
</p>
<pre class="programlisting">% dnssec-signzone -g -o example.com db.example.com \
Kexample.com.+003+17247
@@ -320,39 +427,14 @@ db.example.com.signed
%</pre>
</div>
<div class="refsect1" lang="en">
-<a name="id2659694"></a><h2>KNOWN BUGS</h2>
-<p>
- <span><strong class="command">dnssec-signzone</strong></span> was designed so that it could
- sign a zone partially, using only a subset of the DNSSEC keys
- needed to produce a fully-signed zone. This permits a zone
- administrator, for example, to sign a zone with one key on one
- machine, move the resulting partially-signed zone to a second
- machine, and sign it again with a second key.
- </p>
-<p>
- An unfortunate side-effect of this flexibility is that
- <span><strong class="command">dnssec-signzone</strong></span> does not check to make sure
- it's signing a zone with any valid keys at all. An attempt to
- sign a zone without any keys will appear to succeed, producing
- a "signed" zone with no signatures. There is no warning issued
- when a zone is not fully signed.
- </p>
-<p>
- This will be corrected in a future release. In the meantime, ISC
- recommends examining the output of <span><strong class="command">dnssec-signzone</strong></span>
- to confirm that the zone is properly signed by all keys before
- using it.
- </p>
-</div>
-<div class="refsect1" lang="en">
-<a name="id2659726"></a><h2>SEE ALSO</h2>
+<a name="id2671882"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>,
<em class="citetitle">RFC 4033</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2659751"></a><h2>AUTHOR</h2>
+<a name="id2671907"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
@@ -362,14 +444,14 @@ db.example.com.signed
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
-<a accesskey="p" href="man.dnssec-keygen.html">Prev</a> </td>
+<a accesskey="p" href="man.dnssec-settime.html">Prev</a> </td>
<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
<td width="40%" align="right"> <a accesskey="n" href="man.named-checkconf.html">Next</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">
-<span class="application">dnssec-keygen</span> </td>
+<span class="application">dnssec-settime</span> </td>
<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
<td width="40%" align="right" valign="top"> <span class="application">named-checkconf</span>
</td>
diff --git a/doc/arm/man.genrandom.html b/doc/arm/man.genrandom.html
new file mode 100644
index 000000000000..c9ecc8e4c232
--- /dev/null
+++ b/doc/arm/man.genrandom.html
@@ -0,0 +1,112 @@
+<!--
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2000-2003 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: man.genrandom.html,v 1.34.8.1.2.1 2011-06-09 03:41:11 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>genrandom</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
+<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
+<link rel="prev" href="man.arpaname.html" title="arpaname">
+<link rel="next" href="man.isc-hmac-fixup.html" title="isc-hmac-fixup">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table width="100%" summary="Navigation header">
+<tr><th colspan="3" align="center"><span class="application">genrandom</span></th></tr>
+<tr>
+<td width="20%" align="left">
+<a accesskey="p" href="man.arpaname.html">Prev</a> </td>
+<th width="60%" align="center">Manual pages</th>
+<td width="20%" align="right"> <a accesskey="n" href="man.isc-hmac-fixup.html">Next</a>
+</td>
+</tr>
+</table>
+<hr>
+</div>
+<div class="refentry" lang="en">
+<a name="man.genrandom"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">genrandom</span> &#8212; generate a file containing random data</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">genrandom</code> [<code class="option">-n <em class="replaceable"><code>number</code></em></code>] {<em class="replaceable"><code>size</code></em>} {<em class="replaceable"><code>filename</code></em>}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2649447"></a><h2>DESCRIPTION</h2>
+<p>
+ <span><strong class="command">genrandom</strong></span>
+ generates a file or a set of files containing a specified quantity
+ of pseudo-random data, which can be used as a source of entropy for
+ other commands on systems with no random device.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2649462"></a><h2>ARGUMENTS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">-n <em class="replaceable"><code>number</code></em></span></dt>
+<dd><p>
+ In place of generating one file, generates <code class="option">number</code>
+ (from 2 to 9) files, appending <code class="option">number</code> to the name.
+ </p></dd>
+<dt><span class="term">size</span></dt>
+<dd><p>
+ The size of the file, in kilobytes, to generate.
+ </p></dd>
+<dt><span class="term">domain</span></dt>
+<dd><p>
+ The file name into which random data should be written.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2649523"></a><h2>SEE ALSO</h2>
+<p>
+ <span class="citerefentry"><span class="refentrytitle">rand</span>(3)</span>,
+ <span class="citerefentry"><span class="refentrytitle">arc4random</span>(3)</span>
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2649549"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div>
+<div class="navfooter">
+<hr>
+<table width="100%" summary="Navigation footer">
+<tr>
+<td width="40%" align="left">
+<a accesskey="p" href="man.arpaname.html">Prev</a> </td>
+<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
+<td width="40%" align="right"> <a accesskey="n" href="man.isc-hmac-fixup.html">Next</a>
+</td>
+</tr>
+<tr>
+<td width="40%" align="left" valign="top">
+<span class="application">arpaname</span> </td>
+<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
+<td width="40%" align="right" valign="top"> <span class="application">isc-hmac-fixup</span>
+</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/arm/man.host.html b/doc/arm/man.host.html
index 990d67e452a8..73223532cc54 100644
--- a/doc/arm/man.host.html
+++ b/doc/arm/man.host.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.host.html,v 1.93.14.17 2010-08-20 02:05:40 tbox Exp $ -->
+<!-- $Id: man.host.html,v 1.160.8.1.2.1 2011-06-09 03:41:09 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">host</code> [<code class="option">-aCdlnrsTwv</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-N <em class="replaceable"><code>ndots</code></em></code>] [<code class="option">-R <em class="replaceable"><code>number</code></em></code>] [<code class="option">-t <em class="replaceable"><code>type</code></em></code>] [<code class="option">-W <em class="replaceable"><code>wait</code></em></code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-4</code>] [<code class="option">-6</code>] {name} [server]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2603383"></a><h2>DESCRIPTION</h2>
+<a name="id2610368"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">host</strong></span>
is a simple utility for performing DNS lookups.
It is normally used to convert names to IP addresses and vice versa.
@@ -202,7 +202,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2603897"></a><h2>IDN SUPPORT</h2>
+<a name="id2610882"></a><h2>IDN SUPPORT</h2>
<p>
If <span><strong class="command">host</strong></span> has been built with IDN (internationalized
domain name) support, it can accept and display non-ASCII domain names.
@@ -216,12 +216,12 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2603926"></a><h2>FILES</h2>
+<a name="id2610910"></a><h2>FILES</h2>
<p><code class="filename">/etc/resolv.conf</code>
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2603940"></a><h2>SEE ALSO</h2>
+<a name="id2610924"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">dig</span>(1)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>.
</p>
diff --git a/doc/arm/man.isc-hmac-fixup.html b/doc/arm/man.isc-hmac-fixup.html
new file mode 100644
index 000000000000..bff6e912e4be
--- /dev/null
+++ b/doc/arm/man.isc-hmac-fixup.html
@@ -0,0 +1,122 @@
+<!--
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2000-2003 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: man.isc-hmac-fixup.html,v 1.31.8.1.2.1 2011-06-09 03:41:11 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>isc-hmac-fixup</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
+<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
+<link rel="prev" href="man.genrandom.html" title="genrandom">
+<link rel="next" href="man.nsec3hash.html" title="nsec3hash">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table width="100%" summary="Navigation header">
+<tr><th colspan="3" align="center"><span class="application">isc-hmac-fixup</span></th></tr>
+<tr>
+<td width="20%" align="left">
+<a accesskey="p" href="man.genrandom.html">Prev</a> </td>
+<th width="60%" align="center">Manual pages</th>
+<td width="20%" align="right"> <a accesskey="n" href="man.nsec3hash.html">Next</a>
+</td>
+</tr>
+</table>
+<hr>
+</div>
+<div class="refentry" lang="en">
+<a name="man.isc-hmac-fixup"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">isc-hmac-fixup</span> &#8212; fixes HMAC keys generated by older versions of BIND</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">isc-hmac-fixup</code> {<em class="replaceable"><code>algorithm</code></em>} {<em class="replaceable"><code>secret</code></em>}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2650556"></a><h2>DESCRIPTION</h2>
+<p>
+ Versions of BIND 9 up to and including BIND 9.6 had a bug causing
+ HMAC-SHA* TSIG keys which were longer than the digest length of the
+ hash algorithm (i.e., SHA1 keys longer than 160 bits, SHA256 keys
+ longer than 256 bits, etc) to be used incorrectly, generating a
+ message authentication code that was incompatible with other DNS
+ implementations.
+ </p>
+<p>
+ This bug has been fixed in BIND 9.7. However, the fix may
+ cause incompatibility between older and newer versions of
+ BIND, when using long keys. <span><strong class="command">isc-hmac-fixup</strong></span>
+ modifies those keys to restore compatibility.
+ </p>
+<p>
+ To modify a key, run <span><strong class="command">isc-hmac-fixup</strong></span> and
+ specify the key's algorithm and secret on the command line. If the
+ secret is longer than the digest length of the algorithm (64 bytes
+ for SHA1 through SHA256, or 128 bytes for SHA384 and SHA512), then a
+ new secret will be generated consisting of a hash digest of the old
+ secret. (If the secret did not require conversion, then it will be
+ printed without modification.)
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2650584"></a><h2>SECURITY CONSIDERATIONS</h2>
+<p>
+ Secrets that have been converted by <span><strong class="command">isc-hmac-fixup</strong></span>
+ are shortened, but as this is how the HMAC protocol works in
+ operation anyway, it does not affect security. RFC 2104 notes,
+ "Keys longer than [the digest length] are acceptable but the
+ extra length would not significantly increase the function
+ strength."
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2650600"></a><h2>SEE ALSO</h2>
+<p>
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>,
+ <em class="citetitle">RFC 2104</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2650617"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div>
+<div class="navfooter">
+<hr>
+<table width="100%" summary="Navigation footer">
+<tr>
+<td width="40%" align="left">
+<a accesskey="p" href="man.genrandom.html">Prev</a> </td>
+<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
+<td width="40%" align="right"> <a accesskey="n" href="man.nsec3hash.html">Next</a>
+</td>
+</tr>
+<tr>
+<td width="40%" align="left" valign="top">
+<span class="application">genrandom</span> </td>
+<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
+<td width="40%" align="right" valign="top"> <span class="application">nsec3hash</span>
+</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/arm/man.named-checkconf.html b/doc/arm/man.named-checkconf.html
index 8bf240bd3a73..d6eff94cc2a3 100644
--- a/doc/arm/man.named-checkconf.html
+++ b/doc/arm/man.named-checkconf.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.named-checkconf.html,v 1.92.14.22 2010-08-20 02:05:39 tbox Exp $ -->
+<!-- $Id: man.named-checkconf.html,v 1.174.8.1.2.1 2011-06-09 03:41:10 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,17 +47,30 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">named-checkconf</code> [<code class="option">-h</code>] [<code class="option">-v</code>] [<code class="option">-j</code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] {filename} [<code class="option">-z</code>]</p></div>
+<div class="cmdsynopsis"><p><code class="command">named-checkconf</code> [<code class="option">-h</code>] [<code class="option">-v</code>] [<code class="option">-j</code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] {filename} [<code class="option">-p</code>] [<code class="option">-z</code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2608468"></a><h2>DESCRIPTION</h2>
+<a name="id2617782"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named-checkconf</strong></span>
- checks the syntax, but not the semantics, of a named
- configuration file.
+ checks the syntax, but not the semantics, of a
+ <span><strong class="command">named</strong></span> configuration file. The file is parsed
+ and checked for syntax errors, along with all files included by it.
+ If no file is specified, <code class="filename">/etc/named.conf</code> is read
+ by default.
+ </p>
+<p>
+ Note: files that <span><strong class="command">named</strong></span> reads in separate
+ parser contexts, such as <code class="filename">rndc.key</code> and
+ <code class="filename">bind.keys</code>, are not automatically read
+ by <span><strong class="command">named-checkconf</strong></span>. Configuration
+ errors in these files may cause <span><strong class="command">named</strong></span> to
+ fail to run, even if <span><strong class="command">named-checkconf</strong></span> was
+ successful. <span><strong class="command">named-checkconf</strong></span> can be run
+ on these files explicitly, however.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608482"></a><h2>OPTIONS</h2>
+<a name="id2617852"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-h</span></dt>
<dd><p>
@@ -65,8 +78,7 @@
</p></dd>
<dt><span class="term">-t <em class="replaceable"><code>directory</code></em></span></dt>
<dd><p>
- Chroot to <code class="filename">directory</code> so that
- include
+ Chroot to <code class="filename">directory</code> so that include
directives in the configuration file are processed as if
run by a similarly chrooted named.
</p></dd>
@@ -75,6 +87,11 @@
Print the version of the <span><strong class="command">named-checkconf</strong></span>
program and exit.
</p></dd>
+<dt><span class="term">-p</span></dt>
+<dd><p>
+ Print out the <code class="filename">named.conf</code> and included files
+ in canonical form if no errors were detected.
+ </p></dd>
<dt><span class="term">-z</span></dt>
<dd><p>
Perform a test load of all master zones found in
@@ -92,21 +109,21 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2608598"></a><h2>RETURN VALUES</h2>
+<a name="id2617987"></a><h2>RETURN VALUES</h2>
<p><span><strong class="command">named-checkconf</strong></span>
returns an exit status of 1 if
errors were detected and 0 otherwise.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608885"></a><h2>SEE ALSO</h2>
+<a name="id2618001"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkzone</span>(8)</span>,
<em class="citetitle">BIND 9 Administrator Reference Manual</em>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2608915"></a><h2>AUTHOR</h2>
+<a name="id2618030"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.named-checkzone.html b/doc/arm/man.named-checkzone.html
index aeaf7d363c1b..e7d9dc175687 100644
--- a/doc/arm/man.named-checkzone.html
+++ b/doc/arm/man.named-checkzone.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.named-checkzone.html,v 1.98.14.22 2010-08-20 02:05:37 tbox Exp $ -->
+<!-- $Id: man.named-checkzone.html,v 1.183.8.1.2.1 2011-06-09 03:41:10 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -47,11 +47,11 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">named-checkzone</code> [<code class="option">-d</code>] [<code class="option">-h</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-M <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-S <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
-<div class="cmdsynopsis"><p><code class="command">named-compilezone</code> [<code class="option">-d</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-C <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {<code class="option">-o <em class="replaceable"><code>filename</code></em></code>} {zonename} {filename}</p></div>
+<div class="cmdsynopsis"><p><code class="command">named-checkzone</code> [<code class="option">-d</code>] [<code class="option">-h</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-M <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-o <em class="replaceable"><code>filename</code></em></code>] [<code class="option">-r <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-S <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {zonename} {filename}</p></div>
+<div class="cmdsynopsis"><p><code class="command">named-compilezone</code> [<code class="option">-d</code>] [<code class="option">-j</code>] [<code class="option">-q</code>] [<code class="option">-v</code>] [<code class="option">-c <em class="replaceable"><code>class</code></em></code>] [<code class="option">-C <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-f <em class="replaceable"><code>format</code></em></code>] [<code class="option">-F <em class="replaceable"><code>format</code></em></code>] [<code class="option">-i <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-k <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-m <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-n <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-r <em class="replaceable"><code>mode</code></em></code>] [<code class="option">-s <em class="replaceable"><code>style</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-w <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-D</code>] [<code class="option">-W <em class="replaceable"><code>mode</code></em></code>] {<code class="option">-o <em class="replaceable"><code>filename</code></em></code>} {zonename} {filename}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2609661"></a><h2>DESCRIPTION</h2>
+<a name="id2619464"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named-checkzone</strong></span>
checks the syntax and integrity of a zone file. It performs the
same checks as <span><strong class="command">named</strong></span> does when loading a
@@ -71,7 +71,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2609712"></a><h2>OPTIONS</h2>
+<a name="id2619514"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-d</span></dt>
<dd><p>
@@ -195,6 +195,14 @@
write to standard out.
This is mandatory for <span><strong class="command">named-compilezone</strong></span>.
</p></dd>
+<dt><span class="term">-r <em class="replaceable"><code>mode</code></em></span></dt>
+<dd><p>
+ Check for records that are treated as different by DNSSEC but
+ are semantically equal in plain DNS.
+ Possible modes are <span><strong class="command">"fail"</strong></span>,
+ <span><strong class="command">"warn"</strong></span> (default) and
+ <span><strong class="command">"ignore"</strong></span>.
+ </p></dd>
<dt><span class="term">-s <em class="replaceable"><code>style</code></em></span></dt>
<dd><p>
Specify the style of the dumped zone file.
@@ -257,14 +265,14 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2660557"></a><h2>RETURN VALUES</h2>
+<a name="id2672646"></a><h2>RETURN VALUES</h2>
<p><span><strong class="command">named-checkzone</strong></span>
returns an exit status of 1 if
errors were detected and 0 otherwise.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2660571"></a><h2>SEE ALSO</h2>
+<a name="id2672660"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkconf</span>(8)</span>,
<em class="citetitle">RFC 1035</em>,
@@ -272,7 +280,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2660604"></a><h2>AUTHOR</h2>
+<a name="id2672693"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.named-journalprint.html b/doc/arm/man.named-journalprint.html
new file mode 100644
index 000000000000..11d98a116c66
--- /dev/null
+++ b/doc/arm/man.named-journalprint.html
@@ -0,0 +1,112 @@
+<!--
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2000-2003 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: man.named-journalprint.html,v 1.33.8.1.2.1 2011-06-09 03:41:10 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>named-journalprint</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
+<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
+<link rel="prev" href="man.named.html" title="named">
+<link rel="next" href="man.nsupdate.html" title="nsupdate">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table width="100%" summary="Navigation header">
+<tr><th colspan="3" align="center"><span class="application">named-journalprint</span></th></tr>
+<tr>
+<td width="20%" align="left">
+<a accesskey="p" href="man.named.html">Prev</a> </td>
+<th width="60%" align="center">Manual pages</th>
+<td width="20%" align="right"> <a accesskey="n" href="man.nsupdate.html">Next</a>
+</td>
+</tr>
+</table>
+<hr>
+</div>
+<div class="refentry" lang="en">
+<a name="man.named-journalprint"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">named-journalprint</span> &#8212; print zone journal in human-readable form</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">named-journalprint</code> {<em class="replaceable"><code>journal</code></em>}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2613314"></a><h2>DESCRIPTION</h2>
+<p>
+ <span><strong class="command">named-journalprint</strong></span>
+ prints the contents of a zone journal file in a human-readable
+ form.
+ </p>
+<p>
+ Journal files are automatically created by <span><strong class="command">named</strong></span>
+ when changes are made to dynamic zones (e.g., by
+ <span><strong class="command">nsupdate</strong></span>). They record each addition
+ or deletion of a resource record, in binary format, allowing the
+ changes to be re-applied to the zone when the server is
+ restarted after a shutdown or crash. By default, the name of
+ the journal file is formed by appending the extension
+ <code class="filename">.jnl</code> to the name of the corresponding
+ zone file.
+ </p>
+<p>
+ <span><strong class="command">named-journalprint</strong></span> converts the contents of a given
+ journal file into a human-readable text format. Each line begins
+ with "add" or "del", to indicate whether the record was added or
+ deleted, and continues with the resource record in master-file
+ format.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2638550"></a><h2>SEE ALSO</h2>
+<p>
+ <span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
+ <span class="citerefentry"><span class="refentrytitle">nsupdate</span>(8)</span>,
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2638581"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div>
+<div class="navfooter">
+<hr>
+<table width="100%" summary="Navigation footer">
+<tr>
+<td width="40%" align="left">
+<a accesskey="p" href="man.named.html">Prev</a> </td>
+<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
+<td width="40%" align="right"> <a accesskey="n" href="man.nsupdate.html">Next</a>
+</td>
+</tr>
+<tr>
+<td width="40%" align="left" valign="top">
+<span class="application">named</span> </td>
+<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
+<td width="40%" align="right" valign="top"> <span class="application">nsupdate</span>
+</td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/arm/man.named.html b/doc/arm/man.named.html
index 9a5617f2ed5d..ac45d416fe44 100644
--- a/doc/arm/man.named.html
+++ b/doc/arm/man.named.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.named.html,v 1.99.14.22 2010-08-20 02:05:37 tbox Exp $ -->
+<!-- $Id: man.named.html,v 1.185.8.1.2.1 2011-06-09 03:41:10 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -23,7 +23,7 @@
<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
<link rel="prev" href="man.named-checkzone.html" title="named-checkzone">
-<link rel="next" href="man.nsupdate.html" title="nsupdate">
+<link rel="next" href="man.named-journalprint.html" title="named-journalprint">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
@@ -33,7 +33,7 @@
<td width="20%" align="left">
<a accesskey="p" href="man.named-checkzone.html">Prev</a> </td>
<th width="60%" align="center">Manual pages</th>
-<td width="20%" align="right"> <a accesskey="n" href="man.nsupdate.html">Next</a>
+<td width="20%" align="right"> <a accesskey="n" href="man.named-journalprint.html">Next</a>
</td>
</tr>
</table>
@@ -47,10 +47,10 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">named</code> [<code class="option">-4</code>] [<code class="option">-6</code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-S <em class="replaceable"><code>#max-socks</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>] [<code class="option">-V</code>] [<code class="option">-x <em class="replaceable"><code>cache-file</code></em></code>]</p></div>
+<div class="cmdsynopsis"><p><code class="command">named</code> [<code class="option">-4</code>] [<code class="option">-6</code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine-name</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-S <em class="replaceable"><code>#max-socks</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>] [<code class="option">-V</code>] [<code class="option">-x <em class="replaceable"><code>cache-file</code></em></code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2610009"></a><h2>DESCRIPTION</h2>
+<a name="id2638058"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named</strong></span>
is a Domain Name System (DNS) server,
part of the BIND 9 distribution from ISC. For more
@@ -65,7 +65,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2610040"></a><h2>OPTIONS</h2>
+<a name="id2638089"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-4</span></dt>
<dd><p>
@@ -97,6 +97,14 @@
Debugging traces from <span><strong class="command">named</strong></span> become
more verbose as the debug level increases.
</p></dd>
+<dt><span class="term">-E <em class="replaceable"><code>engine-name</code></em></span></dt>
+<dd><p>
+ Use a crypto hardware (OpenSSL engine) for the crypto operations
+ it supports, for instance re-signing with private keys from
+ a secure key store. When compiled with PKCS#11 support
+ <em class="replaceable"><code>engine-name</code></em>
+ defaults to pkcs11, the empty name resets it to no engine.
+ </p></dd>
<dt><span class="term">-f</span></dt>
<dd><p>
Run the server in the foreground (i.e. do not daemonize).
@@ -238,7 +246,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2612619"></a><h2>SIGNALS</h2>
+<a name="id2640076"></a><h2>SIGNALS</h2>
<p>
In routine operation, signals should not be used to control
the nameserver; <span><strong class="command">rndc</strong></span> should be used
@@ -259,7 +267,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2652264"></a><h2>CONFIGURATION</h2>
+<a name="id2640126"></a><h2>CONFIGURATION</h2>
<p>
The <span><strong class="command">named</strong></span> configuration file is too complex
to describe in detail here. A complete description is provided
@@ -276,7 +284,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2652313"></a><h2>FILES</h2>
+<a name="id2674514"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="filename">/etc/named.conf</code></span></dt>
<dd><p>
@@ -289,7 +297,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2652357"></a><h2>SEE ALSO</h2>
+<a name="id2674694"></a><h2>SEE ALSO</h2>
<p><em class="citetitle">RFC 1033</em>,
<em class="citetitle">RFC 1034</em>,
<em class="citetitle">RFC 1035</em>,
@@ -302,7 +310,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2652427"></a><h2>AUTHOR</h2>
+<a name="id2674764"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
@@ -314,14 +322,14 @@
<td width="40%" align="left">
<a accesskey="p" href="man.named-checkzone.html">Prev</a> </td>
<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
-<td width="40%" align="right"> <a accesskey="n" href="man.nsupdate.html">Next</a>
+<td width="40%" align="right"> <a accesskey="n" href="man.named-journalprint.html">Next</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">
<span class="application">named-checkzone</span> </td>
<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
-<td width="40%" align="right" valign="top"> <span class="application">nsupdate</span>
+<td width="40%" align="right" valign="top"> <span class="application">named-journalprint</span>
</td>
</tr>
</table>
diff --git a/doc/arm/man.nsec3hash.html b/doc/arm/man.nsec3hash.html
new file mode 100644
index 000000000000..9f1fa6cb3ab4
--- /dev/null
+++ b/doc/arm/man.nsec3hash.html
@@ -0,0 +1,113 @@
+<!--
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2000-2003 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+<!-- $Id: man.nsec3hash.html,v 1.34.8.1.2.1 2011-06-09 03:41:11 tbox Exp $ -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>nsec3hash</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
+<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
+<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
+<link rel="prev" href="man.isc-hmac-fixup.html" title="isc-hmac-fixup">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="navheader">
+<table width="100%" summary="Navigation header">
+<tr><th colspan="3" align="center"><span class="application">nsec3hash</span></th></tr>
+<tr>
+<td width="20%" align="left">
+<a accesskey="p" href="man.isc-hmac-fixup.html">Prev</a> </td>
+<th width="60%" align="center">Manual pages</th>
+<td width="20%" align="right"> </td>
+</tr>
+</table>
+<hr>
+</div>
+<div class="refentry" lang="en">
+<a name="man.nsec3hash"></a><div class="titlepage"></div>
+<div class="refnamediv">
+<h2>Name</h2>
+<p><span class="application">nsec3hash</span> &#8212; generate NSEC3 hash</p>
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="cmdsynopsis"><p><code class="command">nsec3hash</code> {<em class="replaceable"><code>salt</code></em>} {<em class="replaceable"><code>algorithm</code></em>} {<em class="replaceable"><code>iterations</code></em>} {<em class="replaceable"><code>domain</code></em>}</p></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2651073"></a><h2>DESCRIPTION</h2>
+<p>
+ <span><strong class="command">nsec3hash</strong></span> generates an NSEC3 hash based on
+ a set of NSEC3 parameters. This can be used to check the validity
+ of NSEC3 records in a signed zone.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2651088"></a><h2>ARGUMENTS</h2>
+<div class="variablelist"><dl>
+<dt><span class="term">salt</span></dt>
+<dd><p>
+ The salt provided to the hash algorithm.
+ </p></dd>
+<dt><span class="term">algorithm</span></dt>
+<dd><p>
+ A number indicating the hash algorithm. Currently the
+ only supported hash algorithm for NSEC3 is SHA-1, which is
+ indicated by the number 1; consequently "1" is the only
+ useful value for this argument.
+ </p></dd>
+<dt><span class="term">iterations</span></dt>
+<dd><p>
+ The number of additional times the hash should be performed.
+ </p></dd>
+<dt><span class="term">domain</span></dt>
+<dd><p>
+ The domain name to be hashed.
+ </p></dd>
+</dl></div>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2651149"></a><h2>SEE ALSO</h2>
+<p>
+ <em class="citetitle">BIND 9 Administrator Reference Manual</em>,
+ <em class="citetitle">RFC 5155</em>.
+ </p>
+</div>
+<div class="refsect1" lang="en">
+<a name="id2651166"></a><h2>AUTHOR</h2>
+<p><span class="corpauthor">Internet Systems Consortium</span>
+ </p>
+</div>
+</div>
+<div class="navfooter">
+<hr>
+<table width="100%" summary="Navigation footer">
+<tr>
+<td width="40%" align="left">
+<a accesskey="p" href="man.isc-hmac-fixup.html">Prev</a> </td>
+<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
+<td width="40%" align="right"> </td>
+</tr>
+<tr>
+<td width="40%" align="left" valign="top">
+<span class="application">isc-hmac-fixup</span> </td>
+<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
+<td width="40%" align="right" valign="top"> </td>
+</tr>
+</table>
+</div>
+</body>
+</html>
diff --git a/doc/arm/man.nsupdate.html b/doc/arm/man.nsupdate.html
index 597b2f103755..c5d983ae670d 100644
--- a/doc/arm/man.nsupdate.html
+++ b/doc/arm/man.nsupdate.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.nsupdate.html,v 1.22.14.24 2010-08-20 02:05:38 tbox Exp $ -->
+<!-- $Id: man.nsupdate.html,v 1.110.8.1.2.1 2011-06-09 03:41:10 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
-<link rel="prev" href="man.named.html" title="named">
+<link rel="prev" href="man.named-journalprint.html" title="named-journalprint">
<link rel="next" href="man.rndc.html" title="rndc">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@@ -31,7 +31,7 @@
<tr><th colspan="3" align="center"><span class="application">nsupdate</span></th></tr>
<tr>
<td width="20%" align="left">
-<a accesskey="p" href="man.named.html">Prev</a> </td>
+<a accesskey="p" href="man.named-journalprint.html">Prev</a> </td>
<th width="60%" align="center">Manual pages</th>
<td width="20%" align="right"> <a accesskey="n" href="man.rndc.html">Next</a>
</td>
@@ -47,12 +47,12 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [<code class="option">-D</code>] [[<code class="option">-g</code>] | [<code class="option">-o</code>] | [<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-R <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-v</code>] [filename]</p></div>
+<div class="cmdsynopsis"><p><code class="command">nsupdate</code> [<code class="option">-d</code>] [<code class="option">-D</code>] [[<code class="option">-g</code>] | [<code class="option">-o</code>] | [<code class="option">-l</code>] | [<code class="option">-y <em class="replaceable"><code>[<span class="optional">hmac:</span>]keyname:secret</code></em></code>] | [<code class="option">-k <em class="replaceable"><code>keyfile</code></em></code>]] [<code class="option">-t <em class="replaceable"><code>timeout</code></em></code>] [<code class="option">-u <em class="replaceable"><code>udptimeout</code></em></code>] [<code class="option">-r <em class="replaceable"><code>udpretries</code></em></code>] [<code class="option">-R <em class="replaceable"><code>randomdev</code></em></code>] [<code class="option">-v</code>] [filename]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2610983"></a><h2>DESCRIPTION</h2>
+<a name="id2638810"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">nsupdate</strong></span>
- is used to submit Dynamic DNS Update requests as defined in RFC2136
+ is used to submit Dynamic DNS Update requests as defined in RFC 2136
to a name server.
This allows resource records to be added or removed from a zone
without manually editing the zone file.
@@ -88,10 +88,14 @@
report additional debugging information to <code class="option">-d</code>.
</p>
<p>
+ The <code class="option">-L</code> option with an integer argument of zero or
+ higher sets the logging debug level. If zero, logging is disabled.
+ </p>
+<p>
Transaction signatures can be used to authenticate the Dynamic
DNS updates. These use the TSIG resource record type described
- in RFC2845 or the SIG(0) record described in RFC3535 and
- RFC2931 or GSS-TSIG as described in RFC3645. TSIG relies on
+ in RFC 2845 or the SIG(0) record described in RFC 2535 and
+ RFC 2931 or GSS-TSIG as described in RFC 3645. TSIG relies on
a shared secret that should only be known to
<span><strong class="command">nsupdate</strong></span> and the name server. Currently,
the only supported encryption algorithm for TSIG is HMAC-MD5,
@@ -108,44 +112,59 @@
record in a zone served by the name server.
<span><strong class="command">nsupdate</strong></span> does not read
<code class="filename">/etc/named.conf</code>.
- GSS-TSIG uses Kerberos credentials.
+ </p>
+<p>
+ GSS-TSIG uses Kerberos credentials. Standard GSS-TSIG mode
+ is switched on with the <code class="option">-g</code> flag. A
+ non-standards-compliant variant of GSS-TSIG used by Windows
+ 2000 can be switched on with the <code class="option">-o</code> flag.
</p>
<p><span><strong class="command">nsupdate</strong></span>
uses the <code class="option">-y</code> or <code class="option">-k</code> option
to provide the shared secret needed to generate a TSIG record
for authenticating Dynamic DNS update requests, default type
- HMAC-MD5. These options are mutually exclusive. With the
- <code class="option">-k</code> option, <span><strong class="command">nsupdate</strong></span> reads
- the shared secret from the file <em class="parameter"><code>keyfile</code></em>,
- whose name is of the form
- <code class="filename">K{name}.+157.+{random}.private</code>. For
- historical reasons, the file
- <code class="filename">K{name}.+157.+{random}.key</code> must also be
- present. When the <code class="option">-y</code> option is used, a
- signature is generated from
+ HMAC-MD5. These options are mutually exclusive.
+ </p>
+<p>
+ When the <code class="option">-y</code> option is used, a signature is
+ generated from
[<span class="optional"><em class="parameter"><code>hmac:</code></em></span>]<em class="parameter"><code>keyname:secret.</code></em>
<em class="parameter"><code>keyname</code></em> is the name of the key, and
- <em class="parameter"><code>secret</code></em> is the base64 encoded shared
- secret. Use of the <code class="option">-y</code> option is discouraged
- because the shared secret is supplied as a command line
- argument in clear text. This may be visible in the output
- from
- <span class="citerefentry"><span class="refentrytitle">ps</span>(1)</span> or in a history file maintained by the user's
- shell.
+ <em class="parameter"><code>secret</code></em> is the base64 encoded shared secret.
+ Use of the <code class="option">-y</code> option is discouraged because the
+ shared secret is supplied as a command line argument in clear text.
+ This may be visible in the output from
+ <span class="citerefentry"><span class="refentrytitle">ps</span>(1)</span>
+ or in a history file maintained by the user's shell.
</p>
<p>
+ With the
+ <code class="option">-k</code> option, <span><strong class="command">nsupdate</strong></span> reads
+ the shared secret from the file <em class="parameter"><code>keyfile</code></em>.
+ Keyfiles may be in two formats: a single file containing
+ a <code class="filename">named.conf</code>-format <span><strong class="command">key</strong></span>
+ statement, which may be generated automatically by
+ <span><strong class="command">ddns-confgen</strong></span>, or a pair of files whose names are
+ of the format <code class="filename">K{name}.+157.+{random}.key</code> and
+ <code class="filename">K{name}.+157.+{random}.private</code>, which can be
+ generated by <span><strong class="command">dnssec-keygen</strong></span>.
The <code class="option">-k</code> may also be used to specify a SIG(0) key used
to authenticate Dynamic DNS update requests. In this case, the key
specified is not an HMAC-MD5 key.
</p>
<p>
- The <code class="option">-g</code> and <code class="option">-o</code> specify that
- GSS-TSIG is to be used. The <code class="option">-o</code> should only
- be used with old Microsoft Windows 2000 servers.
+ <span><strong class="command">nsupdate</strong></span> can be run in a local-host only mode
+ using the <code class="option">-l</code> flag. This sets the server address to
+ localhost (disabling the <span><strong class="command">server</strong></span> so that the server
+ address cannot be overridden). Connections to the local server will
+ use a TSIG key found in <code class="filename">/var/run/named/session.key</code>,
+ which is automatically generated by <span><strong class="command">named</strong></span> if any
+ local master zone has set <span><strong class="command">update-policy</strong></span> to
+ <span><strong class="command">local</strong></span>. The location of this key file can be
+ overridden with the <code class="option">-k</code> option.
</p>
<p>
- By default,
- <span><strong class="command">nsupdate</strong></span>
+ By default, <span><strong class="command">nsupdate</strong></span>
uses UDP to send update requests to the name server unless they are too
large to fit in a UDP request in which case TCP will be used.
The
@@ -156,6 +175,10 @@
This may be preferable when a batch of update requests is made.
</p>
<p>
+ The <code class="option">-p</code> sets the default port number to use for
+ connections to a name server. The default is 53.
+ </p>
+<p>
The <code class="option">-t</code> option sets the maximum time an update request
can
take before it is aborted. The default is 300 seconds. Zero can be
@@ -187,7 +210,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2611378"></a><h2>INPUT FORMAT</h2>
+<a name="id2639349"></a><h2>INPUT FORMAT</h2>
<p><span><strong class="command">nsupdate</strong></span>
reads input from
<em class="parameter"><code>filename</code></em>
@@ -475,7 +498,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2667517"></a><h2>EXAMPLES</h2>
+<a name="id2677944"></a><h2>EXAMPLES</h2>
<p>
The examples below show how
<span><strong class="command">nsupdate</strong></span>
@@ -522,19 +545,23 @@
If there are, the update request fails.
If this name does not exist, a CNAME for it is added.
This ensures that when the CNAME is added, it cannot conflict with the
- long-standing rule in RFC1034 that a name must not exist as any other
+ long-standing rule in RFC 1034 that a name must not exist as any other
record type if it exists as a CNAME.
- (The rule has been updated for DNSSEC in RFC2535 to allow CNAMEs to have
+ (The rule has been updated for DNSSEC in RFC 2535 to allow CNAMEs to have
RRSIG, DNSKEY and NSEC records.)
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2667568"></a><h2>FILES</h2>
+<a name="id2678062"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="constant">/etc/resolv.conf</code></span></dt>
<dd><p>
used to identify default name server
</p></dd>
+<dt><span class="term"><code class="constant">/var/run/named/session.key</code></span></dt>
+<dd><p>
+ sets the default TSIG key for use in local-only mode
+ </p></dd>
<dt><span class="term"><code class="constant">K{name}.+157.+{random}.key</code></span></dt>
<dd><p>
base-64 encoding of HMAC-MD5 key created by
@@ -548,20 +575,22 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2667637"></a><h2>SEE ALSO</h2>
-<p><span class="citerefentry"><span class="refentrytitle">RFC2136</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC3007</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC2104</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC2845</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC1034</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC2535</span></span>,
- <span class="citerefentry"><span class="refentrytitle">RFC2931</span></span>,
+<a name="id2678146"></a><h2>SEE ALSO</h2>
+<p>
+ <em class="citetitle">RFC 2136</em>,
+ <em class="citetitle">RFC 3007</em>,
+ <em class="citetitle">RFC 2104</em>,
+ <em class="citetitle">RFC 2845</em>,
+ <em class="citetitle">RFC 1034</em>,
+ <em class="citetitle">RFC 2535</em>,
+ <em class="citetitle">RFC 2931</em>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
+ <span class="citerefentry"><span class="refentrytitle">ddns-confgen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2667776"></a><h2>BUGS</h2>
+<a name="id2678203"></a><h2>BUGS</h2>
<p>
The TSIG key is redundantly stored in two separate files.
This is a consequence of nsupdate using the DST library
@@ -575,14 +604,14 @@
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
-<a accesskey="p" href="man.named.html">Prev</a> </td>
+<a accesskey="p" href="man.named-journalprint.html">Prev</a> </td>
<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
<td width="40%" align="right"> <a accesskey="n" href="man.rndc.html">Next</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">
-<span class="application">named</span> </td>
+<span class="application">named-journalprint</span> </td>
<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
<td width="40%" align="right" valign="top"> <span class="application">rndc</span>
</td>
diff --git a/doc/arm/man.rndc-confgen.html b/doc/arm/man.rndc-confgen.html
index 523ad9219a76..f441b938be43 100644
--- a/doc/arm/man.rndc-confgen.html
+++ b/doc/arm/man.rndc-confgen.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.rndc-confgen.html,v 1.102.14.24 2010-08-20 02:05:38 tbox Exp $ -->
+<!-- $Id: man.rndc-confgen.html,v 1.189.8.1.2.1 2011-06-09 03:41:11 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -23,6 +23,7 @@
<link rel="start" href="Bv9ARM.html" title="BIND 9 Administrator Reference Manual">
<link rel="up" href="Bv9ARM.ch10.html" title="Manual pages">
<link rel="prev" href="man.rndc.conf.html" title="rndc.conf">
+<link rel="next" href="man.ddns-confgen.html" title="ddns-confgen">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
@@ -32,7 +33,8 @@
<td width="20%" align="left">
<a accesskey="p" href="man.rndc.conf.html">Prev</a> </td>
<th width="60%" align="center">Manual pages</th>
-<td width="20%" align="right"> </td>
+<td width="20%" align="right"> <a accesskey="n" href="man.ddns-confgen.html">Next</a>
+</td>
</tr>
</table>
<hr>
@@ -48,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">rndc-confgen</code> [<code class="option">-a</code>] [<code class="option">-b <em class="replaceable"><code>keysize</code></em></code>] [<code class="option">-c <em class="replaceable"><code>keyfile</code></em></code>] [<code class="option">-h</code>] [<code class="option">-k <em class="replaceable"><code>keyname</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-r <em class="replaceable"><code>randomfile</code></em></code>] [<code class="option">-s <em class="replaceable"><code>address</code></em></code>] [<code class="option">-t <em class="replaceable"><code>chrootdir</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2613082"></a><h2>DESCRIPTION</h2>
+<a name="id2641044"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">rndc-confgen</strong></span>
generates configuration files
for <span><strong class="command">rndc</strong></span>. It can be used as a
@@ -64,7 +66,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2613148"></a><h2>OPTIONS</h2>
+<a name="id2641110"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-a</span></dt>
<dd>
@@ -171,7 +173,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2624525"></a><h2>EXAMPLES</h2>
+<a name="id2642384"></a><h2>EXAMPLES</h2>
<p>
To allow <span><strong class="command">rndc</strong></span> to be used with
no manual configuration, run
@@ -188,7 +190,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2628541"></a><h2>SEE ALSO</h2>
+<a name="id2642440"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc.conf</span>(5)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
@@ -196,7 +198,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2628580"></a><h2>AUTHOR</h2>
+<a name="id2649715"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
@@ -208,13 +210,15 @@
<td width="40%" align="left">
<a accesskey="p" href="man.rndc.conf.html">Prev</a> </td>
<td width="20%" align="center"><a accesskey="u" href="Bv9ARM.ch10.html">Up</a></td>
-<td width="40%" align="right"> </td>
+<td width="40%" align="right"> <a accesskey="n" href="man.ddns-confgen.html">Next</a>
+</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">
<code class="filename">rndc.conf</code> </td>
<td width="20%" align="center"><a accesskey="h" href="Bv9ARM.html">Home</a></td>
-<td width="40%" align="right" valign="top"> </td>
+<td width="40%" align="right" valign="top"> <span class="application">ddns-confgen</span>
+</td>
</tr>
</table>
</div>
diff --git a/doc/arm/man.rndc.conf.html b/doc/arm/man.rndc.conf.html
index f454cf4e2ad4..456ac38e2ca2 100644
--- a/doc/arm/man.rndc.conf.html
+++ b/doc/arm/man.rndc.conf.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.rndc.conf.html,v 1.103.14.24 2010-08-20 02:05:38 tbox Exp $ -->
+<!-- $Id: man.rndc.conf.html,v 1.190.8.1.2.1 2011-06-09 03:41:11 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">rndc.conf</code> </p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2608299"></a><h2>DESCRIPTION</h2>
+<a name="id2640419"></a><h2>DESCRIPTION</h2>
<p><code class="filename">rndc.conf</code> is the configuration file
for <span><strong class="command">rndc</strong></span>, the BIND 9 name server control
utility. This file has a similar structure and syntax to
@@ -135,7 +135,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612294"></a><h2>EXAMPLE</h2>
+<a name="id2640590"></a><h2>EXAMPLE</h2>
<pre class="programlisting">
options {
default-server localhost;
@@ -209,7 +209,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612416"></a><h2>NAME SERVER CONFIGURATION</h2>
+<a name="id2640780"></a><h2>NAME SERVER CONFIGURATION</h2>
<p>
The name server must be configured to accept rndc connections and
to recognize the key specified in the <code class="filename">rndc.conf</code>
@@ -219,7 +219,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612714"></a><h2>SEE ALSO</h2>
+<a name="id2640806"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc-confgen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">mmencode</span>(1)</span>,
@@ -227,7 +227,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612753"></a><h2>AUTHOR</h2>
+<a name="id2640844"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/man.rndc.html b/doc/arm/man.rndc.html
index 0a6c65c85d90..58fa67e07200 100644
--- a/doc/arm/man.rndc.html
+++ b/doc/arm/man.rndc.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000-2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: man.rndc.html,v 1.101.14.24 2010-08-20 02:05:38 tbox Exp $ -->
+<!-- $Id: man.rndc.html,v 1.188.8.1.2.1 2011-06-09 03:41:10 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -50,7 +50,7 @@
<div class="cmdsynopsis"><p><code class="command">rndc</code> [<code class="option">-b <em class="replaceable"><code>source-address</code></em></code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-k <em class="replaceable"><code>key-file</code></em></code>] [<code class="option">-s <em class="replaceable"><code>server</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-V</code>] [<code class="option">-y <em class="replaceable"><code>key_id</code></em></code>] {command}</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2611614"></a><h2>DESCRIPTION</h2>
+<a name="id2639501"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">rndc</strong></span>
controls the operation of a name
server. It supersedes the <span><strong class="command">ndc</strong></span> utility
@@ -79,7 +79,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2611665"></a><h2>OPTIONS</h2>
+<a name="id2639552"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-b <em class="replaceable"><code>source-address</code></em></span></dt>
<dd><p>
@@ -151,7 +151,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612026"></a><h2>LIMITATIONS</h2>
+<a name="id2640254"></a><h2>LIMITATIONS</h2>
<p><span><strong class="command">rndc</strong></span>
does not yet support all the commands of
the BIND 8 <span><strong class="command">ndc</strong></span> utility.
@@ -165,7 +165,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612057"></a><h2>SEE ALSO</h2>
+<a name="id2640285"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">rndc.conf</span>(5)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc-confgen</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
@@ -175,7 +175,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2612113"></a><h2>AUTHOR</h2>
+<a name="id2640341"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/doc/arm/managed-keys.xml b/doc/arm/managed-keys.xml
new file mode 100644
index 000000000000..f1e06f3cc125
--- /dev/null
+++ b/doc/arm/managed-keys.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ - Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: managed-keys.xml,v 1.3 2010-02-03 23:49:07 tbox Exp $ -->
+
+<sect1 id="rfc5011.support">
+ <title>Dynamic Trust Anchor Management</title>
+ <para>BIND 9.7.0 introduces support for RFC 5011, dynamic trust
+ anchor management. Using this feature allows
+ <command>named</command> to keep track of changes to critical
+ DNSSEC keys without any need for the operator to make changes to
+ configuration files.</para>
+ <sect2>
+ <title>Validating Resolver</title>
+ <!-- TODO: command tag is overloaded for configuration and executables -->
+ <para>To configure a validating resolver to use RFC 5011 to
+ maintain a trust anchor, configure the trust anchor using a
+ <command>managed-keys</command> statement. Information about
+ this can be found in
+ <xref linkend="managed-keys" />.</para>
+ <!-- TODO: managed-keys examples
+also in DNSSEC section above here in ARM -->
+ </sect2>
+ <sect2>
+ <title>Authoritative Server</title>
+ <para>To set up an authoritative zone for RFC 5011 trust anchor
+ maintenance, generate two (or more) key signing keys (KSKs) for
+ the zone. Sign the zone with one of them; this is the "active"
+ KSK. All KSK's which do not sign the zone are "stand-by"
+ keys.</para>
+ <para>Any validating resolver which is configured to use the
+ active KSK as an RFC 5011-managed trust anchor will take note
+ of the stand-by KSKs in the zone's DNSKEY RRset, and store them
+ for future reference. The resolver will recheck the zone
+ periodically, and after 30 days, if the new key is still there,
+ then the key will be accepted by the resolver as a valid trust
+ anchor for the zone. Any time after this 30-day acceptance
+ timer has completed, the active KSK can be revoked, and the
+ zone can be "rolled over" to the newly accepted key.</para>
+ <para>The easiest way to place a stand-by key in a zone is to
+ use the "smart signing" features of
+ <command>dnssec-keygen</command> and
+ <command>dnssec-signzone</command>. If a key with a publication
+ date in the past, but an activation date which is unset or in
+ the future, "
+ <command>dnssec-signzone -S</command>" will include the DNSKEY
+ record in the zone, but will not sign with it:</para>
+ <screen>
+$ <userinput>dnssec-keygen -K keys -f KSK -P now -A now+2y example.net</userinput>
+$ <userinput>dnssec-signzone -S -K keys example.net</userinput>
+</screen>
+ <para>To revoke a key, the new command
+ <command>dnssec-revoke</command> has been added. This adds the
+ REVOKED bit to the key flags and re-generates the
+ <filename>K*.key</filename> and
+ <filename>K*.private</filename> files.</para>
+ <para>After revoking the active key, the zone must be signed
+ with both the revoked KSK and the new active KSK. (Smart
+ signing takes care of this automatically.)</para>
+ <para>Once a key has been revoked and used to sign the DNSKEY
+ RRset in which it appears, that key will never again be
+ accepted as a valid trust anchor by the resolver. However,
+ validation can proceed using the new active key (which had been
+ accepted by the resolver when it was a stand-by key).</para>
+ <para>See RFC 5011 for more details on key rollover
+ scenarios.</para>
+ <para>When a key has been revoked, its key ID changes,
+ increasing by 128, and wrapping around at 65535. So, for
+ example, the key "<filename>Kexample.com.+005+10000</filename>" becomes
+ "<filename>Kexample.com.+005+10128</filename>".</para>
+ <para>If two keys have ID's exactly 128 apart, and one is
+ revoked, then the two key ID's will collide, causing several
+ problems. To prevent this,
+ <command>dnssec-keygen</command> will not generate a new key if
+ another key is present which may collide. This checking will
+ only occur if the new keys are written to the same directory
+ which holds all other keys in use for that zone.</para>
+ <para>Older versions of BIND 9 did not have this precaution.
+ Exercise caution if using key revocation on keys that were
+ generated by previous releases, or if using keys stored in
+ multiple directories or on multiple machines.</para>
+ <para>It is expected that a future release of BIND 9 will
+ address this problem in a different way, by storing revoked
+ keys with their original unrevoked key ID's.</para>
+ </sect2>
+</sect1>
diff --git a/doc/arm/pkcs11.xml b/doc/arm/pkcs11.xml
new file mode 100644
index 000000000000..23bf5fdb54a2
--- /dev/null
+++ b/doc/arm/pkcs11.xml
@@ -0,0 +1,390 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+ [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: pkcs11.xml,v 1.3 2010-02-06 07:42:02 marka Exp $ -->
+
+<sect1 id="pkcs11">
+ <title>PKCS #11 (Cryptoki) support</title>
+ <para>PKCS #11 (Public Key Cryptography Standard #11) defines a
+ platform- independent API for the control of hardware security
+ modules (HSMs) and other cryptographic support devices.</para>
+ <para>BIND 9 is known to work with two HSMs: The Sun SCA 6000
+ cryptographic acceleration board, tested under Solaris x86, and
+ the AEP Keyper network-attached key storage device, tested with
+ Debian Linux, Solaris x86 and Windows Server 2003.</para>
+ <sect2>
+ <title>Prerequisites</title>
+ <para>See the HSM vendor documentation for information about
+ installing, initializing, testing and troubleshooting the
+ HSM.</para>
+ <para>BIND 9 uses OpenSSL for cryptography, but stock OpenSSL
+ does not yet fully support PKCS #11. However, a PKCS #11 engine
+ for OpenSSL is available from the OpenSolaris project. It has
+ been modified by ISC to work with with BIND 9, and to provide
+ new features such as PIN management and key by
+ reference.</para>
+ <para>The patched OpenSSL depends on a "PKCS #11 provider".
+ This is a shared library object, providing a low-level PKCS #11
+ interface to the HSM hardware. It is dynamically loaded by
+ OpenSSL at runtime. The PKCS #11 provider comes from the HSM
+ vendor, and and is specific to the HSM to be controlled.</para>
+ <para>There are two "flavors" of PKCS #11 support provided by
+ the patched OpenSSL, one of which must be chosen at
+ configuration time. The correct choice depends on the HSM
+ hardware:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Use 'crypto-accelerator' with HSMs that have hardware
+ cryptographic acceleration features, such as the SCA 6000
+ board. This causes OpenSSL to run all supported
+ cryptographic operations in the HSM.</para>
+ </listitem>
+ <listitem>
+ <para>Use 'sign-only' with HSMs that are designed to
+ function primarily as secure key storage devices, but lack
+ hardware acceleration. These devices are highly secure, but
+ are not necessarily any faster at cryptography than the
+ system CPU &mdash; often, they are slower. It is therefore
+ most efficient to use them only for those cryptographic
+ functions that require access to the secured private key,
+ such as zone signing, and to use the system CPU for all
+ other computationally-intensive operations. The AEP Keyper
+ is an example of such a device.</para>
+ </listitem>
+ </itemizedlist>
+ <para>The modified OpenSSL code is included in the BIND 9.7.0
+ release, in the form of a context diff against the latest OpenSSL.
+ </para>
+ <note>
+ The latest OpenSSL version at the time of the BIND release
+ is 0.9.8l.
+ ISC will provide an updated patch as new versions of OpenSSL
+ are released. The version number in the following examples
+ is expected to change.</note>
+ <para>
+ Before building BIND 9 with PKCS #11 support, it will be
+ necessary to build OpenSSL with this patch in place and inform
+ it of the path to the HSM-specific PKCS #11 provider
+ library.</para>
+ <para>Obtain OpenSSL 0.9.8l:</para>
+ <screen>
+$ <userinput>wget <ulink>http://www.openssl.org/source/openssl-0.9.8l.tar.gz</ulink></userinput>
+</screen>
+ <para>Extract the tarball:</para>
+ <screen>
+$ <userinput>tar zxf openssl-0.9.8l.tar.gz</userinput>
+</screen>
+ <para>Apply the patch from the BIND 9 release:</para>
+ <screen>
+$ <userinput>patch -p1 -d openssl-0.9.8l \
+ &lt; bind-9.7.0/bin/pkcs11/openssl-0.9.8l-patch</userinput>
+</screen>
+ <note>(Note that the patch file may not be compatible with the
+ "patch" utility on all operating systems. You may need to
+ install GNU patch.)</note>
+ <para>When building OpenSSL, place it in a non-standard
+ location so that it does not interfere with OpenSSL libraries
+ elsewhere on the system. In the following examples, we choose
+ to install into "/opt/pkcs11/usr". We will use this location
+ when we configure BIND 9.</para>
+ <sect3>
+ <!-- Example 1 -->
+ <title>Building OpenSSL for the AEP Keyper on Linux</title>
+ <para>The AEP Keyper is a highly secure key storage device,
+ but does not provide hardware cryptographic acceleration. It
+ can carry out cryptographic operations, but it is probably
+ slower than your system's CPU. Therefore, we choose the
+ 'sign-only' flavor when building OpenSSL.</para>
+ <para>The Keyper-specific PKCS #11 provider library is
+ delivered with the Keyper software. In this example, we place
+ it /opt/pkcs11/usr/lib:</para>
+ <screen>
+$ <userinput>cp pkcs11.GCC4.0.2.so.4.05 /opt/pkcs11/usr/lib/libpkcs11.so</userinput>
+</screen>
+ <para>This library is only available for Linux as a 32-bit
+ binary. If we are compiling on a 64-bit Linux system, it is
+ necessary to force a 32-bit build, by specifying -m32 in the
+ build options.</para>
+ <para>Finally, the Keyper library requires threads, so we
+ must specify -pthread.</para>
+ <screen>
+$ <userinput>cd openssl-0.9.8l</userinput>
+$ <userinput>./Configure linux-generic32 -m32 -pthread \
+ --pk11-libname=/opt/pkcs11/usr/lib/libpkcs11.so \
+ --pk11-flavor=sign-only \
+ --prefix=/opt/pkcs11/usr</userinput>
+</screen>
+ <para>After configuring, run "<command>make</command>"
+ and "<command>make test</command>". If "<command>make
+ test</command>" fails with "pthread_atfork() not found", you forgot to
+ add the -pthread above.</para>
+ </sect3>
+ <sect3>
+ <!-- Example 2 -->
+ <title>Building OpenSSL for the SCA 6000 on Solaris</title>
+ <para>The SCA-6000 PKCS #11 provider is installed as a system
+ library, libpkcs11. It is a true crypto accelerator, up to 4
+ times faster than any CPU, so the flavor shall be
+ 'crypto-accelerator'.</para>
+ <para>In this example, we are building on Solaris x86 on an
+ AMD64 system.</para>
+ <screen>
+$ <userinput>cd openssl-0.9.8l</userinput>
+$ <userinput>./Configure solaris64-x86_64-cc \
+ --pk11-libname=/usr/lib/64/libpkcs11.so \
+ --pk11-flavor=crypto-accelerator \
+ --prefix=/opt/pkcs11/usr</userinput>
+</screen>
+ <para>(For a 32-bit build, use "solaris-x86-cc" and
+ /usr/lib/libpkcs11.so.)</para>
+ <para>After configuring, run
+ <command>make</command> and
+ <command>make test</command>.</para>
+ <para>Once you have built OpenSSL, run
+ "<command>apps/openssl engine pkcs11</command>" to confirm
+ that PKCS #11 support was compiled in correctly. The output
+ should be one of the following lines, depending on the flavor
+ selected:</para>
+ <screen>
+ (pkcs11) PKCS #11 engine support (sign only)
+</screen>
+ <para>Or:</para>
+ <screen>
+ (pkcs11) PKCS #11 engine support (crypto accelerator)
+</screen>
+ <para>Next, run
+ "<command>apps/openssl engine pkcs11 -t</command>". This will
+ attempt to initialize the PKCS #11 engine. If it is able to
+ do so successfully, it will report
+ <quote><literal>[ available ]</literal></quote>.</para>
+ <para>If the output is correct, run
+ "<command>make install</command>" which will install the
+ modified OpenSSL suite to
+ <filename>/opt/pkcs11/usr</filename>.</para>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>Building BIND 9 with PKCS#11</title>
+ <para>When building BIND 9, the location of the custom-built
+ OpenSSL library must be specified via configure.</para>
+ <sect3>
+ <!-- Example 3 -->
+ <title>Configuring BIND 9 for Linux</title>
+ <para>To link with the PKCS #11 provider, threads must be
+ enabled in the BIND 9 build.</para>
+ <para>The PKCS #11 library for the AEP Keyper is currently
+ only available as a 32-bit binary. If we are building on a
+ 64-bit host, we must force a 32-bit build by adding "-m32" to
+ the CC options on the "configure" command line.</para>
+ <screen>
+$ <userinput>cd ../bind-9.7.0</userinput>
+$ <userinput>./configure CC="gcc -m32" --enable-threads \
+ --with-openssl=/opt/pkcs11/usr \
+ --with-pkcs11=/opt/pkcs11/usr/lib/libpkcs11.so</userinput>
+</screen>
+ </sect3>
+ <sect3>
+ <!-- Example 4 -->
+ <title>Configuring BIND 9 for Solaris</title>
+ <para>To link with the PKCS #11 provider, threads must be
+ enabled in the BIND 9 build.</para>
+ <screen>
+$ <userinput>cd ../bind-9.7.0</userinput>
+$ <userinput>./configure CC="cc -xarch=amd64" --enable-threads \
+ --with-openssl=/opt/pkcs11/usr \
+ --with-pkcs11=/usr/lib/64/libpkcs11.so</userinput>
+</screen>
+ <para>(For a 32-bit build, omit CC="cc -xarch=amd64".)</para>
+ <para>If configure complains about OpenSSL not working, you
+ may have a 32/64-bit architecture mismatch. Or, you may have
+ incorrectly specified the path to OpenSSL (it should be the
+ same as the --prefix argument to the OpenSSL
+ Configure).</para>
+ </sect3>
+ <para>After configuring, run
+ "<command>make</command>",
+ "<command>make test</command>" and
+ "<command>make install</command>".</para>
+ </sect2>
+ <sect2>
+ <title>PKCS #11 Tools</title>
+ <para>BIND 9 includes a minimal set of tools to operate the
+ HSM, including
+ <command>pkcs11-keygen</command> to generate a new key pair
+ within the HSM,
+ <command>pkcs11-list</command> to list objects currently
+ available, and
+ <command>pkcs11-destroy</command> to remove objects.</para>
+ <para>In UNIX/Linux builds, these tools are built only if BIND
+ 9 is configured with the --with-pkcs11 option. (NOTE: If
+ --with-pkcs11 is set to "yes", rather than to the path of the
+ PKCS #11 provider, then the tools will be built but the
+ provider will be left undefined. Use the -m option or the
+ PKCS11_PROVIDER environment variable to specify the path to the
+ provider.)</para>
+ </sect2>
+ <sect2>
+ <title>Using the HSM</title>
+ <para>First, we must set up the runtime environment so the
+ OpenSSL and PKCS #11 libraries can be loaded:</para>
+ <screen>
+$ <userinput>export LD_LIBRARY_PATH=/opt/pkcs11/usr/lib:${LD_LIBRARY_PATH}</userinput>
+</screen>
+ <para>When operating an AEP Keyper, it is also necessary to
+ specify the location of the "machine" file, which stores
+ information about the Keyper for use by PKCS #11 provider
+ library. If the machine file is in
+ <filename>/opt/Keyper/PKCS11Provider/machine</filename>,
+ use:</para>
+ <screen>
+$ <userinput>export KEYPER_LIBRARY_PATH=/opt/Keyper/PKCS11Provider</userinput>
+</screen>
+ <!-- TODO: why not defined at compile time? -->
+ <para>These environment variables must be set whenever running
+ any tool that uses the HSM, including
+ <command>pkcs11-keygen</command>,
+ <command>pkcs11-list</command>,
+ <command>pkcs11-destroy</command>,
+ <command>dnssec-keyfromlabel</command>,
+ <command>dnssec-signzone</command>,
+ <command>dnssec-keygen</command>(which will use the HSM for
+ random number generation), and
+ <command>named</command>.</para>
+ <para>We can now create and use keys in the HSM. In this case,
+ we will create a 2048 bit key and give it the label
+ "sample-ksk":</para>
+ <screen>
+$ <userinput>pkcs11-keygen -b 2048 -l sample-ksk</userinput>
+</screen>
+ <para>To confirm that the key exists:</para>
+ <screen>
+$ <userinput>pkcs11-list</userinput>
+Enter PIN:
+object[0]: handle 2147483658 class 3 label[8] 'sample-ksk' id[0]
+object[1]: handle 2147483657 class 2 label[8] 'sample-ksk' id[0]
+</screen>
+ <para>Before using this key to sign a zone, we must create a
+ pair of BIND 9 key files. The "dnssec-keyfromlabel" utility
+ does this. In this case, we will be using the HSM key
+ "sample-ksk" as the key-signing key for "example.net":</para>
+ <screen>
+$ <userinput>dnssec-keyfromlabel -l sample-ksk -f KSK example.net</userinput>
+</screen>
+ <para>The resulting K*.key and K*.private files can now be used
+ to sign the zone. Unlike normal K* files, which contain both
+ public and private key data, these files will contain only the
+ public key data, plus an identifier for the private key which
+ remains stored within the HSM. The HSM handles signing with the
+ private key.</para>
+ <para>If you wish to generate a second key in the HSM for use
+ as a zone-signing key, follow the same procedure above, using a
+ different keylabel, a smaller key size, and omitting "-f KSK"
+ from the dnssec-keyfromlabel arguments:</para>
+ <screen>
+$ <userinput>pkcs11-keygen -b 1024 -l sample-zsk</userinput>
+$ <userinput>dnssec-keyfromlabel -l sample-zsk example.net</userinput>
+</screen>
+ <para>Alternatively, you may prefer to generate a conventional
+ on-disk key, using dnssec-keygen:</para>
+ <screen>
+$ <userinput>dnssec-keygen example.net</userinput>
+</screen>
+ <para>This provides less security than an HSM key, but since
+ HSMs can be slow or cumbersome to use for security reasons, it
+ may be more efficient to reserve HSM keys for use in the less
+ frequent key-signing operation. The zone-signing key can be
+ rolled more frequently, if you wish, to compensate for a
+ reduction in key security.</para>
+ <para>Now you can sign the zone. (Note: If not using the -S
+ option to
+ <command>dnssec-signzone</command>, it will be necessary to add
+ the contents of both
+ <filename>K*.key</filename> files to the zone master file before
+ signing it.)</para>
+ <screen>
+$ <userinput>dnssec-signzone -S example.net</userinput>
+Enter PIN:
+Verifying the zone using the following algorithms:
+NSEC3RSASHA1.
+Zone signing complete:
+Algorithm: NSEC3RSASHA1: ZSKs: 1, KSKs: 1 active, 0 revoked, 0 stand-by
+example.net.signed
+</screen>
+ </sect2>
+ <sect2>
+ <title>Specifying the engine on the command line</title>
+ <para>The OpenSSL engine can be specified in
+ <command>named</command> and all of the BIND
+ <command>dnssec-*</command> tools by using the "-E
+ &lt;engine&gt;" command line option. If BIND 9 is built with
+ the --with-pkcs11 option, this option defaults to "pkcs11".
+ Specifying the engine will generally not be necessary unless
+ for some reason you wish to use a different OpenSSL
+ engine.</para>
+ <para>If you wish to disable use of the "pkcs11" engine &mdash;
+ for troubleshooting purposes, or because the HSM is unavailable
+ &mdash; set the engine to the empty string. For example:</para>
+ <screen>
+$ <userinput>dnssec-signzone -E '' -S example.net</userinput>
+</screen>
+ <para>This causes
+ <command>dnssec-signzone</command> to run as if it were compiled
+ without the --with-pkcs11 option.</para>
+ </sect2>
+ <sect2>
+ <title>Running named with automatic zone re-signing</title>
+ <para>If you want
+ <command>named</command> to dynamically re-sign zones using HSM
+ keys, and/or to to sign new records inserted via nsupdate, then
+ named must have access to the HSM PIN. This can be accomplished
+ by placing the PIN into the openssl.cnf file (in the above
+ examples,
+ <filename>/opt/pkcs11/usr/ssl/openssl.cnf</filename>).</para>
+ <para>The location of the openssl.cnf file can be overridden by
+ setting the OPENSSL_CONF environment variable before running
+ named.</para>
+ <para>Sample openssl.cnf:</para>
+ <programlisting>
+ openssl_conf = openssl_def
+ [ openssl_def ]
+ engines = engine_section
+ [ engine_section ]
+ pkcs11 = pkcs11_section
+ [ pkcs11_section ]
+ PIN = <replaceable>&lt;PLACE PIN HERE&gt;</replaceable>
+</programlisting>
+ <para>This will also allow the dnssec-* tools to access the HSM
+ without PIN entry. (The pkcs11-* tools access the HSM directly,
+ not via OpenSSL, so a PIN will still be required to use
+ them.)</para>
+<!--
+If the PIN is not known, I believe the first time named needs the
+PIN to open a key, it'll ask you to type in the PIN, which will be
+a problem because it probably won't be running on a terminal
+-->
+ <warning>
+ <para>Placing the HSM's PIN in a text file in
+ this manner may reduce the security advantage of using an
+ HSM. Be sure this is what you want to do before configuring
+ OpenSSL in this way.</para>
+ </warning>
+ </sect2>
+ <!-- TODO: what is alternative then for named dynamic re-signing? -->
+ <!-- TODO: what happens if PIN is not known? named will log about it? -->
+</sect1>
diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in
index 5a671b86304b..64681767f04a 100644
--- a/doc/misc/Makefile.in
+++ b/doc/misc/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.7.252.2 2009-07-11 23:47:17 tbox Exp $
+# $Id: Makefile.in,v 1.9 2009-07-10 23:47:58 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/doc/misc/options b/doc/misc/options
index a6b2dcdfdb76..673abf7bb497 100644
--- a/doc/misc/options
+++ b/doc/misc/options
@@ -44,6 +44,9 @@ lwres {
view <string> <optional_class>;
};
+managed-keys { <string> <string> <integer> <integer> <integer>
+ <quoted_string>; ... };
+
masters <string> [ port <integer> ] { ( <masters> | <ipv4_address> [ port
<integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
@@ -52,6 +55,7 @@ options {
acache-enable <boolean>;
additional-from-auth <boolean>;
additional-from-cache <boolean>;
+ allow-new-zones <boolean>;
allow-notify { <address_match_element>; ... };
allow-query { <address_match_element>; ... };
allow-query-cache { <address_match_element>; ... };
@@ -68,11 +72,14 @@ options {
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
* ) ];
+ attach-cache <string>;
auth-nxdomain <boolean>; // default changed
avoid-v4-udp-ports { <portrange>; ... };
avoid-v6-udp-ports { <portrange>; ... };
+ bindkeys-file <quoted_string>;
blackhole { <address_match_element>; ... };
cache-file <quoted_string>;
+ check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
check-mx-cname ( fail | warn | ignore );
@@ -85,15 +92,31 @@ options {
coresize <size>;
datasize <size>;
deallocate-on-exit <boolean>; // obsolete
+ deny-answer-addresses { <address_match_element>; ... } [
+ except-from { <quoted_string>; ... } ];
+ deny-answer-aliases { <quoted_string>; ... } [ except-from {
+ <quoted_string>; ... } ];
dialup <dialuptype>;
directory <quoted_string>;
disable-algorithms <string> { <string>; ... };
disable-empty-zone <string>;
+ dns64 <netprefix> {
+ break-dnssec <boolean>;
+ clients { <address_match_element>; ... };
+ exclude { <address_match_element>; ... };
+ mapped { <address_match_element>; ... };
+ recursive-only <boolean>;
+ suffix <ipv6_address>;
+ };
+ dns64-contact <string>;
+ dns64-server <string>;
dnssec-accept-expired <boolean>;
+ dnssec-dnskey-kskonly <boolean>;
dnssec-enable <boolean>;
dnssec-lookaside <string> trust-anchor <string>;
dnssec-must-be-secure <string> <boolean>;
- dnssec-validation <boolean>;
+ dnssec-secure-to-insecure <boolean>;
+ dnssec-validation ( yes | no | auto );
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ); ... };
@@ -105,6 +128,8 @@ options {
fake-iquery <boolean>; // obsolete
fetch-glue <boolean>; // obsolete
files <size>;
+ filter-aaaa { <address_match_element>; ... }; // not configured
+ filter-aaaa-on-v4 <v4_aaaa>; // not configured
flush-zones-on-shutdown <boolean>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> )
@@ -121,6 +146,7 @@ options {
listen-on [ port <integer> ] { <address_match_element>; ... };
listen-on-v6 [ port <integer> ] { <address_match_element>; ... };
maintain-ixfr-base <boolean>; // obsolete
+ managed-keys-directory <quoted_string>;
masterfile-format ( text | raw );
match-mapped-addresses <boolean>;
max-acache-size <size_no_default>;
@@ -168,13 +194,22 @@ options {
request-ixfr <boolean>;
request-nsid <boolean>;
reserved-sockets <integer>;
+ resolver-query-timeout <integer>;
+ response-policy {
+ zone <string> [ policy ( given | no-op | nxdomain | nodata
+ | cname <domain> ) ];
+ };
rfc2308-type1 <boolean>; // not yet implemented
root-delegation-only [ exclude { <quoted_string>; ... } ];
rrset-order { [ class <string> ] [ type <string> ] [ name
<quoted_string> ] <string> <string>; ... };
+ secroots-file <quoted_string>;
serial-queries <integer>; // obsolete
serial-query-rate <integer>;
server-id ( <quoted_string> | none | hostname );
+ session-keyalg <string>;
+ session-keyfile ( <quoted_string> | none );
+ session-keyname <string>;
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
@@ -189,6 +224,7 @@ options {
tkey-dhkey <quoted_string> <integer>;
tkey-domain <quoted_string>;
tkey-gssapi-credential <quoted_string>;
+ tkey-gssapi-keytab <quoted_string>;
topology { <address_match_element>; ... }; // not implemented
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
@@ -242,6 +278,7 @@ view <string> <optional_class> {
acache-enable <boolean>;
additional-from-auth <boolean>;
additional-from-cache <boolean>;
+ allow-new-zones <boolean>;
allow-notify { <address_match_element>; ... };
allow-query { <address_match_element>; ... };
allow-query-cache { <address_match_element>; ... };
@@ -258,8 +295,10 @@ view <string> <optional_class> {
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
* ) ];
+ attach-cache <string>;
auth-nxdomain <boolean>; // default changed
cache-file <quoted_string>;
+ check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
check-mx-cname ( fail | warn | ignore );
@@ -270,17 +309,33 @@ view <string> <optional_class> {
cleaning-interval <integer>;
clients-per-query <integer>;
database <string>;
+ deny-answer-addresses { <address_match_element>; ... } [
+ except-from { <quoted_string>; ... } ];
+ deny-answer-aliases { <quoted_string>; ... } [ except-from {
+ <quoted_string>; ... } ];
dialup <dialuptype>;
disable-algorithms <string> { <string>; ... };
disable-empty-zone <string>;
dlz <string> {
database <string>;
};
+ dns64 <netprefix> {
+ break-dnssec <boolean>;
+ clients { <address_match_element>; ... };
+ exclude { <address_match_element>; ... };
+ mapped { <address_match_element>; ... };
+ recursive-only <boolean>;
+ suffix <ipv6_address>;
+ };
+ dns64-contact <string>;
+ dns64-server <string>;
dnssec-accept-expired <boolean>;
+ dnssec-dnskey-kskonly <boolean>;
dnssec-enable <boolean>;
dnssec-lookaside <string> trust-anchor <string>;
dnssec-must-be-secure <string> <boolean>;
- dnssec-validation <boolean>;
+ dnssec-secure-to-insecure <boolean>;
+ dnssec-validation ( yes | no | auto );
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] | <ipv4_address> [ port <integer> ] |
<ipv6_address> [ port <integer> ] ); ... };
@@ -289,6 +344,8 @@ view <string> <optional_class> {
empty-server <string>;
empty-zones-enable <boolean>;
fetch-glue <boolean>; // obsolete
+ filter-aaaa { <address_match_element>; ... }; // not configured
+ filter-aaaa-on-v4 <v4_aaaa>; // not configured
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> )
[ port <integer> ]; ... };
@@ -300,6 +357,8 @@ view <string> <optional_class> {
key-directory <quoted_string>;
lame-ttl <integer>;
maintain-ixfr-base <boolean>; // obsolete
+ managed-keys { <string> <string> <integer> <integer> <integer>
+ <quoted_string>; ... };
masterfile-format ( text | raw );
match-clients { <address_match_element>; ... };
match-destinations { <address_match_element>; ... };
@@ -338,6 +397,11 @@ view <string> <optional_class> {
recursion <boolean>;
request-ixfr <boolean>;
request-nsid <boolean>;
+ resolver-query-timeout <integer>;
+ response-policy {
+ zone <string> [ policy ( given | no-op | nxdomain | nodata
+ | cname <domain> ) ];
+ };
rfc2308-type1 <boolean>; // not yet implemented
root-delegation-only [ exclude { <quoted_string>; ... } ];
rrset-order { [ class <string> ] [ type <string> ] [ name
@@ -395,6 +459,8 @@ view <string> <optional_class> {
<integer> | * ) ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port (
<integer> | * ) ];
+ auto-dnssec ( allow | maintain | create | off );
+ check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
check-mx-cname ( fail | warn | ignore );
@@ -405,6 +471,8 @@ view <string> <optional_class> {
database <string>;
delegation-only <boolean>;
dialup <dialuptype>;
+ dnssec-dnskey-kskonly <boolean>;
+ dnssec-secure-to-insecure <boolean>;
file <quoted_string>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> |
@@ -440,6 +508,9 @@ view <string> <optional_class> {
nsec3-test-zone <boolean>; // test only
pubkey <integer> <integer> <integer>
<quoted_string>; // obsolete
+ server-addresses { ( <ipv4_address> | <ipv6_address> ) [
+ port <integer> ]; ... };
+ server-names { <quoted_string>; ... };
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
@@ -449,13 +520,14 @@ view <string> <optional_class> {
transfer-source-v6 ( <ipv6_address> | * ) [ port (
<integer> | * ) ];
try-tcp-refresh <boolean>;
- type ( master | slave | stub | hint | forward |
- delegation-only );
+ type ( master | slave | stub | static-stub | hint | forward
+ | delegation-only );
update-check-ksk <boolean>;
- update-policy { ( grant | deny ) <string> ( name |
- subdomain | wildcard | self | selfsub | selfwild |
+ update-policy ( local | { ( grant | deny ) <string> ( name
+ | subdomain | wildcard | self | selfsub | selfwild |
krb5-self | ms-self | krb5-subdomain | ms-subdomain |
- tcp-self | 6to4-self ) <string> <rrtypelist>; ... };
+ tcp-self | 6to4-self | zonesub | external ) [ <string>
+ ] <rrtypelist>; ... };
use-alt-transfer-source <boolean>;
zero-no-soa-ttl <boolean>;
zone-statistics <boolean>;
@@ -475,6 +547,8 @@ zone <string> <optional_class> {
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> |
* ) ];
+ auto-dnssec ( allow | maintain | create | off );
+ check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
check-mx-cname ( fail | warn | ignore );
@@ -485,6 +559,8 @@ zone <string> <optional_class> {
database <string>;
delegation-only <boolean>;
dialup <dialuptype>;
+ dnssec-dnskey-kskonly <boolean>;
+ dnssec-secure-to-insecure <boolean>;
file <quoted_string>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> )
@@ -517,6 +593,9 @@ zone <string> <optional_class> {
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
pubkey <integer> <integer> <integer> <quoted_string>; // obsolete
+ server-addresses { ( <ipv4_address> | <ipv6_address> ) [ port
+ <integer> ]; ... };
+ server-names { <quoted_string>; ... };
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
@@ -524,12 +603,13 @@ zone <string> <optional_class> {
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ];
try-tcp-refresh <boolean>;
- type ( master | slave | stub | hint | forward | delegation-only );
+ type ( master | slave | stub | static-stub | hint | forward |
+ delegation-only );
update-check-ksk <boolean>;
- update-policy { ( grant | deny ) <string> ( name | subdomain |
- wildcard | self | selfsub | selfwild | krb5-self | ms-self |
- krb5-subdomain | ms-subdomain | tcp-self | 6to4-self ) <string>
- <rrtypelist>; ... };
+ update-policy ( local | { ( grant | deny ) <string> ( name |
+ subdomain | wildcard | self | selfsub | selfwild | krb5-self |
+ ms-self | krb5-subdomain | ms-subdomain | tcp-self | 6to4-self
+ | zonesub | external ) [ <string> ] <rrtypelist>; ... };
use-alt-transfer-source <boolean>;
zero-no-soa-ttl <boolean>;
zone-statistics <boolean>;
diff --git a/lib/bind9/Makefile.in b/lib/bind9/Makefile.in
index e37d524cb070..ffc2ad9d6858 100644
--- a/lib/bind9/Makefile.in
+++ b/lib/bind9/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.11 2007-06-19 23:47:16 tbox Exp $
+# $Id: Makefile.in,v 1.14 2009-12-05 23:31:40 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/lib/bind9/api b/lib/bind9/api
index f3b0f9fc331f..78dd0b402a89 100644
--- a/lib/bind9/api
+++ b/lib/bind9/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 50
-LIBREVISION = 4
+LIBINTERFACE = 80
+LIBREVISION = 1
LIBAGE = 0
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index 76ca510d23f2..6fa9aa9a5ba1 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check.c,v 1.95.12.6 2010-03-04 23:47:53 tbox Exp $ */
+/* $Id: check.c,v 1.125 2011-01-07 23:47:07 tbox Exp $ */
/*! \file */
@@ -103,7 +103,7 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"rrset-order: invalid name '%s'", str);
@@ -202,7 +202,7 @@ check_dual_stack(const cfg_obj_t *options, isc_log_t *logctx) {
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
tresult = dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL);
+ 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad name '%s'", str);
@@ -265,7 +265,7 @@ disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) {
str = cfg_obj_asstring(obj);
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- tresult = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad domain name '%s'", str);
@@ -352,7 +352,7 @@ mustbesecure(const cfg_obj_t *secure, isc_symtab_t *symtab, isc_log_t *logctx,
str = cfg_obj_asstring(obj);
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
- result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad domain name '%s'", str);
@@ -407,7 +407,7 @@ check_viewacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
static const char *acls[] = { "allow-query", "allow-query-on",
"allow-query-cache", "allow-query-cache-on",
"blackhole", "match-clients", "match-destinations",
- "sortlist", NULL };
+ "sortlist", "filter-aaaa", NULL };
while (acls[i] != NULL) {
tresult = checkacl(acls[i++], actx, NULL, voptions, config,
@@ -418,6 +418,106 @@ check_viewacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
return (result);
}
+static const unsigned char zeros[16];
+
+static isc_result_t
+check_dns64(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
+ const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ const cfg_obj_t *dns64 = NULL;
+ const cfg_obj_t *options;
+ const cfg_listelt_t *element;
+ const cfg_obj_t *map, *obj;
+ isc_netaddr_t na, sa;
+ unsigned int prefixlen;
+ int nbytes;
+ int i;
+
+ static const char *acls[] = { "client", "exclude", "mapped", NULL};
+
+ if (voptions != NULL)
+ cfg_map_get(voptions, "dns64", &dns64);
+ if (config != NULL && dns64 == NULL) {
+ options = NULL;
+ cfg_map_get(config, "options", &options);
+ if (options != NULL)
+ cfg_map_get(options, "dns64", &dns64);
+ }
+ if (dns64 == NULL)
+ return (ISC_R_SUCCESS);
+
+ for (element = cfg_list_first(dns64);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ map = cfg_listelt_value(element);
+ obj = cfg_map_getname(map);
+
+ cfg_obj_asnetprefix(obj, &na, &prefixlen);
+ if (na.family != AF_INET6) {
+ cfg_obj_log(map, logctx, ISC_LOG_ERROR,
+ "dns64 requires a IPv6 prefix");
+ result = ISC_R_FAILURE;
+ continue;
+ }
+
+ if (prefixlen != 32 && prefixlen != 40 && prefixlen != 48 &&
+ prefixlen != 56 && prefixlen != 64 && prefixlen != 96) {
+ cfg_obj_log(map, logctx, ISC_LOG_ERROR,
+ "bad prefix length %u [32/40/48/56/64/96]",
+ prefixlen);
+ result = ISC_R_FAILURE;
+ continue;
+ }
+
+ for (i = 0; acls[i] != NULL; i++) {
+ obj = NULL;
+ (void)cfg_map_get(map, acls[i], &obj);
+ if (obj != NULL) {
+ dns_acl_t *acl = NULL;
+ isc_result_t tresult;
+
+ tresult = cfg_acl_fromconfig(obj, config,
+ logctx, actx,
+ mctx, 0, &acl);
+ if (acl != NULL)
+ dns_acl_detach(&acl);
+ if (tresult != ISC_R_SUCCESS)
+ result = tresult;
+ }
+ }
+
+ obj = NULL;
+ (void)cfg_map_get(map, "suffix", &obj);
+ if (obj != NULL) {
+ isc_netaddr_fromsockaddr(&sa, cfg_obj_assockaddr(obj));
+ if (sa.family != AF_INET6) {
+ cfg_obj_log(map, logctx, ISC_LOG_ERROR,
+ "dns64 requires a IPv6 suffix");
+ result = ISC_R_FAILURE;
+ continue;
+ }
+ nbytes = prefixlen / 8 + 4;
+ if (prefixlen >= 32 && prefixlen <= 64)
+ nbytes++;
+ if (memcmp(sa.type.in6.s6_addr, zeros, nbytes) != 0) {
+ char netaddrbuf[ISC_NETADDR_FORMATSIZE];
+ isc_netaddr_format(&sa, netaddrbuf,
+ sizeof(netaddrbuf));
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "bad suffix '%s' leading "
+ "%u octets not zeros",
+ netaddrbuf, nbytes);
+ result = ISC_R_FAILURE;
+ }
+ }
+ }
+
+ return (result);
+}
+
+
/*
* Check allow-recursion and allow-recursion-on acls, and also log a
* warning if they're inconsistent with the "recursion" option.
@@ -493,6 +593,78 @@ check_recursionacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
return (result);
}
+static isc_result_t
+check_filteraaaa(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
+ const char *viewname, const cfg_obj_t *config,
+ isc_log_t *logctx, isc_mem_t *mctx)
+{
+ const cfg_obj_t *options, *aclobj, *obj = NULL;
+ dns_acl_t *acl = NULL;
+ isc_result_t result = ISC_R_SUCCESS, tresult;
+ dns_v4_aaaa_t filter;
+ const char *forview = " for view ";
+
+ if (voptions != NULL)
+ cfg_map_get(voptions, "filter-aaaa-on-v4", &obj);
+ if (obj == NULL && config != NULL) {
+ options = NULL;
+ cfg_map_get(config, "options", &options);
+ if (options != NULL)
+ cfg_map_get(options, "filter-aaaa-on-v4", &obj);
+ }
+
+ if (obj == NULL)
+ filter = dns_v4_aaaa_ok; /* default */
+ else if (cfg_obj_isboolean(obj))
+ filter = cfg_obj_asboolean(obj) ? dns_v4_aaaa_filter :
+ dns_v4_aaaa_ok;
+ else
+ filter = dns_v4_aaaa_break_dnssec; /* break-dnssec */
+
+ if (viewname == NULL) {
+ viewname = "";
+ forview = "";
+ }
+
+ aclobj = options = NULL;
+ acl = NULL;
+
+ if (voptions != NULL)
+ cfg_map_get(voptions, "filter-aaaa", &aclobj);
+ if (config != NULL && aclobj == NULL) {
+ options = NULL;
+ cfg_map_get(config, "options", &options);
+ if (options != NULL)
+ cfg_map_get(options, "filter-aaaa", &aclobj);
+ }
+ if (aclobj == NULL)
+ return (result);
+
+ tresult = cfg_acl_fromconfig(aclobj, config, logctx,
+ actx, mctx, 0, &acl);
+
+ if (tresult != ISC_R_SUCCESS) {
+ result = tresult;
+ } else if (filter != dns_v4_aaaa_ok && dns_acl_isnone(acl)) {
+ cfg_obj_log(aclobj, logctx, ISC_LOG_WARNING,
+ "both \"filter-aaaa-on-v4 %s;\" and "
+ "\"filter-aaaa\" is 'none;'%s%s",
+ filter == dns_v4_aaaa_break_dnssec ?
+ "break-dnssec" : "yes", forview, viewname);
+ result = ISC_R_FAILURE;
+ } else if (filter == dns_v4_aaaa_ok && !dns_acl_isnone(acl)) {
+ cfg_obj_log(aclobj, logctx, ISC_LOG_WARNING,
+ "both \"filter-aaaa-on-v4 no;\" and "
+ "\"filter-aaaa\" is set%s%s", forview, viewname);
+ result = ISC_R_FAILURE;
+ }
+
+ if (acl != NULL)
+ dns_acl_detach(&acl);
+
+ return (result);
+}
+
typedef struct {
const char *name;
unsigned int scale;
@@ -524,6 +696,12 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
{ "statistics-interval", 60, 28 * 24 * 60 }, /* 28 days */
};
+ static const char *server_contact[] = {
+ "empty-server", "empty-contact",
+ "dns64-server", "dns64-contact",
+ NULL
+ };
+
/*
* Check that fields specified in units of time other than seconds
* have reasonable values.
@@ -620,7 +798,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(name, &b,
dns_rootname,
- ISC_FALSE, NULL);
+ 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad domain name '%s'",
@@ -666,14 +844,24 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
element = cfg_list_next(element))
{
const char *dlv;
+ const cfg_obj_t *anchor;
obj = cfg_listelt_value(element);
dlv = cfg_obj_asstring(cfg_tuple_get(obj, "domain"));
+ anchor = cfg_tuple_get(obj, "trust-anchor");
+
+ /*
+ * If domain is "auto" and trust anchor is missing,
+ * skip remaining tests
+ */
+ if (!strcmp(dlv, "auto") && cfg_obj_isvoid(anchor))
+ continue;
+
isc_buffer_init(&b, dlv, strlen(dlv));
isc_buffer_add(&b, strlen(dlv));
tresult = dns_name_fromtext(name, &b, dns_rootname,
- ISC_TRUE, NULL);
+ 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"bad domain name '%s'", dlv);
@@ -701,19 +889,32 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
if (result == ISC_R_SUCCESS)
result = ISC_R_FAILURE;
}
- dlv = cfg_obj_asstring(cfg_tuple_get(obj,
- "trust-anchor"));
- isc_buffer_init(&b, dlv, strlen(dlv));
- isc_buffer_add(&b, strlen(dlv));
- tresult = dns_name_fromtext(name, &b, dns_rootname,
- ISC_TRUE, NULL);
- if (tresult != ISC_R_SUCCESS) {
+
+ if (!cfg_obj_isvoid(anchor)) {
+ dlv = cfg_obj_asstring(anchor);
+ isc_buffer_init(&b, dlv, strlen(dlv));
+ isc_buffer_add(&b, strlen(dlv));
+ tresult = dns_name_fromtext(name, &b,
+ dns_rootname,
+ DNS_NAME_DOWNCASE,
+ NULL);
+ if (tresult != ISC_R_SUCCESS) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "bad domain name '%s'",
+ dlv);
+ if (result == ISC_R_SUCCESS)
+ result = tresult;
+ }
+ } else {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
- "bad domain name '%s'", dlv);
+ "dnssec-lookaside requires "
+ "either 'auto' or a domain and "
+ "trust anchor");
if (result == ISC_R_SUCCESS)
- result = tresult;
+ result = ISC_R_FAILURE;
}
}
+
if (symtab != NULL)
isc_symtab_destroy(&symtab);
}
@@ -743,38 +944,29 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
}
/*
- * Check empty zone configuration.
+ * Check server/contacts for syntactic validity.
*/
- obj = NULL;
- (void)cfg_map_get(options, "empty-server", &obj);
- if (obj != NULL) {
- str = cfg_obj_asstring(obj);
- isc_buffer_init(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
- if (tresult != ISC_R_SUCCESS) {
- cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
- "empty-server: invalid name '%s'", str);
- result = ISC_R_FAILURE;
- }
- }
-
- obj = NULL;
- (void)cfg_map_get(options, "empty-contact", &obj);
- if (obj != NULL) {
- str = cfg_obj_asstring(obj);
- isc_buffer_init(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
- if (tresult != ISC_R_SUCCESS) {
- cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
- "empty-contact: invalid name '%s'", str);
- result = ISC_R_FAILURE;
+ for (i= 0; server_contact[i] != NULL; i++) {
+ obj = NULL;
+ (void)cfg_map_get(options, server_contact[i], &obj);
+ if (obj != NULL) {
+ str = cfg_obj_asstring(obj);
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ tresult = dns_name_fromtext(dns_fixedname_name(&fixed),
+ &b, dns_rootname, 0, NULL);
+ if (tresult != ISC_R_SUCCESS) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "%s: invalid name '%s'",
+ server_contact[i], str);
+ result = ISC_R_FAILURE;
+ }
}
}
+ /*
+ * Check empty zone configuration.
+ */
obj = NULL;
(void)cfg_map_get(options, "disable-empty-zone", &obj);
for (element = cfg_list_first(obj);
@@ -786,7 +978,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"disable-empty-zone: invalid name '%s'",
@@ -950,6 +1142,12 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
const char *str;
isc_buffer_t b;
+ /* Check for "update-policy local;" */
+ if (cfg_obj_isstring(policy) &&
+ strcmp("local", cfg_obj_asstring(policy)) == 0)
+ return (ISC_R_SUCCESS);
+
+ /* Now check the grant policy */
for (element = cfg_list_first(policy);
element != NULL;
element = cfg_list_next(element))
@@ -965,24 +1163,28 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(identity, logctx, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
result = tresult;
}
- dns_fixedname_init(&fixed);
- str = cfg_obj_asstring(dname);
- isc_buffer_init(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, ISC_FALSE, NULL);
- if (tresult != ISC_R_SUCCESS) {
- cfg_obj_log(dname, logctx, ISC_LOG_ERROR,
- "'%s' is not a valid name", str);
- result = tresult;
+ if (tresult == ISC_R_SUCCESS &&
+ strcasecmp(cfg_obj_asstring(matchtype), "zonesub") != 0) {
+ dns_fixedname_init(&fixed);
+ str = cfg_obj_asstring(dname);
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ tresult = dns_name_fromtext(dns_fixedname_name(&fixed),
+ &b, dns_rootname, 0, NULL);
+ if (tresult != ISC_R_SUCCESS) {
+ cfg_obj_log(dname, logctx, ISC_LOG_ERROR,
+ "'%s' is not a valid name", str);
+ result = tresult;
+ }
}
+
if (tresult == ISC_R_SUCCESS &&
strcasecmp(cfg_obj_asstring(matchtype), "wildcard") == 0 &&
!dns_name_iswildcard(dns_fixedname_name(&fixed))) {
@@ -1020,7 +1222,8 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
#define HINTZONE 8
#define FORWARDZONE 16
#define DELEGATIONZONE 32
-#define CHECKACL 64
+#define STATICSTUBZONE 64
+#define CHECKACL 128
typedef struct {
const char *name;
@@ -1033,7 +1236,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
dns_rdataclass_t defclass, cfg_aclconfctx_t *actx,
isc_log_t *logctx, isc_mem_t *mctx)
{
- const char *zname;
+ const char *znamestr;
const char *typestr;
unsigned int ztype;
const cfg_obj_t *zoptions;
@@ -1043,11 +1246,14 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
unsigned int i;
dns_rdataclass_t zclass;
dns_fixedname_t fixedname;
+ dns_name_t *zname = NULL;
isc_buffer_t b;
isc_boolean_t root = ISC_FALSE;
+ const cfg_listelt_t *element;
static optionstable options[] = {
- { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | CHECKACL },
+ { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | CHECKACL |
+ STATICSTUBZONE },
{ "allow-notify", SLAVEZONE | CHECKACL },
{ "allow-transfer", MASTERZONE | SLAVEZONE | CHECKACL },
{ "notify", MASTERZONE | SLAVEZONE },
@@ -1070,12 +1276,14 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
{ "min-retry-time", SLAVEZONE | STUBZONE },
{ "max-refresh-time", SLAVEZONE | STUBZONE },
{ "min-refresh-time", SLAVEZONE | STUBZONE },
+ { "dnssec-secure-to-insecure", MASTERZONE },
{ "sig-validity-interval", MASTERZONE },
{ "sig-re-signing-interval", MASTERZONE },
{ "sig-signing-nodes", MASTERZONE },
{ "sig-signing-type", MASTERZONE },
{ "sig-signing-signatures", MASTERZONE },
- { "zone-statistics", MASTERZONE | SLAVEZONE | STUBZONE },
+ { "zone-statistics", MASTERZONE | SLAVEZONE | STUBZONE |
+ STATICSTUBZONE},
{ "allow-update", MASTERZONE | CHECKACL },
{ "allow-update-forwarding", SLAVEZONE | CHECKACL },
{ "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE },
@@ -1089,12 +1297,17 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
{ "key-directory", MASTERZONE },
{ "check-wildcard", MASTERZONE },
{ "check-mx", MASTERZONE },
+ { "check-dup-records", MASTERZONE },
{ "integrity-check", MASTERZONE },
{ "check-mx-cname", MASTERZONE },
{ "check-srv-cname", MASTERZONE },
{ "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE },
{ "update-check-ksk", MASTERZONE },
+ { "dnssec-dnskey-kskonly", MASTERZONE },
+ { "auto-dnssec", MASTERZONE },
{ "try-tcp-refresh", SLAVEZONE },
+ { "server-addresses", STATICSTUBZONE },
+ { "server-names", STATICSTUBZONE },
};
static optionstable dialups[] = {
@@ -1104,7 +1317,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
{ "passive", SLAVEZONE | STUBZONE },
};
- zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
+ znamestr = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
zoptions = cfg_tuple_get(zconfig, "options");
@@ -1112,7 +1325,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
(void)cfg_map_get(zoptions, "type", &obj);
if (obj == NULL) {
cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
- "zone '%s': type not present", zname);
+ "zone '%s': type not present", znamestr);
return (ISC_R_FAILURE);
}
@@ -1123,6 +1336,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
ztype = SLAVEZONE;
else if (strcasecmp(typestr, "stub") == 0)
ztype = STUBZONE;
+ else if (strcasecmp(typestr, "static-stub") == 0)
+ ztype = STATICSTUBZONE;
else if (strcasecmp(typestr, "forward") == 0)
ztype = FORWARDZONE;
else if (strcasecmp(typestr, "hint") == 0)
@@ -1132,7 +1347,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
else {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"zone '%s': invalid type %s",
- zname, typestr);
+ znamestr, typestr);
return (ISC_R_FAILURE);
}
@@ -1146,14 +1361,14 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
if (result != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"zone '%s': invalid class %s",
- zname, r.base);
+ znamestr, r.base);
return (ISC_R_FAILURE);
}
if (zclass != defclass) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"zone '%s': class '%s' does not "
"match view/default class",
- zname, r.base);
+ znamestr, r.base);
return (ISC_R_FAILURE);
}
}
@@ -1164,26 +1379,25 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
* deals with strings.
*/
dns_fixedname_init(&fixedname);
- isc_buffer_init(&b, zname, strlen(zname));
- isc_buffer_add(&b, strlen(zname));
+ isc_buffer_init(&b, znamestr, strlen(znamestr));
+ isc_buffer_add(&b, strlen(znamestr));
tresult = dns_name_fromtext(dns_fixedname_name(&fixedname), &b,
- dns_rootname, ISC_TRUE, NULL);
+ dns_rootname, DNS_NAME_DOWNCASE, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
- "zone '%s': is not a valid name", zname);
+ "zone '%s': is not a valid name", znamestr);
result = ISC_R_FAILURE;
} else {
char namebuf[DNS_NAME_FORMATSIZE];
- dns_name_format(dns_fixedname_name(&fixedname),
- namebuf, sizeof(namebuf));
+ zname = dns_fixedname_name(&fixedname);
+ dns_name_format(zname, namebuf, sizeof(namebuf));
tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 : 2,
symtab, "zone '%s': already exists "
"previous definition: %s:%u", logctx, mctx);
if (tresult != ISC_R_SUCCESS)
result = tresult;
- if (dns_name_equal(dns_fixedname_name(&fixedname),
- dns_rootname))
+ if (dns_name_equal(zname, dns_rootname))
root = ISC_TRUE;
}
@@ -1202,13 +1416,15 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"option '%s' is not allowed "
"in '%s' zone '%s'",
- options[i].name, typestr, zname);
+ options[i].name, typestr,
+ znamestr);
result = ISC_R_FAILURE;
} else
cfg_obj_log(obj, logctx, ISC_LOG_WARNING,
"option '%s' is not allowed "
"in '%s' zone '%s'",
- options[i].name, typestr, zname);
+ options[i].name, typestr,
+ znamestr);
}
obj = NULL;
if ((options[i].allowed & ztype) != 0 &&
@@ -1230,7 +1446,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
if (cfg_map_get(zoptions, "masters", &obj) != ISC_R_SUCCESS) {
cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR,
"zone '%s': missing 'masters' entry",
- zname);
+ znamestr);
result = ISC_R_FAILURE;
} else {
isc_uint32_t count;
@@ -1241,7 +1457,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
if (tresult == ISC_R_SUCCESS && count == 0) {
cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR,
"zone '%s': empty 'masters' entry",
- zname);
+ znamestr);
result = ISC_R_FAILURE;
}
}
@@ -1251,7 +1467,10 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
* Master zones can't have both "allow-update" and "update-policy".
*/
if (ztype == MASTERZONE) {
- isc_result_t res1, res2;
+ isc_result_t res1, res2, res3;
+ const char *arg;
+ isc_boolean_t ddns;
+
obj = NULL;
res1 = cfg_map_get(zoptions, "allow-update", &obj);
obj = NULL;
@@ -1260,11 +1479,32 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"zone '%s': 'allow-update' is ignored "
"when 'update-policy' is present",
- zname);
+ znamestr);
result = ISC_R_FAILURE;
} else if (res2 == ISC_R_SUCCESS &&
check_update_policy(obj, logctx) != ISC_R_SUCCESS)
result = ISC_R_FAILURE;
+ ddns = ISC_TF(res1 == ISC_R_SUCCESS || res2 == ISC_R_SUCCESS);
+
+ obj = NULL;
+ arg = "off";
+ res3 = cfg_map_get(zoptions, "auto-dnssec", &obj);
+ if (res3 == ISC_R_SUCCESS)
+ arg = cfg_obj_asstring(obj);
+ if (strcasecmp(arg, "off") != 0 && !ddns) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "'auto-dnssec %s;' requires "
+ "dynamic DNS to be configured in the zone",
+ arg);
+ result = ISC_R_FAILURE;
+ }
+ if (strcasecmp(arg, "create") == 0) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "'auto-dnssec create;' is not "
+ "yet implemented");
+ result = ISC_R_FAILURE;
+ }
+
obj = NULL;
res1 = cfg_map_get(zoptions, "sig-signing-type", &obj);
if (res1 == ISC_R_SUCCESS) {
@@ -1298,7 +1538,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
"dialup type '%s' is not "
"allowed in '%s' "
"zone '%s'",
- str, typestr, zname);
+ str, typestr, znamestr);
result = ISC_R_FAILURE;
}
break;
@@ -1306,7 +1546,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
if (i == sizeof(dialups) / sizeof(dialups[0])) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"invalid dialup type '%s' in zone "
- "'%s'", str, zname);
+ "'%s'", str, znamestr);
result = ISC_R_FAILURE;
}
}
@@ -1330,6 +1570,78 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
result = ISC_R_FAILURE;
/*
+ * Check validity of static stub server addresses.
+ */
+ obj = NULL;
+ (void)cfg_map_get(zoptions, "server-addresses", &obj);
+ if (ztype == STATICSTUBZONE && obj != NULL) {
+ for (element = cfg_list_first(obj);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ isc_sockaddr_t sa;
+ isc_netaddr_t na;
+ obj = cfg_listelt_value(element);
+ sa = *cfg_obj_assockaddr(obj);
+
+ if (isc_sockaddr_getport(&sa) != 0) {
+ result = ISC_R_FAILURE;
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "port is not configurable for "
+ "static stub server-addresses");
+ }
+
+ isc_netaddr_fromsockaddr(&na, &sa);
+ if (isc_netaddr_getzone(&na) != 0) {
+ result = ISC_R_FAILURE;
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "scoped address is not allowed "
+ "for static stub "
+ "server-addresses");
+ }
+ }
+ }
+
+ /*
+ * Check validity of static stub server names.
+ */
+ obj = NULL;
+ (void)cfg_map_get(zoptions, "server-names", &obj);
+ if (zname != NULL && ztype == STATICSTUBZONE && obj != NULL) {
+ for (element = cfg_list_first(obj);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const char *snamestr;
+ dns_fixedname_t fixed_sname;
+ isc_buffer_t b2;
+ dns_name_t *sname;
+
+ obj = cfg_listelt_value(element);
+ snamestr = cfg_obj_asstring(obj);
+
+ dns_fixedname_init(&fixed_sname);
+ isc_buffer_init(&b2, snamestr, strlen(snamestr));
+ isc_buffer_add(&b2, strlen(snamestr));
+ sname = dns_fixedname_name(&fixed_sname);
+ tresult = dns_name_fromtext(sname, &b2, dns_rootname,
+ 0, NULL);
+ if (tresult != ISC_R_SUCCESS) {
+ cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
+ "server-name '%s' is not a valid "
+ "name", snamestr);
+ result = ISC_R_FAILURE;
+ } else if (dns_name_issubdomain(sname, zname)) {
+ cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
+ "server-name '%s' must not be a "
+ "subdomain of zone name '%s'",
+ snamestr, znamestr);
+ result = ISC_R_FAILURE;
+ }
+ }
+ }
+
+ /*
* Check various options.
*/
tresult = check_options(zoptions, logctx, mctx);
@@ -1352,7 +1664,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
(ztype == MASTERZONE || ztype == HINTZONE)) {
cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
"zone '%s': missing 'file' entry",
- zname);
+ znamestr);
result = tresult;
}
}
@@ -1374,6 +1686,9 @@ bind9_check_key(const cfg_obj_t *key, isc_log_t *logctx) {
const char *algorithm;
int i;
size_t len = 0;
+ isc_result_t result;
+ isc_buffer_t buf;
+ unsigned char secretbuf[1024];
static const algorithmtable algorithms[] = {
{ "hmac-md5", 128 },
{ "hmac-md5.sig-alg.reg.int", 0 },
@@ -1396,6 +1711,14 @@ bind9_check_key(const cfg_obj_t *key, isc_log_t *logctx) {
return (ISC_R_FAILURE);
}
+ isc_buffer_init(&buf, secretbuf, sizeof(secretbuf));
+ result = isc_base64_decodestring(cfg_obj_asstring(secretobj), &buf);
+ if (result != ISC_R_SUCCESS) {
+ cfg_obj_log(secretobj, logctx, ISC_LOG_ERROR,
+ "bad secret '%s'", isc_result_totext(result));
+ return (result);
+ }
+
algorithm = cfg_obj_asstring(algobj);
for (i = 0; algorithms[i].name != NULL; i++) {
len = strlen(algorithms[i].name);
@@ -1480,7 +1803,7 @@ check_keylist(const cfg_obj_t *keys, isc_symtab_t *symtab,
isc_buffer_init(&b, keyid, strlen(keyid));
isc_buffer_add(&b, strlen(keyid));
tresult = dns_name_fromtext(name, &b, dns_rootname,
- ISC_FALSE, NULL);
+ 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
"key '%s': bad key name", keyid);
@@ -1650,7 +1973,7 @@ check_servers(const cfg_obj_t *config, const cfg_obj_t *voptions,
isc_buffer_add(&b, strlen(keyval));
keyname = dns_fixedname_name(&fname);
tresult = dns_name_fromtext(keyname, &b, dns_rootname,
- ISC_FALSE, NULL);
+ 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(keys, logctx, ISC_LOG_ERROR,
"bad key name '%s'", keyval);
@@ -1670,7 +1993,8 @@ check_servers(const cfg_obj_t *config, const cfg_obj_t *voptions,
}
static isc_result_t
-check_trusted_key(const cfg_obj_t *key, isc_log_t *logctx)
+check_trusted_key(const cfg_obj_t *key, isc_boolean_t managed,
+ isc_log_t *logctx)
{
const char *keystr, *keynamestr;
dns_fixedname_t fkeyname;
@@ -1704,6 +2028,19 @@ check_trusted_key(const cfg_obj_t *key, isc_log_t *logctx)
result = ISC_R_FAILURE;
}
+ if (managed) {
+ const char *initmethod;
+ initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init"));
+
+ if (strcasecmp(initmethod, "initial-key") != 0) {
+ cfg_obj_log(key, logctx, ISC_LOG_ERROR,
+ "managed key '%s': "
+ "invalid initialization method '%s'",
+ keynamestr, initmethod);
+ result = ISC_R_FAILURE;
+ }
+ }
+
isc_buffer_init(&keydatabuf, keydata, sizeof(keydata));
keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
@@ -1719,7 +2056,8 @@ check_trusted_key(const cfg_obj_t *key, isc_log_t *logctx)
if ((alg == DST_ALG_RSASHA1 || alg == DST_ALG_RSAMD5) &&
r.length > 1 && r.base[0] == 1 && r.base[1] == 3)
cfg_obj_log(key, logctx, ISC_LOG_WARNING,
- "trusted key '%s' has a weak exponent",
+ "%s key '%s' has a weak exponent",
+ managed ? "managed" : "trusted",
keynamestr);
}
@@ -1892,12 +2230,32 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
element2 != NULL;
element2 = cfg_list_next(element2)) {
obj = cfg_listelt_value(element2);
- tresult = check_trusted_key(obj, logctx);
+ tresult = check_trusted_key(obj, ISC_FALSE, logctx);
if (tresult != ISC_R_SUCCESS)
result = tresult;
}
}
+ keys = NULL;
+ if (voptions != NULL)
+ (void)cfg_map_get(voptions, "managed-keys", &keys);
+ if (keys == NULL)
+ (void)cfg_map_get(config, "managed-keys", &keys);
+
+ for (element = cfg_list_first(keys);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const cfg_obj_t *keylist = cfg_listelt_value(element);
+ for (element2 = cfg_list_first(keylist);
+ element2 != NULL;
+ element2 = cfg_list_next(element2)) {
+ obj = cfg_listelt_value(element2);
+ tresult = check_trusted_key(obj, ISC_TRUE, logctx);
+ if (tresult != ISC_R_SUCCESS)
+ result = tresult;
+ }
+ }
/*
* Check options.
*/
@@ -1917,7 +2275,16 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
if (tresult != ISC_R_SUCCESS)
result = tresult;
- cfg_aclconfctx_destroy(&actx);
+ tresult = check_filteraaaa(&actx, voptions, viewname, config,
+ logctx, mctx);
+ if (tresult != ISC_R_SUCCESS)
+ result = tresult;
+
+ tresult = check_dns64(&actx, voptions, config, logctx, mctx);
+ if (tresult != ISC_R_SUCCESS)
+ result = tresult;
+
+ cfg_aclconfctx_clear(&actx);
return (result);
}
@@ -2162,7 +2529,7 @@ bind9_check_controls(const cfg_obj_t *config, isc_log_t *logctx,
result = tresult;
}
}
- cfg_aclconfctx_destroy(&actx);
+ cfg_aclconfctx_clear(&actx);
return (result);
}
diff --git a/lib/bind9/include/bind9/getaddresses.h b/lib/bind9/include/bind9/getaddresses.h
index 677ced23f831..9ad80450db3a 100644
--- a/lib/bind9/include/bind9/getaddresses.h
+++ b/lib/bind9/include/bind9/getaddresses.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: getaddresses.h,v 1.9.332.2 2009-01-18 23:47:35 tbox Exp $ */
+/* $Id: getaddresses.h,v 1.11 2009-01-17 23:47:42 tbox Exp $ */
#ifndef BIND9_GETADDRESSES_H
#define BIND9_GETADDRESSES_H 1
diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in
index dfb8d7f61b5c..45c5c2a4174e 100644
--- a/lib/dns/Makefile.in
+++ b/lib/dns/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.163.50.2 2010-06-09 23:48:16 tbox Exp $
+# $Id: Makefile.in,v 1.176 2011-01-13 01:59:27 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -34,8 +34,7 @@ USE_ISC_SPNEGO = @USE_ISC_SPNEGO@
CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} \
${ISC_INCLUDES} @DST_OPENSSL_INC@ @DST_GSSAPI_INC@
-CDEFINES = -DUSE_MD5 @USE_OPENSSL@ @USE_PKCS11@ @USE_GSSAPI@ \
- ${USE_ISC_SPNEGO}
+CDEFINES = -DUSE_MD5 @USE_OPENSSL@ @USE_GSSAPI@ ${USE_ISC_SPNEGO}
CWARNINGS =
@@ -48,7 +47,7 @@ LIBS = @LIBS@
# Alphabetically
OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \
- opensslrsa_link.@O@
+ opensslgost_link.@O@ opensslrsa_link.@O@
DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \
dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \
@@ -58,24 +57,26 @@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \
DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \
cache.@O@ callbacks.@O@ compress.@O@ \
db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
- dlz.@O@ dnssec.@O@ ds.@O@ forward.@O@ iptable.@O@ journal.@O@ \
- keytable.@O@ lib.@O@ log.@O@ lookup.@O@ \
+ dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ forward.@O@ iptable.@O@ \
+ journal.@O@ keydata.@O@ keytable.@O@ \
+ lib.@O@ log.@O@ lookup.@O@ \
master.@O@ masterdump.@O@ message.@O@ \
- name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ order.@O@ peer.@O@ portlist.@O@ \
+ name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ order.@O@ peer.@O@ \
+ portlist.@O@ private.@O@ \
rbt.@O@ rbtdb.@O@ rbtdb64.@O@ rcode.@O@ rdata.@O@ \
- rdatalist.@O@ \
- rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ request.@O@ \
- resolver.@O@ result.@O@ rootns.@O@ sdb.@O@ sdlz.@O@ \
- soa.@O@ ssu.@O@ \
+ rdatalist.@O@ rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ \
+ request.@O@ resolver.@O@ result.@O@ rootns.@O@ rpz.@O@ \
+ rriterator.@O@ sdb.@O@ \
+ sdlz.@O@ soa.@O@ ssu.@O@ ssu_external.@O@ \
stats.@O@ tcpmsg.@O@ time.@O@ timer.@O@ tkey.@O@ \
- tsig.@O@ ttl.@O@ validator.@O@ \
+ tsec.@O@ tsig.@O@ ttl.@O@ validator.@O@ \
version.@O@ view.@O@ xfrin.@O@ zone.@O@ zonekey.@O@ zt.@O@
OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS}
# Alphabetically
-OPENSSLLINKSRCS = openssl_link.c openssldh_link.c \
- openssldsa_link.c opensslrsa_link.c
+OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \
+ opensslgost_link.c opensslrsa_link.c
DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \
dst_api.c dst_lib.c dst_parse.c \
@@ -85,17 +86,16 @@ DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \
DNSSRCS = acache.c acl.c adb.c byaddr.c \
cache.c callbacks.c compress.c \
db.c dbiterator.c dbtable.c diff.c dispatch.c \
- dlz.c dnssec.c ds.c forward.c iptable.c journal.c \
- keytable.c lib.c log.c lookup.c \
+ dlz.c dns64.c dnssec.c ds.c forward.c iptable.c journal.c \
+ keydata.c keytable.c lib.c log.c lookup.c \
master.c masterdump.c message.c \
name.c ncache.c nsec.c nsec3.c order.c peer.c portlist.c \
- rbt.c rbtdb.c rbtdb64.c rcode.c rdata.c \
- rdatalist.c \
+ rbt.c rbtdb.c rbtdb64.c rcode.c rdata.c rdatalist.c \
rdataset.c rdatasetiter.c rdataslab.c request.c \
- resolver.c result.c rootns.c sdb.c sdlz.c \
- soa.c ssu.c \
+ resolver.c result.c rootns.c rpz.c rriterator.c \
+ sdb.c sdlz.c soa.c ssu.c ssu_external.c \
stats.c tcpmsg.c time.c timer.c tkey.c \
- tsig.c ttl.c validator.c \
+ tsec.c tsig.c ttl.c validator.c \
version.c view.c xfrin.c zone.c zonekey.c zt.c ${OTHERSRCS}
SRCS = ${DSTSRCS} ${DNSSRCS}
diff --git a/lib/dns/acl.c b/lib/dns/acl.c
index cfb7fd8345da..118e3944882b 100644
--- a/lib/dns/acl.c
+++ b/lib/dns/acl.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: acl.c,v 1.50.44.3 2009-01-18 23:47:35 tbox Exp $ */
+/* $Id: acl.c,v 1.53 2009-01-17 23:47:42 tbox Exp $ */
/*! \file */
diff --git a/lib/dns/adb.c b/lib/dns/adb.c
index cd9cadf9412e..fcc2dd8ecdb9 100644
--- a/lib/dns/adb.c
+++ b/lib/dns/adb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: adb.c,v 1.243.42.6 2010-08-11 23:45:49 tbox Exp $ */
+/* $Id: adb.c,v 1.254 2010-12-21 23:47:08 tbox Exp $ */
/*! \file
*
@@ -66,13 +66,6 @@
#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
/*!
- * The number of buckets needs to be a prime (for good hashing).
- *
- * XXXRTH How many buckets do we need?
- */
-#define NBUCKETS 1009 /*%< how many buckets for names/addrs */
-
-/*!
* For type 3 negative cache entries, we will remember that the address is
* broken for this long. XXXMLG This is also used for actual addresses, too.
* The intent is to keep us from constantly asking about A/AAAA records
@@ -139,30 +132,37 @@ struct dns_adb {
*
* XXXRTH Have a per-bucket structure that contains all of these?
*/
- dns_adbnamelist_t names[NBUCKETS];
- dns_adbnamelist_t deadnames[NBUCKETS];
- /*% See dns_adbnamelist_t */
- isc_mutex_t namelocks[NBUCKETS];
- /*% See dns_adbnamelist_t */
- isc_boolean_t name_sd[NBUCKETS];
- /*% See dns_adbnamelist_t */
- unsigned int name_refcnt[NBUCKETS];
+ unsigned int nnames;
+ isc_mutex_t namescntlock;
+ unsigned int namescnt;
+ dns_adbnamelist_t *names;
+ dns_adbnamelist_t *deadnames;
+ isc_mutex_t *namelocks;
+ isc_boolean_t *name_sd;
+ unsigned int *name_refcnt;
/*!
- * Bucketized locks for entries.
+ * Bucketized locks and lists for entries.
*
* XXXRTH Have a per-bucket structure that contains all of these?
*/
- dns_adbentrylist_t entries[NBUCKETS];
- dns_adbentrylist_t deadentries[NBUCKETS];
- isc_mutex_t entrylocks[NBUCKETS];
- isc_boolean_t entry_sd[NBUCKETS]; /*%< shutting down */
- unsigned int entry_refcnt[NBUCKETS];
+ unsigned int nentries;
+ isc_mutex_t entriescntlock;
+ unsigned int entriescnt;
+ dns_adbentrylist_t *entries;
+ dns_adbentrylist_t *deadentries;
+ isc_mutex_t *entrylocks;
+ isc_boolean_t *entry_sd; /*%< shutting down */
+ unsigned int *entry_refcnt;
isc_event_t cevent;
isc_boolean_t cevent_sent;
isc_boolean_t shutting_down;
isc_eventlist_t whenshutdown;
+ isc_event_t growentries;
+ isc_boolean_t growentries_sent;
+ isc_event_t grownames;
+ isc_boolean_t grownames_sent;
};
/*
@@ -484,6 +484,322 @@ ttlclamp(dns_ttl_t ttl) {
}
/*
+ * Hashing is most efficient if the number of buckets is prime.
+ * The sequence below is the closest previous primes to 2^n and
+ * 1.5 * 2^n, for values of n from 10 to 28. (The tables will
+ * no longer grow beyond 2^28 entries.)
+ */
+static const unsigned nbuckets[] = { 1021, 1531, 2039, 3067, 4093, 6143,
+ 8191, 12281, 16381, 24571, 32749,
+ 49193, 65521, 98299, 131071, 199603,
+ 262139, 393209, 524287, 768431, 1048573,
+ 1572853, 2097143, 3145721, 4194301,
+ 6291449, 8388593, 12582893, 16777213,
+ 25165813, 33554393, 50331599, 67108859,
+ 100663291, 134217689, 201326557,
+ 268535431, 0 };
+
+static void
+grow_entries(isc_task_t *task, isc_event_t *ev) {
+ dns_adb_t *adb;
+ dns_adbentry_t *e;
+ dns_adbentrylist_t *newdeadentries = NULL;
+ dns_adbentrylist_t *newentries = NULL;
+ isc_boolean_t *newentry_sd = NULL;
+ isc_mutex_t *newentrylocks = NULL;
+ isc_result_t result;
+ unsigned int *newentry_refcnt = NULL;
+ unsigned int i, n, bucket;
+
+ adb = ev->ev_arg;
+ INSIST(DNS_ADB_VALID(adb));
+
+ isc_event_free(&ev);
+
+ isc_task_beginexclusive(task);
+
+ i = 0;
+ while (nbuckets[i] != 0 && adb->nentries >= nbuckets[i])
+ i++;
+ if (nbuckets[i] != 0)
+ n = nbuckets[i];
+ else
+ goto done;
+
+ DP(ISC_LOG_INFO, "adb: grow_entries to %u starting", n);
+
+ /*
+ * Are we shutting down?
+ */
+ for (i = 0; i < adb->nentries; i++)
+ if (adb->entry_sd[i])
+ goto cleanup;
+
+ /*
+ * Grab all the resources we need.
+ */
+ newentries = isc_mem_get(adb->mctx, sizeof(*newentries) * n);
+ newdeadentries = isc_mem_get(adb->mctx, sizeof(*newdeadentries) * n);
+ newentrylocks = isc_mem_get(adb->mctx, sizeof(*newentrylocks) * n);
+ newentry_sd = isc_mem_get(adb->mctx, sizeof(*newentry_sd) * n);
+ newentry_refcnt = isc_mem_get(adb->mctx, sizeof(*newentry_refcnt) * n);
+ if (newentries == NULL || newdeadentries == NULL ||
+ newentrylocks == NULL || newentry_sd == NULL ||
+ newentry_refcnt == NULL)
+ goto cleanup;
+
+ /*
+ * Initialise the new resources.
+ */
+ result = isc_mutexblock_init(newentrylocks, n);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ for (i = 0; i < n; i++) {
+ ISC_LIST_INIT(newentries[i]);
+ ISC_LIST_INIT(newdeadentries[i]);
+ newentry_sd[i] = ISC_FALSE;
+ newentry_refcnt[i] = 0;
+ adb->irefcnt++;
+ }
+
+ /*
+ * Move entries to new arrays.
+ */
+ for (i = 0; i < adb->nentries; i++) {
+ e = ISC_LIST_HEAD(adb->entries[i]);
+ while (e != NULL) {
+ ISC_LIST_UNLINK(adb->entries[i], e, plink);
+ bucket = isc_sockaddr_hash(&e->sockaddr, ISC_TRUE) % n;
+ e->lock_bucket = bucket;
+ ISC_LIST_APPEND(newentries[bucket], e, plink);
+ INSIST(adb->entry_refcnt[i] > 0);
+ adb->entry_refcnt[i]--;
+ newentry_refcnt[bucket]++;
+ e = ISC_LIST_HEAD(adb->entries[i]);
+ }
+ e = ISC_LIST_HEAD(adb->deadentries[i]);
+ while (e != NULL) {
+ ISC_LIST_UNLINK(adb->deadentries[i], e, plink);
+ bucket = isc_sockaddr_hash(&e->sockaddr, ISC_TRUE) % n;
+ e->lock_bucket = bucket;
+ ISC_LIST_APPEND(newdeadentries[bucket], e, plink);
+ INSIST(adb->entry_refcnt[i] > 0);
+ adb->entry_refcnt[i]--;
+ newentry_refcnt[bucket]++;
+ e = ISC_LIST_HEAD(adb->deadentries[i]);
+ }
+ INSIST(adb->entry_refcnt[i] == 0);
+ adb->irefcnt--;
+ }
+
+ /*
+ * Cleanup old resources.
+ */
+ DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
+ isc_mem_put(adb->mctx, adb->entries,
+ sizeof(*adb->entries) * adb->nentries);
+ isc_mem_put(adb->mctx, adb->deadentries,
+ sizeof(*adb->deadentries) * adb->nentries);
+ isc_mem_put(adb->mctx, adb->entrylocks,
+ sizeof(*adb->entrylocks) * adb->nentries);
+ isc_mem_put(adb->mctx, adb->entry_sd,
+ sizeof(*adb->entry_sd) * adb->nentries);
+ isc_mem_put(adb->mctx, adb->entry_refcnt,
+ sizeof(*adb->entry_refcnt) * adb->nentries);
+
+ /*
+ * Install new resources.
+ */
+ adb->entries = newentries;
+ adb->deadentries = newdeadentries;
+ adb->entrylocks = newentrylocks;
+ adb->entry_sd = newentry_sd;
+ adb->entry_refcnt = newentry_refcnt;
+ adb->nentries = n;
+
+ /*
+ * Only on success do we set adb->growentries_sent to ISC_FALSE.
+ * This will prevent us being continuously being called on error.
+ */
+ adb->growentries_sent = ISC_FALSE;
+ goto done;
+
+ cleanup:
+ if (newentries != NULL)
+ isc_mem_put(adb->mctx, newentries,
+ sizeof(*newentries) * n);
+ if (newdeadentries != NULL)
+ isc_mem_put(adb->mctx, newdeadentries,
+ sizeof(*newdeadentries) * n);
+ if (newentrylocks != NULL)
+ isc_mem_put(adb->mctx, newentrylocks,
+ sizeof(*newentrylocks) * n);
+ if (newentry_sd != NULL)
+ isc_mem_put(adb->mctx, newentry_sd,
+ sizeof(*newentry_sd) * n);
+ if (newentry_refcnt != NULL)
+ isc_mem_put(adb->mctx, newentry_refcnt,
+ sizeof(*newentry_refcnt) * n);
+ done:
+ isc_task_endexclusive(task);
+
+ LOCK(&adb->lock);
+ if (dec_adb_irefcnt(adb))
+ check_exit(adb);
+ UNLOCK(&adb->lock);
+ DP(ISC_LOG_INFO, "adb: grow_entries finished");
+}
+
+static void
+grow_names(isc_task_t *task, isc_event_t *ev) {
+ dns_adb_t *adb;
+ dns_adbname_t *name;
+ dns_adbnamelist_t *newdeadnames = NULL;
+ dns_adbnamelist_t *newnames = NULL;
+ isc_boolean_t *newname_sd = NULL;
+ isc_mutex_t *newnamelocks = NULL;
+ isc_result_t result;
+ unsigned int *newname_refcnt = NULL;
+ unsigned int i, n, bucket;
+
+ adb = ev->ev_arg;
+ INSIST(DNS_ADB_VALID(adb));
+
+ isc_event_free(&ev);
+
+ isc_task_beginexclusive(task);
+
+ i = 0;
+ while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i])
+ i++;
+ if (nbuckets[i] != 0)
+ n = nbuckets[i];
+ else
+ goto done;
+
+ DP(ISC_LOG_INFO, "adb: grow_names to %u starting", n);
+
+ /*
+ * Are we shutting down?
+ */
+ for (i = 0; i < adb->nnames; i++)
+ if (adb->name_sd[i])
+ goto cleanup;
+
+ /*
+ * Grab all the resources we need.
+ */
+ newnames = isc_mem_get(adb->mctx, sizeof(*newnames) * n);
+ newdeadnames = isc_mem_get(adb->mctx, sizeof(*newdeadnames) * n);
+ newnamelocks = isc_mem_get(adb->mctx, sizeof(*newnamelocks) * n);
+ newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n);
+ newname_refcnt = isc_mem_get(adb->mctx, sizeof(*newname_refcnt) * n);
+ if (newnames == NULL || newdeadnames == NULL ||
+ newnamelocks == NULL || newname_sd == NULL ||
+ newname_refcnt == NULL)
+ goto cleanup;
+
+ /*
+ * Initialise the new resources.
+ */
+ result = isc_mutexblock_init(newnamelocks, n);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ for (i = 0; i < n; i++) {
+ ISC_LIST_INIT(newnames[i]);
+ ISC_LIST_INIT(newdeadnames[i]);
+ newname_sd[i] = ISC_FALSE;
+ newname_refcnt[i] = 0;
+ adb->irefcnt++;
+ }
+
+ /*
+ * Move names to new arrays.
+ */
+ for (i = 0; i < adb->nnames; i++) {
+ name = ISC_LIST_HEAD(adb->names[i]);
+ while (name != NULL) {
+ ISC_LIST_UNLINK(adb->names[i], name, plink);
+ bucket = dns_name_fullhash(&name->name, ISC_TRUE) % n;
+ name->lock_bucket = bucket;
+ ISC_LIST_APPEND(newnames[bucket], name, plink);
+ INSIST(adb->name_refcnt[i] > 0);
+ adb->name_refcnt[i]--;
+ newname_refcnt[bucket]++;
+ name = ISC_LIST_HEAD(adb->names[i]);
+ }
+ name = ISC_LIST_HEAD(adb->deadnames[i]);
+ while (name != NULL) {
+ ISC_LIST_UNLINK(adb->deadnames[i], name, plink);
+ bucket = dns_name_fullhash(&name->name, ISC_TRUE) % n;
+ name->lock_bucket = bucket;
+ ISC_LIST_APPEND(newdeadnames[bucket], name, plink);
+ INSIST(adb->name_refcnt[i] > 0);
+ adb->name_refcnt[i]--;
+ newname_refcnt[bucket]++;
+ name = ISC_LIST_HEAD(adb->deadnames[i]);
+ }
+ INSIST(adb->name_refcnt[i] == 0);
+ adb->irefcnt--;
+ }
+
+ /*
+ * Cleanup old resources.
+ */
+ DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames);
+ isc_mem_put(adb->mctx, adb->names,
+ sizeof(*adb->names) * adb->nnames);
+ isc_mem_put(adb->mctx, adb->deadnames,
+ sizeof(*adb->deadnames) * adb->nnames);
+ isc_mem_put(adb->mctx, adb->namelocks,
+ sizeof(*adb->namelocks) * adb->nnames);
+ isc_mem_put(adb->mctx, adb->name_sd,
+ sizeof(*adb->name_sd) * adb->nnames);
+ isc_mem_put(adb->mctx, adb->name_refcnt,
+ sizeof(*adb->name_refcnt) * adb->nnames);
+
+ /*
+ * Install new resources.
+ */
+ adb->names = newnames;
+ adb->deadnames = newdeadnames;
+ adb->namelocks = newnamelocks;
+ adb->name_sd = newname_sd;
+ adb->name_refcnt = newname_refcnt;
+ adb->nnames = n;
+
+ /*
+ * Only on success do we set adb->grownames_sent to ISC_FALSE.
+ * This will prevent us being continuously being called on error.
+ */
+ adb->grownames_sent = ISC_FALSE;
+ goto done;
+
+ cleanup:
+ if (newnames != NULL)
+ isc_mem_put(adb->mctx, newnames, sizeof(*newnames) * n);
+ if (newdeadnames != NULL)
+ isc_mem_put(adb->mctx, newdeadnames, sizeof(*newdeadnames) * n);
+ if (newnamelocks != NULL)
+ isc_mem_put(adb->mctx, newnamelocks, sizeof(*newnamelocks) * n);
+ if (newname_sd != NULL)
+ isc_mem_put(adb->mctx, newname_sd, sizeof(*newname_sd) * n);
+ if (newname_refcnt != NULL)
+ isc_mem_put(adb->mctx, newname_refcnt,
+ sizeof(*newname_refcnt) * n);
+ done:
+ isc_task_endexclusive(task);
+
+ LOCK(&adb->lock);
+ if (dec_adb_irefcnt(adb))
+ check_exit(adb);
+ UNLOCK(&adb->lock);
+ DP(ISC_LOG_INFO, "adb: grow_names finished");
+}
+
+/*
* Requires the adbname bucket be locked and that no entry buckets be locked.
*
* This code handles A and AAAA rdatasets only.
@@ -836,12 +1152,12 @@ violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {
*/
static isc_boolean_t
shutdown_names(dns_adb_t *adb) {
- int bucket;
+ unsigned int bucket;
isc_boolean_t result = ISC_FALSE;
dns_adbname_t *name;
dns_adbname_t *next_name;
- for (bucket = 0; bucket < NBUCKETS; bucket++) {
+ for (bucket = 0; bucket < adb->nnames; bucket++) {
LOCK(&adb->namelocks[bucket]);
adb->name_sd[bucket] = ISC_TRUE;
@@ -881,12 +1197,12 @@ shutdown_names(dns_adb_t *adb) {
*/
static isc_boolean_t
shutdown_entries(dns_adb_t *adb) {
- int bucket;
+ unsigned int bucket;
isc_boolean_t result = ISC_FALSE;
dns_adbentry_t *entry;
dns_adbentry_t *next_entry;
- for (bucket = 0; bucket < NBUCKETS; bucket++) {
+ for (bucket = 0; bucket < adb->nentries; bucket++) {
LOCK(&adb->entrylocks[bucket]);
adb->entry_sd[bucket] = ISC_TRUE;
@@ -1306,6 +1622,16 @@ new_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
ISC_LIST_INIT(name->finds);
ISC_LINK_INIT(name, plink);
+ LOCK(&adb->namescntlock);
+ adb->namescnt++;
+ if (!adb->grownames_sent && adb->namescnt > (adb->nnames * 8)) {
+ isc_event_t *event = &adb->grownames;
+ inc_adb_irefcnt(adb);
+ isc_task_send(adb->task, &event);
+ adb->grownames_sent = ISC_TRUE;
+ }
+ UNLOCK(&adb->namescntlock);
+
return (name);
}
@@ -1329,6 +1655,9 @@ free_adbname(dns_adb_t *adb, dns_adbname_t **name) {
dns_name_free(&n->name, adb->mctx);
isc_mempool_put(adb->nmp, n);
+ LOCK(&adb->namescntlock);
+ adb->namescnt--;
+ UNLOCK(&adb->namescntlock);
}
static inline dns_adbnamehook_t *
@@ -1417,6 +1746,16 @@ new_adbentry(dns_adb_t *adb) {
e->expires = 0;
ISC_LIST_INIT(e->lameinfo);
ISC_LINK_INIT(e, plink);
+ LOCK(&adb->entriescntlock);
+ adb->entriescnt++;
+ if (!adb->growentries_sent &&
+ adb->entriescnt > (adb->nentries * 8)) {
+ isc_event_t *event = &adb->growentries;
+ inc_adb_irefcnt(adb);
+ isc_task_send(adb->task, &event);
+ adb->growentries_sent = ISC_TRUE;
+ }
+ UNLOCK(&adb->entriescntlock);
return (e);
}
@@ -1444,6 +1783,9 @@ free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
}
isc_mempool_put(adb->emp, e);
+ LOCK(&adb->entriescntlock);
+ adb->entriescnt--;
+ UNLOCK(&adb->entriescntlock);
}
static inline dns_adbfind_t *
@@ -1597,7 +1939,7 @@ find_name_and_lock(dns_adb_t *adb, dns_name_t *name,
dns_adbname_t *adbname;
int bucket;
- bucket = dns_name_fullhash(name, ISC_FALSE) % NBUCKETS;
+ bucket = dns_name_fullhash(name, ISC_FALSE) % adb->nnames;
if (*bucketp == DNS_ADB_INVALIDBUCKET) {
LOCK(&adb->namelocks[bucket]);
@@ -1639,7 +1981,7 @@ find_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp,
dns_adbentry_t *entry, *entry_next;
int bucket;
- bucket = isc_sockaddr_hash(addr, ISC_TRUE) % NBUCKETS;
+ bucket = isc_sockaddr_hash(addr, ISC_TRUE) % adb->nentries;
if (*bucketp == DNS_ADB_INVALIDBUCKET) {
LOCK(&adb->entrylocks[bucket]);
@@ -1992,13 +2334,36 @@ destroy(dns_adb_t *adb) {
isc_mempool_destroy(&adb->aimp);
isc_mempool_destroy(&adb->afmp);
- DESTROYMUTEXBLOCK(adb->entrylocks, NBUCKETS);
- DESTROYMUTEXBLOCK(adb->namelocks, NBUCKETS);
+ DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
+ isc_mem_put(adb->mctx, adb->entries,
+ sizeof(*adb->entries) * adb->nentries);
+ isc_mem_put(adb->mctx, adb->deadentries,
+ sizeof(*adb->deadentries) * adb->nentries);
+ isc_mem_put(adb->mctx, adb->entrylocks,
+ sizeof(*adb->entrylocks) * adb->nentries);
+ isc_mem_put(adb->mctx, adb->entry_sd,
+ sizeof(*adb->entry_sd) * adb->nentries);
+ isc_mem_put(adb->mctx, adb->entry_refcnt,
+ sizeof(*adb->entry_refcnt) * adb->nentries);
+
+ DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames);
+ isc_mem_put(adb->mctx, adb->names,
+ sizeof(*adb->names) * adb->nnames);
+ isc_mem_put(adb->mctx, adb->deadnames,
+ sizeof(*adb->deadnames) * adb->nnames);
+ isc_mem_put(adb->mctx, adb->namelocks,
+ sizeof(*adb->namelocks) * adb->nnames);
+ isc_mem_put(adb->mctx, adb->name_sd,
+ sizeof(*adb->name_sd) * adb->nnames);
+ isc_mem_put(adb->mctx, adb->name_refcnt,
+ sizeof(*adb->name_refcnt) * adb->nnames);
DESTROYLOCK(&adb->reflock);
DESTROYLOCK(&adb->lock);
DESTROYLOCK(&adb->mplock);
DESTROYLOCK(&adb->overmemlock);
+ DESTROYLOCK(&adb->entriescntlock);
+ DESTROYLOCK(&adb->namescntlock);
isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
}
@@ -2014,7 +2379,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
{
dns_adb_t *adb;
isc_result_t result;
- int i;
+ unsigned int i;
REQUIRE(mem != NULL);
REQUIRE(view != NULL);
@@ -2054,6 +2419,30 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
adb->shutting_down = ISC_FALSE;
ISC_LIST_INIT(adb->whenshutdown);
+ adb->nentries = nbuckets[0];
+ adb->entriescnt = 0;
+ adb->entries = NULL;
+ adb->deadentries = NULL;
+ adb->entry_sd = NULL;
+ adb->entry_refcnt = NULL;
+ adb->entrylocks = NULL;
+ ISC_EVENT_INIT(&adb->growentries, sizeof(adb->growentries), 0, NULL,
+ DNS_EVENT_ADBGROWENTRIES, grow_entries, adb,
+ adb, NULL, NULL);
+ adb->growentries_sent = ISC_FALSE;
+
+ adb->nnames = nbuckets[0];
+ adb->namescnt = 0;
+ adb->names = NULL;
+ adb->deadnames = NULL;
+ adb->name_sd = NULL;
+ adb->name_refcnt = NULL;
+ adb->namelocks = NULL;
+ ISC_EVENT_INIT(&adb->grownames, sizeof(adb->grownames), 0, NULL,
+ DNS_EVENT_ADBGROWNAMES, grow_names, adb,
+ adb, NULL, NULL);
+ adb->grownames_sent = ISC_FALSE;
+
isc_mem_attach(mem, &adb->mctx);
result = isc_mutex_init(&adb->lock);
@@ -2072,28 +2461,68 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
if (result != ISC_R_SUCCESS)
goto fail0e;
+ result = isc_mutex_init(&adb->entriescntlock);
+ if (result != ISC_R_SUCCESS)
+ goto fail0f;
+
+ result = isc_mutex_init(&adb->namescntlock);
+ if (result != ISC_R_SUCCESS)
+ goto fail0g;
+
+#define ALLOCENTRY(adb, el) \
+ do { \
+ (adb)->el = isc_mem_get((adb)->mctx, \
+ sizeof(*(adb)->el) * (adb)->nentries); \
+ if ((adb)->el == NULL) { \
+ result = ISC_R_NOMEMORY; \
+ goto fail1; \
+ }\
+ } while (0)
+ ALLOCENTRY(adb, entries);
+ ALLOCENTRY(adb, deadentries);
+ ALLOCENTRY(adb, entrylocks);
+ ALLOCENTRY(adb, entry_sd);
+ ALLOCENTRY(adb, entry_refcnt);
+#undef ALLOCENTRY
+
+#define ALLOCNAME(adb, el) \
+ do { \
+ (adb)->el = isc_mem_get((adb)->mctx, \
+ sizeof(*(adb)->el) * (adb)->nnames); \
+ if ((adb)->el == NULL) { \
+ result = ISC_R_NOMEMORY; \
+ goto fail1; \
+ }\
+ } while (0)
+ ALLOCNAME(adb, names);
+ ALLOCNAME(adb, deadnames);
+ ALLOCNAME(adb, namelocks);
+ ALLOCNAME(adb, name_sd);
+ ALLOCNAME(adb, name_refcnt);
+#undef ALLOCNAME
+
/*
* Initialize the bucket locks for names and elements.
* May as well initialize the list heads, too.
*/
- result = isc_mutexblock_init(adb->namelocks, NBUCKETS);
+ result = isc_mutexblock_init(adb->namelocks, adb->nnames);
if (result != ISC_R_SUCCESS)
goto fail1;
- for (i = 0; i < NBUCKETS; i++) {
+ for (i = 0; i < adb->nnames; i++) {
ISC_LIST_INIT(adb->names[i]);
ISC_LIST_INIT(adb->deadnames[i]);
adb->name_sd[i] = ISC_FALSE;
adb->name_refcnt[i] = 0;
adb->irefcnt++;
}
- for (i = 0; i < NBUCKETS; i++) {
+ for (i = 0; i < adb->nentries; i++) {
ISC_LIST_INIT(adb->entries[i]);
ISC_LIST_INIT(adb->deadentries[i]);
adb->entry_sd[i] = ISC_FALSE;
adb->entry_refcnt[i] = 0;
adb->irefcnt++;
}
- result = isc_mutexblock_init(adb->entrylocks, NBUCKETS);
+ result = isc_mutexblock_init(adb->entrylocks, adb->nentries);
if (result != ISC_R_SUCCESS)
goto fail2;
@@ -2140,12 +2569,42 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
isc_task_detach(&adb->task);
/* clean up entrylocks */
- DESTROYMUTEXBLOCK(adb->entrylocks, NBUCKETS);
+ DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
fail2: /* clean up namelocks */
- DESTROYMUTEXBLOCK(adb->namelocks, NBUCKETS);
+ DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames);
fail1: /* clean up only allocated memory */
+ if (adb->entries != NULL)
+ isc_mem_put(adb->mctx, adb->entries,
+ sizeof(*adb->entries) * adb->nentries);
+ if (adb->deadentries != NULL)
+ isc_mem_put(adb->mctx, adb->deadentries,
+ sizeof(*adb->deadentries) * adb->nentries);
+ if (adb->entrylocks != NULL)
+ isc_mem_put(adb->mctx, adb->entrylocks,
+ sizeof(*adb->entrylocks) * adb->nentries);
+ if (adb->entry_sd != NULL)
+ isc_mem_put(adb->mctx, adb->entry_sd,
+ sizeof(*adb->entry_sd) * adb->nentries);
+ if (adb->entry_refcnt != NULL)
+ isc_mem_put(adb->mctx, adb->entry_refcnt,
+ sizeof(*adb->entry_refcnt) * adb->nentries);
+ if (adb->names != NULL)
+ isc_mem_put(adb->mctx, adb->names,
+ sizeof(*adb->names) * adb->nnames);
+ if (adb->deadnames != NULL)
+ isc_mem_put(adb->mctx, adb->deadnames,
+ sizeof(*adb->deadnames) * adb->nnames);
+ if (adb->namelocks != NULL)
+ isc_mem_put(adb->mctx, adb->namelocks,
+ sizeof(*adb->namelocks) * adb->nnames);
+ if (adb->name_sd != NULL)
+ isc_mem_put(adb->mctx, adb->name_sd,
+ sizeof(*adb->name_sd) * adb->nnames);
+ if (adb->name_refcnt != NULL)
+ isc_mem_put(adb->mctx, adb->name_refcnt,
+ sizeof(*adb->name_refcnt) * adb->nnames);
if (adb->nmp != NULL)
isc_mempool_destroy(&adb->nmp);
if (adb->nhmp != NULL)
@@ -2161,6 +2620,10 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
if (adb->afmp != NULL)
isc_mempool_destroy(&adb->afmp);
+ DESTROYLOCK(&adb->namescntlock);
+ fail0g:
+ DESTROYLOCK(&adb->entriescntlock);
+ fail0f:
DESTROYLOCK(&adb->overmemlock);
fail0e:
DESTROYLOCK(&adb->reflock);
@@ -2728,7 +3191,7 @@ dns_adb_cancelfind(dns_adbfind_t *find) {
void
dns_adb_dump(dns_adb_t *adb, FILE *f) {
- int i;
+ unsigned int i;
isc_stdtime_t now;
REQUIRE(DNS_ADB_VALID(adb));
@@ -2744,9 +3207,9 @@ dns_adb_dump(dns_adb_t *adb, FILE *f) {
LOCK(&adb->lock);
isc_stdtime_get(&now);
- for (i = 0; i < NBUCKETS; i++)
+ for (i = 0; i < adb->nnames; i++)
RUNTIME_CHECK(cleanup_names(adb, i, now) == ISC_FALSE);
- for (i = 0; i < NBUCKETS; i++)
+ for (i = 0; i < adb->nentries; i++)
RUNTIME_CHECK(cleanup_entries(adb, i, now) == ISC_FALSE);
dump_adb(adb, f, ISC_FALSE, now);
@@ -2762,7 +3225,7 @@ dump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) {
static void
dump_adb(dns_adb_t *adb, FILE *f, isc_boolean_t debug, isc_stdtime_t now) {
- int i;
+ unsigned int i;
dns_adbname_t *name;
dns_adbentry_t *entry;
@@ -2772,15 +3235,15 @@ dump_adb(dns_adb_t *adb, FILE *f, isc_boolean_t debug, isc_stdtime_t now) {
adb, adb->erefcnt, adb->irefcnt,
isc_mempool_getallocated(adb->nhmp));
- for (i = 0; i < NBUCKETS; i++)
+ for (i = 0; i < adb->nnames; i++)
LOCK(&adb->namelocks[i]);
- for (i = 0; i < NBUCKETS; i++)
+ for (i = 0; i < adb->nentries; i++)
LOCK(&adb->entrylocks[i]);
/*
* Dump the names
*/
- for (i = 0; i < NBUCKETS; i++) {
+ for (i = 0; i < adb->nnames; i++) {
name = ISC_LIST_HEAD(adb->names[i]);
if (name == NULL)
continue;
@@ -2824,7 +3287,7 @@ dump_adb(dns_adb_t *adb, FILE *f, isc_boolean_t debug, isc_stdtime_t now) {
fprintf(f, ";\n; Unassociated entries\n;\n");
- for (i = 0; i < NBUCKETS; i++) {
+ for (i = 0; i < adb->nentries; i++) {
entry = ISC_LIST_HEAD(adb->entries[i]);
while (entry != NULL) {
if (entry->refcnt == 0)
@@ -2836,9 +3299,9 @@ dump_adb(dns_adb_t *adb, FILE *f, isc_boolean_t debug, isc_stdtime_t now) {
/*
* Unlock everything
*/
- for (i = 0; i < NBUCKETS; i++)
+ for (i = 0; i < adb->nentries; i++)
UNLOCK(&adb->entrylocks[i]);
- for (i = 0; i < NBUCKETS; i++)
+ for (i = 0; i < adb->nnames; i++)
UNLOCK(&adb->namelocks[i]);
}
@@ -2999,10 +3462,20 @@ dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype)
else
adbname->fetch6_err = FIND_ERR_UNEXPECTED;
- result = dns_view_find(adb->view, &adbname->name, rdtype, now,
- NAME_GLUEOK(adbname) ? DNS_DBFIND_GLUEOK : 0,
- ISC_TF(NAME_HINTOK(adbname)),
- NULL, NULL, fname, &rdataset, NULL);
+ /*
+ * We need to specify whether to search static-stub zones (if
+ * configured) depending on whether this is a "start at zone" lookup,
+ * i.e., whether it's a "bailiwick" glue. If it's bailiwick (in which
+ * case NAME_STARTATZONE is set) we need to stop the search at any
+ * matching static-stub zone without looking into the cache to honor
+ * the configuration on which server we should send queries to.
+ */
+ result = dns_view_find2(adb->view, &adbname->name, rdtype, now,
+ NAME_GLUEOK(adbname) ? DNS_DBFIND_GLUEOK : 0,
+ ISC_TF(NAME_HINTOK(adbname)),
+ (adbname->flags & NAME_STARTATZONE) != 0 ?
+ ISC_TRUE : ISC_FALSE,
+ NULL, NULL, fname, &rdataset, NULL);
/* XXXVIX this switch statement is too sparse to gen a jump table. */
switch (result) {
@@ -3557,9 +4030,9 @@ dns_adb_flush(dns_adb_t *adb) {
/*
* Call our cleanup routines.
*/
- for (i = 0; i < NBUCKETS; i++)
+ for (i = 0; i < adb->nnames; i++)
RUNTIME_CHECK(cleanup_names(adb, i, INT_MAX) == ISC_FALSE);
- for (i = 0; i < NBUCKETS; i++)
+ for (i = 0; i < adb->nentries; i++)
RUNTIME_CHECK(cleanup_entries(adb, i, INT_MAX) == ISC_FALSE);
#ifdef DUMP_ADB_AFTER_CLEANING
@@ -3578,7 +4051,7 @@ dns_adb_flushname(dns_adb_t *adb, dns_name_t *name) {
INSIST(DNS_ADB_VALID(adb));
LOCK(&adb->lock);
- bucket = dns_name_hash(name, ISC_FALSE) % NBUCKETS;
+ bucket = dns_name_hash(name, ISC_FALSE) % adb->nnames;
LOCK(&adb->namelocks[bucket]);
adbname = ISC_LIST_HEAD(adb->names[bucket]);
while (adbname != NULL) {
diff --git a/lib/dns/api b/lib/dns/api
index 87c3c90a708d..9bac0602bdc1 100644
--- a/lib/dns/api
+++ b/lib/dns/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 59
-LIBREVISION = 5
+LIBINTERFACE = 82
+LIBREVISION = 3
LIBAGE = 1
diff --git a/lib/dns/byaddr.c b/lib/dns/byaddr.c
index 96b9f3843cb1..2fd61a2abca5 100644
--- a/lib/dns/byaddr.c
+++ b/lib/dns/byaddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: byaddr.c,v 1.39 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: byaddr.c,v 1.41 2009-09-02 23:48:02 tbox Exp $ */
/*! \file */
@@ -43,25 +43,6 @@
* XXXRTH We could use a static event...
*/
-struct dns_byaddr {
- /* Unlocked. */
- unsigned int magic;
- isc_mem_t * mctx;
- isc_mutex_t lock;
- dns_fixedname_t name;
- /* Locked by lock. */
- unsigned int options;
- dns_lookup_t * lookup;
- isc_task_t * task;
- dns_byaddrevent_t * event;
- isc_boolean_t canceled;
-};
-
-#define BYADDR_MAGIC ISC_MAGIC('B', 'y', 'A', 'd')
-#define VALID_BYADDR(b) ISC_MAGIC_VALID(b, BYADDR_MAGIC)
-
-#define MAX_RESTARTS 16
-
static char hex_digits[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
@@ -125,10 +106,29 @@ dns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options,
len = (unsigned int)strlen(textname);
isc_buffer_init(&buffer, textname, len);
isc_buffer_add(&buffer, len);
- return (dns_name_fromtext(name, &buffer, dns_rootname,
- ISC_FALSE, NULL));
+ return (dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL));
}
+#ifdef BIND9
+struct dns_byaddr {
+ /* Unlocked. */
+ unsigned int magic;
+ isc_mem_t * mctx;
+ isc_mutex_t lock;
+ dns_fixedname_t name;
+ /* Locked by lock. */
+ unsigned int options;
+ dns_lookup_t * lookup;
+ isc_task_t * task;
+ dns_byaddrevent_t * event;
+ isc_boolean_t canceled;
+};
+
+#define BYADDR_MAGIC ISC_MAGIC('B', 'y', 'A', 'd')
+#define VALID_BYADDR(b) ISC_MAGIC_VALID(b, BYADDR_MAGIC)
+
+#define MAX_RESTARTS 16
+
static inline isc_result_t
copy_ptr_targets(dns_byaddr_t *byaddr, dns_rdataset_t *rdataset) {
isc_result_t result;
@@ -314,3 +314,4 @@ dns_byaddr_destroy(dns_byaddr_t **byaddrp) {
*byaddrp = NULL;
}
+#endif /* BIND9 */
diff --git a/lib/dns/cache.c b/lib/dns/cache.c
index 28ead664f9e7..bf93da2d0985 100644
--- a/lib/dns/cache.c
+++ b/lib/dns/cache.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: cache.c,v 1.80.50.3 2009-05-06 23:34:30 jinmei Exp $ */
+/* $Id: cache.c,v 1.87 2009-11-12 23:43:02 each Exp $ */
/*! \file */
@@ -122,6 +122,7 @@ struct dns_cache {
isc_mutex_t lock;
isc_mutex_t filelock;
isc_mem_t *mctx;
+ char *name;
/* Locked by 'lock'. */
int references;
@@ -132,6 +133,7 @@ struct dns_cache {
char *db_type;
int db_argc;
char **db_argv;
+ isc_uint32_t size;
/* Locked by 'filelock'. */
char *filename;
@@ -171,6 +173,16 @@ dns_cache_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
const char *db_type, unsigned int db_argc, char **db_argv,
dns_cache_t **cachep)
{
+ return (dns_cache_create2(mctx, taskmgr, timermgr, rdclass, "",
+ db_type, db_argc, db_argv, cachep));
+}
+
+isc_result_t
+dns_cache_create2(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
+ isc_timermgr_t *timermgr, dns_rdataclass_t rdclass,
+ const char *cachename, const char *db_type,
+ unsigned int db_argc, char **db_argv, dns_cache_t **cachep)
+{
isc_result_t result;
dns_cache_t *cache;
int i;
@@ -179,6 +191,7 @@ dns_cache_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
REQUIRE(cachep != NULL);
REQUIRE(*cachep == NULL);
REQUIRE(mctx != NULL);
+ REQUIRE(cachename != NULL);
cache = isc_mem_get(mctx, sizeof(*cache));
if (cache == NULL)
@@ -187,6 +200,15 @@ dns_cache_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
cache->mctx = NULL;
isc_mem_attach(mctx, &cache->mctx);
+ cache->name = NULL;
+ if (cachename != NULL) {
+ cache->name = isc_mem_strdup(mctx, cachename);
+ if (cache->name == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup_mem;
+ }
+ }
+
result = isc_mutex_init(&cache->lock);
if (result != ISC_R_SUCCESS)
goto cleanup_mem;
@@ -275,6 +297,8 @@ dns_cache_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
cleanup_lock:
DESTROYLOCK(&cache->lock);
cleanup_mem:
+ if (cache->name != NULL)
+ isc_mem_free(mctx, cache->name);
isc_mem_put(mctx, cache, sizeof(*cache));
isc_mem_detach(&mctx);
return (result);
@@ -323,6 +347,9 @@ cache_free(dns_cache_t *cache) {
if (cache->db_type != NULL)
isc_mem_free(cache->mctx, cache->db_type);
+ if (cache->name != NULL)
+ isc_mem_free(cache->mctx, cache->name);
+
DESTROYLOCK(&cache->lock);
DESTROYLOCK(&cache->filelock);
cache->magic = 0;
@@ -423,6 +450,7 @@ dns_cache_setfilename(dns_cache_t *cache, const char *filename) {
return (ISC_R_SUCCESS);
}
+#ifdef BIND9
isc_result_t
dns_cache_load(dns_cache_t *cache) {
isc_result_t result;
@@ -438,22 +466,29 @@ dns_cache_load(dns_cache_t *cache) {
return (result);
}
+#endif /* BIND9 */
isc_result_t
dns_cache_dump(dns_cache_t *cache) {
+#ifdef BIND9
isc_result_t result;
+#endif
REQUIRE(VALID_CACHE(cache));
if (cache->filename == NULL)
return (ISC_R_SUCCESS);
+#ifdef BIND9
LOCK(&cache->filelock);
result = dns_master_dump(cache->mctx, cache->db, NULL,
&dns_master_style_cache, cache->filename);
UNLOCK(&cache->filelock);
-
return (result);
+#else
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
+
}
void
@@ -493,6 +528,26 @@ dns_cache_setcleaninginterval(dns_cache_t *cache, unsigned int t) {
UNLOCK(&cache->lock);
}
+unsigned int
+dns_cache_getcleaninginterval(dns_cache_t *cache) {
+ unsigned int t;
+
+ REQUIRE(VALID_CACHE(cache));
+
+ LOCK(&cache->lock);
+ t = cache->cleaner.cleaning_interval;
+ UNLOCK(&cache->lock);
+
+ return (t);
+}
+
+const char *
+dns_cache_getname(dns_cache_t *cache) {
+ REQUIRE(VALID_CACHE(cache));
+
+ return (cache->name);
+}
+
/*
* Initialize the cache cleaner object at *cleaner.
* Space for the object must be allocated by the caller.
@@ -519,6 +574,7 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
cleaner->cleaning_timer = NULL;
cleaner->resched_event = NULL;
cleaner->overmem_event = NULL;
+ cleaner->cleaning_interval = 0; /* Initially turned off. */
result = dns_db_createiterator(cleaner->cache->db, ISC_FALSE,
&cleaner->iterator);
@@ -547,7 +603,6 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
goto cleanup;
}
- cleaner->cleaning_interval = 0; /* Initially turned off. */
result = isc_timer_create(timermgr, isc_timertype_inactive,
NULL, NULL, cleaner->task,
cleaning_timer_action, cleaner,
@@ -949,6 +1004,10 @@ dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) {
if (size != 0 && size < DNS_CACHE_MINSIZE)
size = DNS_CACHE_MINSIZE;
+ LOCK(&cache->lock);
+ cache->size = size;
+ UNLOCK(&cache->lock);
+
hiwater = size - (size >> 3); /* Approximately 7/8ths. */
lowater = size - (size >> 2); /* Approximately 3/4ths. */
@@ -972,6 +1031,19 @@ dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) {
isc_mem_setwater(cache->mctx, water, cache, hiwater, lowater);
}
+isc_uint32_t
+dns_cache_getcachesize(dns_cache_t *cache) {
+ isc_uint32_t size;
+
+ REQUIRE(VALID_CACHE(cache));
+
+ LOCK(&cache->lock);
+ size = cache->size;
+ UNLOCK(&cache->lock);
+
+ return (size);
+}
+
/*
* The cleaner task is shutting down; do the necessary cleanup.
*/
diff --git a/lib/dns/client.c b/lib/dns/client.c
new file mode 100644
index 000000000000..e55ea1f2bc4b
--- /dev/null
+++ b/lib/dns/client.c
@@ -0,0 +1,3019 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.12 2010-12-03 12:03:22 marka Exp $ */
+
+#include <config.h>
+
+#include <stddef.h>
+
+#include <isc/app.h>
+#include <isc/mem.h>
+#include <isc/mutex.h>
+#include <isc/sockaddr.h>
+#include <isc/socket.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include <dns/adb.h>
+#include <dns/client.h>
+#include <dns/db.h>
+#include <dns/dispatch.h>
+#include <dns/events.h>
+#include <dns/forward.h>
+#include <dns/keytable.h>
+#include <dns/message.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdatalist.h>
+#include <dns/rdataset.h>
+#include <dns/rdatatype.h>
+#include <dns/rdatasetiter.h>
+#include <dns/rdatastruct.h>
+#include <dns/request.h>
+#include <dns/resolver.h>
+#include <dns/result.h>
+#include <dns/tsec.h>
+#include <dns/tsig.h>
+#include <dns/view.h>
+
+#include <dst/dst.h>
+
+#define DNS_CLIENT_MAGIC ISC_MAGIC('D', 'N', 'S', 'c')
+#define DNS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, DNS_CLIENT_MAGIC)
+
+#define RCTX_MAGIC ISC_MAGIC('R', 'c', 't', 'x')
+#define RCTX_VALID(c) ISC_MAGIC_VALID(c, RCTX_MAGIC)
+
+#define REQCTX_MAGIC ISC_MAGIC('R', 'q', 'c', 'x')
+#define REQCTX_VALID(c) ISC_MAGIC_VALID(c, REQCTX_MAGIC)
+
+#define UCTX_MAGIC ISC_MAGIC('U', 'c', 't', 'x')
+#define UCTX_VALID(c) ISC_MAGIC_VALID(c, UCTX_MAGIC)
+
+#define MAX_RESTARTS 16
+
+/*%
+ * DNS client object
+ */
+struct dns_client {
+ /* Unlocked */
+ unsigned int magic;
+ unsigned int attributes;
+ isc_mutex_t lock;
+ isc_mem_t *mctx;
+ isc_appctx_t *actx;
+ isc_taskmgr_t *taskmgr;
+ isc_task_t *task;
+ isc_socketmgr_t *socketmgr;
+ isc_timermgr_t *timermgr;
+ dns_dispatchmgr_t *dispatchmgr;
+ dns_dispatch_t *dispatchv4;
+ dns_dispatch_t *dispatchv6;
+
+ unsigned int update_timeout;
+ unsigned int update_udptimeout;
+ unsigned int update_udpretries;
+ unsigned int find_timeout;
+ unsigned int find_udpretries;
+
+ /* Locked */
+ unsigned int references;
+ dns_viewlist_t viewlist;
+ ISC_LIST(struct resctx) resctxs;
+ ISC_LIST(struct reqctx) reqctxs;
+ ISC_LIST(struct updatectx) updatectxs;
+};
+
+/*%
+ * Timeout/retry constants for dynamic update borrowed from nsupdate
+ */
+#define DEF_UPDATE_TIMEOUT 300
+#define MIN_UPDATE_TIMEOUT 30
+#define DEF_UPDATE_UDPTIMEOUT 3
+#define DEF_UPDATE_UDPRETRIES 3
+
+#define DEF_FIND_TIMEOUT 5
+#define DEF_FIND_UDPRETRIES 3
+
+#define DNS_CLIENTATTR_OWNCTX 0x01
+
+#define DNS_CLIENTVIEW_NAME "dnsclient"
+
+/*%
+ * Internal state for a single name resolution procedure
+ */
+typedef struct resctx {
+ /* Unlocked */
+ unsigned int magic;
+ isc_mutex_t lock;
+ dns_client_t *client;
+ isc_boolean_t want_dnssec;
+
+ /* Locked */
+ ISC_LINK(struct resctx) link;
+ isc_task_t *task;
+ dns_view_t *view;
+ unsigned int restarts;
+ dns_fixedname_t name;
+ dns_rdatatype_t type;
+ dns_fetch_t *fetch;
+ dns_namelist_t namelist;
+ isc_result_t result;
+ dns_clientresevent_t *event;
+ isc_boolean_t canceled;
+ dns_rdataset_t *rdataset;
+ dns_rdataset_t *sigrdataset;
+} resctx_t;
+
+/*%
+ * Argument of an internal event for synchronous name resolution.
+ */
+typedef struct resarg {
+ /* Unlocked */
+ isc_appctx_t *actx;
+ dns_client_t *client;
+ isc_mutex_t lock;
+
+ /* Locked */
+ isc_result_t result;
+ isc_result_t vresult;
+ dns_namelist_t *namelist;
+ dns_clientrestrans_t *trans;
+ isc_boolean_t canceled;
+} resarg_t;
+
+/*%
+ * Internal state for a single DNS request
+ */
+typedef struct reqctx {
+ /* Unlocked */
+ unsigned int magic;
+ isc_mutex_t lock;
+ dns_client_t *client;
+ unsigned int parseoptions;
+
+ /* Locked */
+ ISC_LINK(struct reqctx) link;
+ isc_boolean_t canceled;
+ dns_tsigkey_t *tsigkey;
+ dns_request_t *request;
+ dns_clientreqevent_t *event;
+} reqctx_t;
+
+/*%
+ * Argument of an internal event for synchronous DNS request.
+ */
+typedef struct reqarg {
+ /* Unlocked */
+ isc_appctx_t *actx;
+ dns_client_t *client;
+ isc_mutex_t lock;
+
+ /* Locked */
+ isc_result_t result;
+ dns_clientreqtrans_t *trans;
+ isc_boolean_t canceled;
+} reqarg_t;
+
+/*%
+ * Argument of an internal event for synchronous name resolution.
+ */
+typedef struct updatearg {
+ /* Unlocked */
+ isc_appctx_t *actx;
+ dns_client_t *client;
+ isc_mutex_t lock;
+
+ /* Locked */
+ isc_result_t result;
+ dns_clientupdatetrans_t *trans;
+ isc_boolean_t canceled;
+} updatearg_t;
+
+/*%
+ * Internal state for a single dynamic update procedure
+ */
+typedef struct updatectx {
+ /* Unlocked */
+ unsigned int magic;
+ isc_mutex_t lock;
+ dns_client_t *client;
+
+ /* Locked */
+ dns_request_t *updatereq;
+ dns_request_t *soareq;
+ dns_clientrestrans_t *restrans;
+ dns_clientrestrans_t *restrans2;
+ isc_boolean_t canceled;
+
+ /* Task Locked */
+ ISC_LINK(struct updatectx) link;
+ dns_clientupdatestate_t state;
+ dns_rdataclass_t rdclass;
+ dns_view_t *view;
+ dns_message_t *updatemsg;
+ dns_message_t *soaquery;
+ dns_clientupdateevent_t *event;
+ dns_tsigkey_t *tsigkey;
+ dst_key_t *sig0key;
+ dns_name_t *firstname;
+ dns_name_t soaqname;
+ dns_fixedname_t zonefname;
+ dns_name_t *zonename;
+ isc_sockaddrlist_t servers;
+ unsigned int nservers;
+ isc_sockaddr_t *currentserver;
+ struct updatectx *bp4;
+ struct updatectx *bp6;
+} updatectx_t;
+
+static isc_result_t request_soa(updatectx_t *uctx);
+static void client_resfind(resctx_t *rctx, dns_fetchevent_t *event);
+static isc_result_t send_update(updatectx_t *uctx);
+
+static isc_result_t
+getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
+ isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr,
+ isc_boolean_t is_shared, dns_dispatch_t **dispp)
+{
+ unsigned int attrs, attrmask;
+ isc_sockaddr_t sa;
+ dns_dispatch_t *disp;
+ unsigned buffersize, maxbuffers, maxrequests, buckets, increment;
+ isc_result_t result;
+
+ attrs = 0;
+ attrs |= DNS_DISPATCHATTR_UDP;
+ switch (family) {
+ case AF_INET:
+ attrs |= DNS_DISPATCHATTR_IPV4;
+ break;
+ case AF_INET6:
+ attrs |= DNS_DISPATCHATTR_IPV6;
+ break;
+ default:
+ INSIST(0);
+ }
+ attrmask = 0;
+ attrmask |= DNS_DISPATCHATTR_UDP;
+ attrmask |= DNS_DISPATCHATTR_TCP;
+ attrmask |= DNS_DISPATCHATTR_IPV4;
+ attrmask |= DNS_DISPATCHATTR_IPV6;
+
+ isc_sockaddr_anyofpf(&sa, family);
+
+ buffersize = 4096;
+ maxbuffers = is_shared ? 1000 : 8;
+ maxrequests = 32768;
+ buckets = is_shared ? 16411 : 3;
+ increment = is_shared ? 16433 : 5;
+
+ disp = NULL;
+ result = dns_dispatch_getudp(dispatchmgr, socketmgr,
+ taskmgr, &sa,
+ buffersize, maxbuffers, maxrequests,
+ buckets, increment,
+ attrs, attrmask, &disp);
+ if (result == ISC_R_SUCCESS)
+ *dispp = disp;
+
+ return (result);
+}
+
+static isc_result_t
+dns_client_createview(isc_mem_t *mctx, dns_rdataclass_t rdclass,
+ unsigned int options, isc_taskmgr_t *taskmgr,
+ unsigned int ntasks, isc_socketmgr_t *socketmgr,
+ isc_timermgr_t *timermgr, dns_dispatchmgr_t *dispatchmgr,
+ dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
+ dns_view_t **viewp)
+{
+ isc_result_t result;
+ dns_view_t *view = NULL;
+ const char *dbtype;
+
+ result = dns_view_create(mctx, rdclass, DNS_CLIENTVIEW_NAME, &view);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /* Initialize view security roots */
+ result = dns_view_initsecroots(view, mctx);
+ if (result != ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ return (result);
+ }
+
+ result = dns_view_createresolver(view, taskmgr, ntasks, socketmgr,
+ timermgr, 0, dispatchmgr,
+ dispatchv4, dispatchv6);
+ if (result != ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ return (result);
+ }
+
+ /*
+ * Set cache DB.
+ * XXX: it may be better if specific DB implementations can be
+ * specified via some configuration knob.
+ */
+ if ((options & DNS_CLIENTCREATEOPT_USECACHE) != 0)
+ dbtype = "rbt";
+ else
+ dbtype = "ecdb";
+ result = dns_db_create(mctx, dbtype, dns_rootname, dns_dbtype_cache,
+ rdclass, 0, NULL, &view->cachedb);
+ if (result != ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ return (result);
+ }
+
+ *viewp = view;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_client_create(dns_client_t **clientp, unsigned int options) {
+ isc_result_t result;
+ isc_mem_t *mctx = NULL;
+ isc_appctx_t *actx = NULL;
+ isc_taskmgr_t *taskmgr = NULL;
+ isc_socketmgr_t *socketmgr = NULL;
+ isc_timermgr_t *timermgr = NULL;
+
+ result = isc_mem_create(0, 0, &mctx);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_appctx_create(mctx, &actx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = isc_app_ctxstart(actx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = isc_taskmgr_createinctx(mctx, actx, 1, 0, &taskmgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = isc_socketmgr_createinctx(mctx, actx, &socketmgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = isc_timermgr_createinctx(mctx, actx, &timermgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr,
+ options, clientp);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ (*clientp)->attributes |= DNS_CLIENTATTR_OWNCTX;
+
+ /* client has its own reference to mctx, so we can detach it here */
+ isc_mem_detach(&mctx);
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (taskmgr != NULL)
+ isc_taskmgr_destroy(&taskmgr);
+ if (timermgr != NULL)
+ isc_timermgr_destroy(&timermgr);
+ if (socketmgr != NULL)
+ isc_socketmgr_destroy(&socketmgr);
+ if (actx != NULL)
+ isc_appctx_destroy(&actx);
+ isc_mem_detach(&mctx);
+
+ return (result);
+}
+
+isc_result_t
+dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
+ isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
+ unsigned int options, dns_client_t **clientp)
+{
+ dns_client_t *client;
+ isc_result_t result;
+ dns_dispatchmgr_t *dispatchmgr = NULL;
+ dns_dispatch_t *dispatchv4 = NULL;
+ dns_dispatch_t *dispatchv6 = NULL;
+ dns_view_t *view = NULL;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(taskmgr != NULL);
+ REQUIRE(timermgr != NULL);
+ REQUIRE(socketmgr != NULL);
+ REQUIRE(clientp != NULL && *clientp == NULL);
+
+ client = isc_mem_get(mctx, sizeof(*client));
+ if (client == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&client->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, client, sizeof(*client));
+ return (result);
+ }
+
+ client->actx = actx;
+ client->taskmgr = taskmgr;
+ client->socketmgr = socketmgr;
+ client->timermgr = timermgr;
+
+ client->task = NULL;
+ result = isc_task_create(client->taskmgr, 0, &client->task);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ client->dispatchmgr = dispatchmgr;
+
+ /* TODO: whether to use dispatch v4 or v6 should be configurable */
+ client->dispatchv4 = NULL;
+ client->dispatchv6 = NULL;
+ result = getudpdispatch(AF_INET, dispatchmgr, socketmgr,
+ taskmgr, ISC_TRUE, &dispatchv4);
+ if (result == ISC_R_SUCCESS)
+ client->dispatchv4 = dispatchv4;
+ result = getudpdispatch(AF_INET6, dispatchmgr, socketmgr,
+ taskmgr, ISC_TRUE, &dispatchv6);
+ if (result == ISC_R_SUCCESS)
+ client->dispatchv6 = dispatchv6;
+
+ /* We need at least one of the dispatchers */
+ if (dispatchv4 == NULL && dispatchv6 == NULL) {
+ INSIST(result != ISC_R_SUCCESS);
+ goto cleanup;
+ }
+
+ /* Create the default view for class IN */
+ result = dns_client_createview(mctx, dns_rdataclass_in, options,
+ taskmgr, 31, socketmgr, timermgr,
+ dispatchmgr, dispatchv4, dispatchv6,
+ &view);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ ISC_LIST_INIT(client->viewlist);
+ ISC_LIST_APPEND(client->viewlist, view, link);
+
+ dns_view_freeze(view); /* too early? */
+
+ ISC_LIST_INIT(client->resctxs);
+ ISC_LIST_INIT(client->reqctxs);
+ ISC_LIST_INIT(client->updatectxs);
+
+ client->mctx = NULL;
+ isc_mem_attach(mctx, &client->mctx);
+
+ client->update_timeout = DEF_UPDATE_TIMEOUT;
+ client->update_udptimeout = DEF_UPDATE_UDPTIMEOUT;
+ client->update_udpretries = DEF_UPDATE_UDPRETRIES;
+ client->find_timeout = DEF_FIND_TIMEOUT;
+ client->find_udpretries = DEF_FIND_UDPRETRIES;
+
+ client->references = 1;
+ client->magic = DNS_CLIENT_MAGIC;
+
+ *clientp = client;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (dispatchv4 != NULL)
+ dns_dispatch_detach(&dispatchv4);
+ if (dispatchv6 != NULL)
+ dns_dispatch_detach(&dispatchv6);
+ if (dispatchmgr != NULL)
+ dns_dispatchmgr_destroy(&dispatchmgr);
+ if (client->task != NULL)
+ isc_task_detach(&client->task);
+ isc_mem_put(mctx, client, sizeof(*client));
+
+ return (result);
+}
+
+static void
+destroyclient(dns_client_t **clientp) {
+ dns_client_t *client = *clientp;
+ dns_view_t *view;
+
+ while ((view = ISC_LIST_HEAD(client->viewlist)) != NULL) {
+ ISC_LIST_UNLINK(client->viewlist, view, link);
+ dns_view_detach(&view);
+ }
+
+ if (client->dispatchv4 != NULL)
+ dns_dispatch_detach(&client->dispatchv4);
+ if (client->dispatchv6 != NULL)
+ dns_dispatch_detach(&client->dispatchv6);
+
+ dns_dispatchmgr_destroy(&client->dispatchmgr);
+
+ isc_task_detach(&client->task);
+
+ /*
+ * If the client has created its own running environments,
+ * destroy them.
+ */
+ if ((client->attributes & DNS_CLIENTATTR_OWNCTX) != 0) {
+ isc_taskmgr_destroy(&client->taskmgr);
+ isc_timermgr_destroy(&client->timermgr);
+ isc_socketmgr_destroy(&client->socketmgr);
+
+ isc_app_ctxfinish(client->actx);
+ isc_appctx_destroy(&client->actx);
+ }
+
+ DESTROYLOCK(&client->lock);
+ client->magic = 0;
+
+ isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
+
+ *clientp = NULL;
+}
+
+void
+dns_client_destroy(dns_client_t **clientp) {
+ dns_client_t *client;
+ isc_boolean_t destroyok = ISC_FALSE;
+
+ REQUIRE(clientp != NULL);
+ client = *clientp;
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ LOCK(&client->lock);
+ client->references--;
+ if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
+ ISC_LIST_EMPTY(client->reqctxs) &&
+ ISC_LIST_EMPTY(client->updatectxs)) {
+ destroyok = ISC_TRUE;
+ }
+ UNLOCK(&client->lock);
+
+ if (destroyok)
+ destroyclient(&client);
+
+ *clientp = NULL;
+}
+
+isc_result_t
+dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *namespace, isc_sockaddrlist_t *addrs)
+{
+ isc_result_t result;
+ dns_view_t *view = NULL;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(addrs != NULL);
+
+ if (namespace == NULL)
+ namespace = dns_rootname;
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ rdclass, &view);
+ if (result != ISC_R_SUCCESS) {
+ UNLOCK(&client->lock);
+ return (result);
+ }
+ UNLOCK(&client->lock);
+
+ result = dns_fwdtable_add(view->fwdtable, namespace, addrs,
+ dns_fwdpolicy_only);
+
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+isc_result_t
+dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *namespace)
+{
+ isc_result_t result;
+ dns_view_t *view = NULL;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ if (namespace == NULL)
+ namespace = dns_rootname;
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ rdclass, &view);
+ if (result != ISC_R_SUCCESS) {
+ UNLOCK(&client->lock);
+ return (result);
+ }
+ UNLOCK(&client->lock);
+
+ result = dns_fwdtable_delete(view->fwdtable, namespace);
+
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+static isc_result_t
+getrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) {
+ dns_rdataset_t *rdataset;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(rdatasetp != NULL && *rdatasetp == NULL);
+
+ rdataset = isc_mem_get(mctx, sizeof(*rdataset));
+ if (rdataset == NULL)
+ return (ISC_R_NOMEMORY);
+
+ dns_rdataset_init(rdataset);
+
+ *rdatasetp = rdataset;
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+putrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) {
+ dns_rdataset_t *rdataset;
+
+ REQUIRE(rdatasetp != NULL);
+ rdataset = *rdatasetp;
+ REQUIRE(rdataset != NULL);
+
+ if (dns_rdataset_isassociated(rdataset))
+ dns_rdataset_disassociate(rdataset);
+
+ isc_mem_put(mctx, rdataset, sizeof(*rdataset));
+
+ *rdatasetp = NULL;
+}
+
+static void
+fetch_done(isc_task_t *task, isc_event_t *event) {
+ resctx_t *rctx = event->ev_arg;
+ dns_fetchevent_t *fevent;
+
+ REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
+ REQUIRE(RCTX_VALID(rctx));
+ REQUIRE(rctx->task == task);
+ fevent = (dns_fetchevent_t *)event;
+
+ client_resfind(rctx, fevent);
+}
+
+static inline isc_result_t
+start_fetch(resctx_t *rctx) {
+ isc_result_t result;
+
+ /*
+ * The caller must be holding the rctx's lock.
+ */
+
+ REQUIRE(rctx->fetch == NULL);
+
+ result = dns_resolver_createfetch(rctx->view->resolver,
+ dns_fixedname_name(&rctx->name),
+ rctx->type,
+ NULL, NULL, NULL, 0,
+ rctx->task, fetch_done, rctx,
+ rctx->rdataset,
+ rctx->sigrdataset,
+ &rctx->fetch);
+
+ return (result);
+}
+
+static isc_result_t
+view_find(resctx_t *rctx, dns_db_t **dbp, dns_dbnode_t **nodep,
+ dns_name_t *foundname)
+{
+ isc_result_t result;
+ dns_name_t *name = dns_fixedname_name(&rctx->name);
+ dns_rdatatype_t type;
+
+ if (rctx->type == dns_rdatatype_rrsig)
+ type = dns_rdatatype_any;
+ else
+ type = rctx->type;
+
+ result = dns_view_find(rctx->view, name, type, 0, 0, ISC_FALSE,
+ dbp, nodep, foundname, rctx->rdataset,
+ rctx->sigrdataset);
+
+ return (result);
+}
+
+static void
+client_resfind(resctx_t *rctx, dns_fetchevent_t *event) {
+ isc_mem_t *mctx;
+ isc_result_t result, tresult;
+ isc_result_t vresult = ISC_R_SUCCESS;
+ isc_boolean_t want_restart;
+ isc_boolean_t send_event = ISC_FALSE;
+ dns_name_t *name, *prefix;
+ dns_fixedname_t foundname, fixed;
+ dns_rdataset_t *trdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ unsigned int nlabels;
+ int order;
+ dns_namereln_t namereln;
+ dns_rdata_cname_t cname;
+ dns_rdata_dname_t dname;
+
+ REQUIRE(RCTX_VALID(rctx));
+
+ LOCK(&rctx->lock);
+
+ mctx = rctx->view->mctx;
+
+ result = ISC_R_SUCCESS;
+ name = dns_fixedname_name(&rctx->name);
+
+ do {
+ dns_name_t *fname = NULL;
+ dns_name_t *ansname = NULL;
+ dns_db_t *db = NULL;
+ dns_dbnode_t *node = NULL;
+
+ rctx->restarts++;
+ want_restart = ISC_FALSE;
+
+ if (event == NULL && !rctx->canceled) {
+ dns_fixedname_init(&foundname);
+ fname = dns_fixedname_name(&foundname);
+ INSIST(!dns_rdataset_isassociated(rctx->rdataset));
+ INSIST(rctx->sigrdataset == NULL ||
+ !dns_rdataset_isassociated(rctx->sigrdataset));
+ result = view_find(rctx, &db, &node, fname);
+ if (result == ISC_R_NOTFOUND) {
+ /*
+ * We don't know anything about the name.
+ * Launch a fetch.
+ */
+ if (node != NULL) {
+ INSIST(db != NULL);
+ dns_db_detachnode(db, &node);
+ }
+ if (db != NULL)
+ dns_db_detach(&db);
+ result = start_fetch(rctx);
+ if (result != ISC_R_SUCCESS) {
+ putrdataset(mctx, &rctx->rdataset);
+ if (rctx->sigrdataset != NULL)
+ putrdataset(mctx,
+ &rctx->sigrdataset);
+ send_event = ISC_TRUE;
+ }
+ goto done;
+ }
+ } else {
+ INSIST(event->fetch == rctx->fetch);
+ dns_resolver_destroyfetch(&rctx->fetch);
+ db = event->db;
+ node = event->node;
+ result = event->result;
+ vresult = event->vresult;
+ fname = dns_fixedname_name(&event->foundname);
+ INSIST(event->rdataset == rctx->rdataset);
+ INSIST(event->sigrdataset == rctx->sigrdataset);
+ }
+
+ /*
+ * If we've been canceled, forget about the result.
+ */
+ if (rctx->canceled)
+ result = ISC_R_CANCELED;
+ else {
+ /*
+ * Otherwise, get some resource for copying the
+ * result.
+ */
+ ansname = isc_mem_get(mctx, sizeof(*ansname));
+ if (ansname == NULL)
+ tresult = ISC_R_NOMEMORY;
+ else {
+ dns_name_t *aname;
+
+ aname = dns_fixedname_name(&rctx->name);
+ dns_name_init(ansname, NULL);
+ tresult = dns_name_dup(aname, mctx, ansname);
+ if (tresult != ISC_R_SUCCESS)
+ isc_mem_put(mctx, ansname,
+ sizeof(*ansname));
+ }
+ if (tresult != ISC_R_SUCCESS)
+ result = tresult;
+ }
+
+ switch (result) {
+ case ISC_R_SUCCESS:
+ send_event = ISC_TRUE;
+ /*
+ * This case is handled in the main line below.
+ */
+ break;
+ case DNS_R_CNAME:
+ /*
+ * Add the CNAME to the answer list.
+ */
+ trdataset = rctx->rdataset;
+ ISC_LIST_APPEND(ansname->list, rctx->rdataset, link);
+ rctx->rdataset = NULL;
+ if (rctx->sigrdataset != NULL) {
+ ISC_LIST_APPEND(ansname->list,
+ rctx->sigrdataset, link);
+ rctx->sigrdataset = NULL;
+ }
+ ISC_LIST_APPEND(rctx->namelist, ansname, link);
+ ansname = NULL;
+
+ /*
+ * Copy the CNAME's target into the lookup's
+ * query name and start over.
+ */
+ tresult = dns_rdataset_first(trdataset);
+ if (tresult != ISC_R_SUCCESS)
+ goto done;
+ dns_rdataset_current(trdataset, &rdata);
+ tresult = dns_rdata_tostruct(&rdata, &cname, NULL);
+ dns_rdata_reset(&rdata);
+ if (tresult != ISC_R_SUCCESS)
+ goto done;
+ tresult = dns_name_copy(&cname.cname, name, NULL);
+ dns_rdata_freestruct(&cname);
+ if (tresult == ISC_R_SUCCESS)
+ want_restart = ISC_TRUE;
+ else
+ result = tresult;
+ goto done;
+ case DNS_R_DNAME:
+ /*
+ * Add the DNAME to the answer list.
+ */
+ trdataset = rctx->rdataset;
+ ISC_LIST_APPEND(ansname->list, rctx->rdataset, link);
+ rctx->rdataset = NULL;
+ if (rctx->sigrdataset != NULL) {
+ ISC_LIST_APPEND(ansname->list,
+ rctx->sigrdataset, link);
+ rctx->sigrdataset = NULL;
+ }
+ ISC_LIST_APPEND(rctx->namelist, ansname, link);
+ ansname = NULL;
+
+ namereln = dns_name_fullcompare(name, fname, &order,
+ &nlabels);
+ INSIST(namereln == dns_namereln_subdomain);
+ /*
+ * Get the target name of the DNAME.
+ */
+ tresult = dns_rdataset_first(trdataset);
+ if (tresult != ISC_R_SUCCESS) {
+ result = tresult;
+ goto done;
+ }
+ dns_rdataset_current(trdataset, &rdata);
+ tresult = dns_rdata_tostruct(&rdata, &dname, NULL);
+ dns_rdata_reset(&rdata);
+ if (tresult != ISC_R_SUCCESS) {
+ result = tresult;
+ goto done;
+ }
+ /*
+ * Construct the new query name and start over.
+ */
+ dns_fixedname_init(&fixed);
+ prefix = dns_fixedname_name(&fixed);
+ dns_name_split(name, nlabels, prefix, NULL);
+ tresult = dns_name_concatenate(prefix, &dname.dname,
+ name, NULL);
+ dns_rdata_freestruct(&dname);
+ if (tresult == ISC_R_SUCCESS)
+ want_restart = ISC_TRUE;
+ else
+ result = tresult;
+ goto done;
+ case DNS_R_NCACHENXDOMAIN:
+ case DNS_R_NCACHENXRRSET:
+ ISC_LIST_APPEND(ansname->list, rctx->rdataset, link);
+ ISC_LIST_APPEND(rctx->namelist, ansname, link);
+ ansname = NULL;
+ rctx->rdataset = NULL;
+ /* What about sigrdataset? */
+ if (rctx->sigrdataset != NULL)
+ putrdataset(mctx, &rctx->sigrdataset);
+ send_event = ISC_TRUE;
+ goto done;
+ default:
+ if (rctx->rdataset != NULL)
+ putrdataset(mctx, &rctx->rdataset);
+ if (rctx->sigrdataset != NULL)
+ putrdataset(mctx, &rctx->sigrdataset);
+ send_event = ISC_TRUE;
+ goto done;
+ }
+
+ if (rctx->type == dns_rdatatype_any) {
+ int n = 0;
+ dns_rdatasetiter_t *rdsiter = NULL;
+
+ tresult = dns_db_allrdatasets(db, node, NULL, 0,
+ &rdsiter);
+ if (tresult != ISC_R_SUCCESS) {
+ result = tresult;
+ goto done;
+ }
+
+ tresult = dns_rdatasetiter_first(rdsiter);
+ while (tresult == ISC_R_SUCCESS) {
+ dns_rdatasetiter_current(rdsiter,
+ rctx->rdataset);
+ if (rctx->rdataset->type != 0) {
+ ISC_LIST_APPEND(ansname->list,
+ rctx->rdataset,
+ link);
+ n++;
+ rctx->rdataset = NULL;
+ } else {
+ /*
+ * We're not interested in this
+ * rdataset.
+ */
+ dns_rdataset_disassociate(
+ rctx->rdataset);
+ }
+ tresult = dns_rdatasetiter_next(rdsiter);
+
+ if (tresult == ISC_R_SUCCESS &&
+ rctx->rdataset == NULL) {
+ tresult = getrdataset(mctx,
+ &rctx->rdataset);
+ if (tresult != ISC_R_SUCCESS) {
+ result = tresult;
+ break;
+ }
+ }
+ }
+ if (n == 0) {
+ /*
+ * We didn't match any rdatasets (which means
+ * something went wrong in this
+ * implementation).
+ */
+ result = DNS_R_SERVFAIL; /* better code? */
+ } else {
+ ISC_LIST_APPEND(rctx->namelist, ansname, link);
+ ansname = NULL;
+ }
+ dns_rdatasetiter_destroy(&rdsiter);
+ if (tresult != ISC_R_NOMORE)
+ result = DNS_R_SERVFAIL; /* ditto */
+ else
+ result = ISC_R_SUCCESS;
+ goto done;
+ } else {
+ /*
+ * This is the "normal" case -- an ordinary question
+ * to which we've got the answer.
+ */
+ ISC_LIST_APPEND(ansname->list, rctx->rdataset, link);
+ rctx->rdataset = NULL;
+ if (rctx->sigrdataset != NULL) {
+ ISC_LIST_APPEND(ansname->list,
+ rctx->sigrdataset, link);
+ rctx->sigrdataset = NULL;
+ }
+ ISC_LIST_APPEND(rctx->namelist, ansname, link);
+ ansname = NULL;
+ }
+
+ done:
+ /*
+ * Free temporary resources
+ */
+ if (ansname != NULL) {
+ dns_rdataset_t *rdataset;
+
+ while ((rdataset = ISC_LIST_HEAD(ansname->list))
+ != NULL) {
+ ISC_LIST_UNLINK(ansname->list, rdataset, link);
+ putrdataset(mctx, &rdataset);
+ }
+ dns_name_free(ansname, mctx);
+ isc_mem_put(mctx, ansname, sizeof(*ansname));
+ }
+
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ if (db != NULL)
+ dns_db_detach(&db);
+ if (event != NULL)
+ isc_event_free(ISC_EVENT_PTR(&event));
+
+ /*
+ * Limit the number of restarts.
+ */
+ if (want_restart && rctx->restarts == MAX_RESTARTS) {
+ want_restart = ISC_FALSE;
+ result = ISC_R_QUOTA;
+ send_event = ISC_TRUE;
+ }
+
+ /*
+ * Prepare further find with new resources
+ */
+ if (want_restart) {
+ INSIST(rctx->rdataset == NULL &&
+ rctx->sigrdataset == NULL);
+
+ result = getrdataset(mctx, &rctx->rdataset);
+ if (result == ISC_R_SUCCESS && rctx->want_dnssec) {
+ result = getrdataset(mctx, &rctx->sigrdataset);
+ if (result != ISC_R_SUCCESS) {
+ putrdataset(mctx, &rctx->rdataset);
+ }
+ }
+
+ if (result != ISC_R_SUCCESS) {
+ want_restart = ISC_FALSE;
+ send_event = ISC_TRUE;
+ }
+ }
+ } while (want_restart);
+
+ if (send_event) {
+ isc_task_t *task;
+
+ while ((name = ISC_LIST_HEAD(rctx->namelist)) != NULL) {
+ ISC_LIST_UNLINK(rctx->namelist, name, link);
+ ISC_LIST_APPEND(rctx->event->answerlist, name, link);
+ }
+
+ rctx->event->result = result;
+ rctx->event->vresult = vresult;
+ task = rctx->event->ev_sender;
+ rctx->event->ev_sender = rctx;
+ isc_task_sendanddetach(&task, ISC_EVENT_PTR(&rctx->event));
+ }
+
+ UNLOCK(&rctx->lock);
+}
+
+static void
+resolve_done(isc_task_t *task, isc_event_t *event) {
+ resarg_t *resarg = event->ev_arg;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_name_t *name;
+
+ UNUSED(task);
+
+ LOCK(&resarg->lock);
+
+ resarg->result = rev->result;
+ resarg->vresult = rev->vresult;
+ while ((name = ISC_LIST_HEAD(rev->answerlist)) != NULL) {
+ ISC_LIST_UNLINK(rev->answerlist, name, link);
+ ISC_LIST_APPEND(*resarg->namelist, name, link);
+ }
+
+ dns_client_destroyrestrans(&resarg->trans);
+ isc_event_free(&event);
+
+ if (!resarg->canceled) {
+ UNLOCK(&resarg->lock);
+
+ /* Exit from the internal event loop */
+ isc_app_ctxsuspend(resarg->actx);
+ } else {
+ /*
+ * We have already exited from the loop (due to some
+ * unexpected event). Just clean the arg up.
+ */
+ UNLOCK(&resarg->lock);
+ DESTROYLOCK(&resarg->lock);
+ isc_mem_put(resarg->client->mctx, resarg, sizeof(*resarg));
+ }
+}
+
+isc_result_t
+dns_client_resolve(dns_client_t *client, dns_name_t *name,
+ dns_rdataclass_t rdclass, dns_rdatatype_t type,
+ unsigned int options, dns_namelist_t *namelist)
+{
+ isc_result_t result;
+ isc_appctx_t *actx;
+ resarg_t *resarg;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(namelist != NULL && ISC_LIST_EMPTY(*namelist));
+
+ if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 &&
+ (options & DNS_CLIENTRESOPT_ALLOWRUN) == 0) {
+ /*
+ * If the client is run under application's control, we need
+ * to create a new running (sub)environment for this
+ * particular resolution.
+ */
+ return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */
+ } else
+ actx = client->actx;
+
+ resarg = isc_mem_get(client->mctx, sizeof(*resarg));
+ if (resarg == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&resarg->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(client->mctx, resarg, sizeof(*resarg));
+ return (result);
+ }
+
+ resarg->actx = actx;
+ resarg->client = client;
+ resarg->result = DNS_R_SERVFAIL;
+ resarg->namelist = namelist;
+ resarg->trans = NULL;
+ resarg->canceled = ISC_FALSE;
+ result = dns_client_startresolve(client, name, rdclass, type, options,
+ client->task, resolve_done, resarg,
+ &resarg->trans);
+ if (result != ISC_R_SUCCESS) {
+ DESTROYLOCK(&resarg->lock);
+ isc_mem_put(client->mctx, resarg, sizeof(*resarg));
+ return (result);
+ }
+
+ /*
+ * Start internal event loop. It blocks until the entire process
+ * is completed.
+ */
+ result = isc_app_ctxrun(actx);
+
+ LOCK(&resarg->lock);
+ if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND)
+ result = resarg->result;
+ if (result != ISC_R_SUCCESS && resarg->vresult != ISC_R_SUCCESS) {
+ /*
+ * If this lookup failed due to some error in DNSSEC
+ * validation, return the validation error code.
+ * XXX: or should we pass the validation result separately?
+ */
+ result = resarg->vresult;
+ }
+ if (resarg->trans != NULL) {
+ /*
+ * Unusual termination (perhaps due to signal). We need some
+ * tricky cleanup process.
+ */
+ resarg->canceled = ISC_TRUE;
+ dns_client_cancelresolve(resarg->trans);
+
+ UNLOCK(&resarg->lock);
+
+ /* resarg will be freed in the event handler. */
+ } else {
+ UNLOCK(&resarg->lock);
+
+ DESTROYLOCK(&resarg->lock);
+ isc_mem_put(client->mctx, resarg, sizeof(*resarg));
+ }
+
+ return (result);
+}
+
+isc_result_t
+dns_client_startresolve(dns_client_t *client, dns_name_t *name,
+ dns_rdataclass_t rdclass, dns_rdatatype_t type,
+ unsigned int options, isc_task_t *task,
+ isc_taskaction_t action, void *arg,
+ dns_clientrestrans_t **transp)
+{
+ dns_view_t *view = NULL;
+ dns_clientresevent_t *event = NULL;
+ resctx_t *rctx = NULL;
+ isc_task_t *clone = NULL;
+ isc_mem_t *mctx;
+ isc_result_t result;
+ dns_rdataset_t *rdataset, *sigrdataset;
+ isc_boolean_t want_dnssec;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(transp != NULL && *transp == NULL);
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ rdclass, &view);
+ UNLOCK(&client->lock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ mctx = client->mctx;
+ rdataset = NULL;
+ sigrdataset = NULL;
+ want_dnssec = ISC_TF((options & DNS_CLIENTRESOPT_NODNSSEC) == 0);
+
+ /*
+ * Prepare some intermediate resources
+ */
+ clone = NULL;
+ isc_task_attach(task, &clone);
+ event = (dns_clientresevent_t *)
+ isc_event_allocate(mctx, clone, DNS_EVENT_CLIENTRESDONE,
+ action, arg, sizeof(*event));
+ if (event == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ event->result = DNS_R_SERVFAIL;
+ ISC_LIST_INIT(event->answerlist);
+
+ rctx = isc_mem_get(mctx, sizeof(*rctx));
+ if (rctx == NULL)
+ result = ISC_R_NOMEMORY;
+ else {
+ result = isc_mutex_init(&rctx->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, rctx, sizeof(*rctx));
+ rctx = NULL;
+ }
+ }
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = getrdataset(mctx, &rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ rctx->rdataset = rdataset;
+
+ if (want_dnssec) {
+ result = getrdataset(mctx, &sigrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+ rctx->sigrdataset = sigrdataset;
+
+ dns_fixedname_init(&rctx->name);
+ result = dns_name_copy(name, dns_fixedname_name(&rctx->name), NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ rctx->client = client;
+ ISC_LINK_INIT(rctx, link);
+ rctx->canceled = ISC_FALSE;
+ rctx->task = client->task;
+ rctx->type = type;
+ rctx->view = view;
+ rctx->restarts = 0;
+ rctx->fetch = NULL;
+ rctx->want_dnssec = want_dnssec;
+ ISC_LIST_INIT(rctx->namelist);
+ rctx->event = event;
+
+ rctx->magic = RCTX_MAGIC;
+
+ LOCK(&client->lock);
+ ISC_LIST_APPEND(client->resctxs, rctx, link);
+ UNLOCK(&client->lock);
+
+ client_resfind(rctx, NULL);
+
+ *transp = (dns_clientrestrans_t *)rctx;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (rdataset != NULL)
+ putrdataset(client->mctx, &rdataset);
+ if (sigrdataset != NULL)
+ putrdataset(client->mctx, &sigrdataset);
+ if (rctx != NULL) {
+ DESTROYLOCK(&rctx->lock);
+ isc_mem_put(mctx, rctx, sizeof(*rctx));
+ }
+ if (event != NULL)
+ isc_event_free(ISC_EVENT_PTR(&event));
+ isc_task_detach(&clone);
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+void
+dns_client_cancelresolve(dns_clientrestrans_t *trans) {
+ resctx_t *rctx;
+
+ REQUIRE(trans != NULL);
+ rctx = (resctx_t *)trans;
+ REQUIRE(RCTX_VALID(rctx));
+
+ LOCK(&rctx->lock);
+
+ if (!rctx->canceled) {
+ rctx->canceled = ISC_TRUE;
+ if (rctx->fetch != NULL)
+ dns_resolver_cancelfetch(rctx->fetch);
+ }
+
+ UNLOCK(&rctx->lock);
+}
+
+void
+dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist) {
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(namelist != NULL);
+
+ while ((name = ISC_LIST_HEAD(*namelist)) != NULL) {
+ ISC_LIST_UNLINK(*namelist, name, link);
+ while ((rdataset = ISC_LIST_HEAD(name->list)) != NULL) {
+ ISC_LIST_UNLINK(name->list, rdataset, link);
+ putrdataset(client->mctx, &rdataset);
+ }
+ dns_name_free(name, client->mctx);
+ isc_mem_put(client->mctx, name, sizeof(*name));
+ }
+}
+
+void
+dns_client_destroyrestrans(dns_clientrestrans_t **transp) {
+ resctx_t *rctx;
+ isc_mem_t *mctx;
+ dns_client_t *client;
+ isc_boolean_t need_destroyclient = ISC_FALSE;
+
+ REQUIRE(transp != NULL);
+ rctx = (resctx_t *)*transp;
+ REQUIRE(RCTX_VALID(rctx));
+ REQUIRE(rctx->fetch == NULL);
+ REQUIRE(rctx->event == NULL);
+ client = rctx->client;
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ mctx = client->mctx;
+ dns_view_detach(&rctx->view);
+
+ LOCK(&client->lock);
+
+ INSIST(ISC_LINK_LINKED(rctx, link));
+ ISC_LIST_UNLINK(client->resctxs, rctx, link);
+
+ if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
+ ISC_LIST_EMPTY(client->reqctxs) &&
+ ISC_LIST_EMPTY(client->updatectxs))
+ need_destroyclient = ISC_TRUE;
+
+ UNLOCK(&client->lock);
+
+ INSIST(ISC_LIST_EMPTY(rctx->namelist));
+
+ DESTROYLOCK(&rctx->lock);
+ rctx->magic = 0;
+
+ isc_mem_put(mctx, rctx, sizeof(*rctx));
+
+ if (need_destroyclient)
+ destroyclient(&client);
+
+ *transp = NULL;
+}
+
+isc_result_t
+dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *keyname, isc_buffer_t *keydatabuf)
+{
+ isc_result_t result;
+ dns_view_t *view = NULL;
+ dst_key_t *dstkey = NULL;
+ dns_keytable_t *secroots = NULL;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ rdclass, &view);
+ UNLOCK(&client->lock);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_view_getsecroots(view, &secroots);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dst_key_fromdns(keyname, rdclass, keydatabuf, client->mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_keytable_add(secroots, ISC_FALSE, &dstkey);
+
+ cleanup:
+ if (dstkey != NULL)
+ dst_key_free(&dstkey);
+ if (view != NULL)
+ dns_view_detach(&view);
+ if (secroots != NULL)
+ dns_keytable_detach(&secroots);
+ return (result);
+}
+
+/*%
+ * Simple request routines
+ */
+static void
+request_done(isc_task_t *task, isc_event_t *event) {
+ dns_requestevent_t *reqev = NULL;
+ dns_request_t *request;
+ isc_result_t result, eresult;
+ reqctx_t *ctx;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE);
+ reqev = (dns_requestevent_t *)event;
+ request = reqev->request;
+ result = eresult = reqev->result;
+ ctx = reqev->ev_arg;
+ REQUIRE(REQCTX_VALID(ctx));
+
+ isc_event_free(&event);
+
+ LOCK(&ctx->lock);
+
+ if (eresult == ISC_R_SUCCESS) {
+ result = dns_request_getresponse(request, ctx->event->rmessage,
+ ctx->parseoptions);
+ }
+
+ if (ctx->tsigkey != NULL)
+ dns_tsigkey_detach(&ctx->tsigkey);
+
+ if (ctx->canceled)
+ ctx->event->result = ISC_R_CANCELED;
+ else
+ ctx->event->result = result;
+ task = ctx->event->ev_sender;
+ ctx->event->ev_sender = ctx;
+ isc_task_sendanddetach(&task, ISC_EVENT_PTR(&ctx->event));
+
+ UNLOCK(&ctx->lock);
+}
+
+static void
+localrequest_done(isc_task_t *task, isc_event_t *event) {
+ reqarg_t *reqarg = event->ev_arg;
+ dns_clientreqevent_t *rev =(dns_clientreqevent_t *)event;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_type == DNS_EVENT_CLIENTREQDONE);
+
+ LOCK(&reqarg->lock);
+
+ reqarg->result = rev->result;
+ dns_client_destroyreqtrans(&reqarg->trans);
+ isc_event_free(&event);
+
+ if (!reqarg->canceled) {
+ UNLOCK(&reqarg->lock);
+
+ /* Exit from the internal event loop */
+ isc_app_ctxsuspend(reqarg->actx);
+ } else {
+ /*
+ * We have already exited from the loop (due to some
+ * unexpected event). Just clean the arg up.
+ */
+ UNLOCK(&reqarg->lock);
+ DESTROYLOCK(&reqarg->lock);
+ isc_mem_put(reqarg->client->mctx, reqarg, sizeof(*reqarg));
+ }
+}
+
+isc_result_t
+dns_client_request(dns_client_t *client, dns_message_t *qmessage,
+ dns_message_t *rmessage, isc_sockaddr_t *server,
+ unsigned int options, unsigned int parseoptions,
+ dns_tsec_t *tsec, unsigned int timeout,
+ unsigned int udptimeout, unsigned int udpretries)
+{
+ isc_appctx_t *actx;
+ reqarg_t *reqarg;
+ isc_result_t result;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(qmessage != NULL);
+ REQUIRE(rmessage != NULL);
+
+ if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 &&
+ (options & DNS_CLIENTREQOPT_ALLOWRUN) == 0) {
+ /*
+ * If the client is run under application's control, we need
+ * to create a new running (sub)environment for this
+ * particular resolution.
+ */
+ return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */
+ } else
+ actx = client->actx;
+
+ reqarg = isc_mem_get(client->mctx, sizeof(*reqarg));
+ if (reqarg == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&reqarg->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(client->mctx, reqarg, sizeof(*reqarg));
+ return (result);
+ }
+
+ reqarg->actx = actx;
+ reqarg->client = client;
+ reqarg->trans = NULL;
+ reqarg->canceled = ISC_FALSE;
+
+ result = dns_client_startrequest(client, qmessage, rmessage, server,
+ options, parseoptions, tsec, timeout,
+ udptimeout, udpretries,
+ client->task, localrequest_done,
+ reqarg, &reqarg->trans);
+ if (result != ISC_R_SUCCESS) {
+ DESTROYLOCK(&reqarg->lock);
+ isc_mem_put(client->mctx, reqarg, sizeof(*reqarg));
+ return (result);
+ }
+
+ /*
+ * Start internal event loop. It blocks until the entire process
+ * is completed.
+ */
+ result = isc_app_ctxrun(actx);
+
+ LOCK(&reqarg->lock);
+ if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND)
+ result = reqarg->result;
+ if (reqarg->trans != NULL) {
+ /*
+ * Unusual termination (perhaps due to signal). We need some
+ * tricky cleanup process.
+ */
+ reqarg->canceled = ISC_TRUE;
+ dns_client_cancelresolve(reqarg->trans);
+
+ UNLOCK(&reqarg->lock);
+
+ /* reqarg will be freed in the event handler. */
+ } else {
+ UNLOCK(&reqarg->lock);
+
+ DESTROYLOCK(&reqarg->lock);
+ isc_mem_put(client->mctx, reqarg, sizeof(*reqarg));
+ }
+
+ return (result);
+}
+
+isc_result_t
+dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage,
+ dns_message_t *rmessage, isc_sockaddr_t *server,
+ unsigned int options, unsigned int parseoptions,
+ dns_tsec_t *tsec, unsigned int timeout,
+ unsigned int udptimeout, unsigned int udpretries,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
+ dns_clientreqtrans_t **transp)
+{
+ isc_result_t result;
+ dns_view_t *view = NULL;
+ isc_task_t *clone = NULL;
+ dns_clientreqevent_t *event = NULL;
+ reqctx_t *ctx = NULL;
+ dns_tsectype_t tsectype = dns_tsectype_none;
+
+ UNUSED(options);
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(qmessage != NULL);
+ REQUIRE(rmessage != NULL);
+ REQUIRE(transp != NULL && *transp == NULL);
+
+ if (tsec != NULL) {
+ tsectype = dns_tsec_gettype(tsec);
+ if (tsectype != dns_tsectype_tsig)
+ return (ISC_R_NOTIMPLEMENTED); /* XXX */
+ }
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ qmessage->rdclass, &view);
+ UNLOCK(&client->lock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ clone = NULL;
+ isc_task_attach(task, &clone);
+ event = (dns_clientreqevent_t *)
+ isc_event_allocate(client->mctx, clone,
+ DNS_EVENT_CLIENTREQDONE,
+ action, arg, sizeof(*event));
+ if (event == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+
+ ctx = isc_mem_get(client->mctx, sizeof(*ctx));
+ if (ctx == NULL)
+ result = ISC_R_NOMEMORY;
+ else {
+ result = isc_mutex_init(&ctx->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(client->mctx, ctx, sizeof(*ctx));
+ ctx = NULL;
+ }
+ }
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ ctx->client = client;
+ ISC_LINK_INIT(ctx, link);
+ ctx->parseoptions = parseoptions;
+ ctx->canceled = ISC_FALSE;
+ ctx->event = event;
+ ctx->event->rmessage = rmessage;
+ ctx->tsigkey = NULL;
+ if (tsec != NULL)
+ dns_tsec_getkey(tsec, &ctx->tsigkey);
+
+ ctx->magic = REQCTX_MAGIC;
+
+ LOCK(&client->lock);
+ ISC_LIST_APPEND(client->reqctxs, ctx, link);
+ UNLOCK(&client->lock);
+
+ ctx->request = NULL;
+ result = dns_request_createvia3(view->requestmgr, qmessage, NULL,
+ server, options, ctx->tsigkey,
+ timeout, udptimeout, udpretries,
+ client->task, request_done, ctx,
+ &ctx->request);
+ if (result == ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ *transp = (dns_clientreqtrans_t *)ctx;
+ return (ISC_R_SUCCESS);
+ }
+
+ cleanup:
+ if (ctx != NULL) {
+ LOCK(&client->lock);
+ ISC_LIST_UNLINK(client->reqctxs, ctx, link);
+ UNLOCK(&client->lock);
+ DESTROYLOCK(&ctx->lock);
+ isc_mem_put(client->mctx, ctx, sizeof(*ctx));
+ }
+ if (event != NULL)
+ isc_event_free(ISC_EVENT_PTR(&event));
+ isc_task_detach(&clone);
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+void
+dns_client_cancelrequest(dns_clientreqtrans_t *trans) {
+ reqctx_t *ctx;
+
+ REQUIRE(trans != NULL);
+ ctx = (reqctx_t *)trans;
+ REQUIRE(REQCTX_VALID(ctx));
+
+ LOCK(&ctx->lock);
+
+ if (!ctx->canceled) {
+ ctx->canceled = ISC_TRUE;
+ if (ctx->request != NULL)
+ dns_request_cancel(ctx->request);
+ }
+
+ UNLOCK(&ctx->lock);
+}
+
+void
+dns_client_destroyreqtrans(dns_clientreqtrans_t **transp) {
+ reqctx_t *ctx;
+ isc_mem_t *mctx;
+ dns_client_t *client;
+ isc_boolean_t need_destroyclient = ISC_FALSE;
+
+ REQUIRE(transp != NULL);
+ ctx = (reqctx_t *)*transp;
+ REQUIRE(REQCTX_VALID(ctx));
+ client = ctx->client;
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(ctx->event == NULL);
+ REQUIRE(ctx->request != NULL);
+
+ dns_request_destroy(&ctx->request);
+ mctx = client->mctx;
+
+ LOCK(&client->lock);
+
+ INSIST(ISC_LINK_LINKED(ctx, link));
+ ISC_LIST_UNLINK(client->reqctxs, ctx, link);
+
+ if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
+ ISC_LIST_EMPTY(client->reqctxs) &&
+ ISC_LIST_EMPTY(client->updatectxs)) {
+ need_destroyclient = ISC_TRUE;
+ }
+
+ UNLOCK(&client->lock);
+
+ DESTROYLOCK(&ctx->lock);
+ ctx->magic = 0;
+
+ isc_mem_put(mctx, ctx, sizeof(*ctx));
+
+ if (need_destroyclient)
+ destroyclient(&client);
+
+ *transp = NULL;
+}
+
+/*%
+ * Dynamic update routines
+ */
+static isc_result_t
+rcode2result(dns_rcode_t rcode) {
+ /* XXX: isn't there a similar function? */
+ switch (rcode) {
+ case dns_rcode_formerr:
+ return (DNS_R_FORMERR);
+ case dns_rcode_servfail:
+ return (DNS_R_SERVFAIL);
+ case dns_rcode_nxdomain:
+ return (DNS_R_NXDOMAIN);
+ case dns_rcode_notimp:
+ return (DNS_R_NOTIMP);
+ case dns_rcode_refused:
+ return (DNS_R_REFUSED);
+ case dns_rcode_yxdomain:
+ return (DNS_R_YXDOMAIN);
+ case dns_rcode_yxrrset:
+ return (DNS_R_YXRRSET);
+ case dns_rcode_nxrrset:
+ return (DNS_R_NXRRSET);
+ case dns_rcode_notauth:
+ return (DNS_R_NOTAUTH);
+ case dns_rcode_notzone:
+ return (DNS_R_NOTZONE);
+ case dns_rcode_badvers:
+ return (DNS_R_BADVERS);
+ }
+
+ return (ISC_R_FAILURE);
+}
+
+static void
+update_sendevent(updatectx_t *uctx, isc_result_t result) {
+ isc_task_t *task;
+
+ dns_message_destroy(&uctx->updatemsg);
+ if (uctx->tsigkey != NULL)
+ dns_tsigkey_detach(&uctx->tsigkey);
+ if (uctx->sig0key != NULL)
+ dst_key_free(&uctx->sig0key);
+
+ if (uctx->canceled)
+ uctx->event->result = ISC_R_CANCELED;
+ else
+ uctx->event->result = result;
+ uctx->event->state = uctx->state;
+ task = uctx->event->ev_sender;
+ uctx->event->ev_sender = uctx;
+ isc_task_sendanddetach(&task, ISC_EVENT_PTR(&uctx->event));
+}
+
+static void
+update_done(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+ dns_requestevent_t *reqev = NULL;
+ dns_request_t *request;
+ dns_message_t *answer = NULL;
+ updatectx_t *uctx = event->ev_arg;
+ dns_client_t *client;
+ unsigned int timeout;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE);
+ reqev = (dns_requestevent_t *)event;
+ request = reqev->request;
+ REQUIRE(UCTX_VALID(uctx));
+ client = uctx->client;
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ result = reqev->result;
+ if (result != ISC_R_SUCCESS)
+ goto out;
+
+ result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE,
+ &answer);
+ if (result != ISC_R_SUCCESS)
+ goto out;
+ uctx->state = dns_clientupdatestate_done;
+ result = dns_request_getresponse(request, answer,
+ DNS_MESSAGEPARSE_PRESERVEORDER);
+ if (result == ISC_R_SUCCESS && answer->rcode != dns_rcode_noerror)
+ result = rcode2result(answer->rcode);
+
+ out:
+ if (answer != NULL)
+ dns_message_destroy(&answer);
+ isc_event_free(&event);
+
+ LOCK(&uctx->lock);
+ uctx->currentserver = ISC_LIST_NEXT(uctx->currentserver, link);
+ dns_request_destroy(&uctx->updatereq);
+ if (result != ISC_R_SUCCESS && !uctx->canceled &&
+ uctx->currentserver != NULL) {
+ dns_message_renderreset(uctx->updatemsg);
+ dns_message_settsigkey(uctx->updatemsg, NULL);
+
+ timeout = client->update_timeout / uctx->nservers;
+ if (timeout < MIN_UPDATE_TIMEOUT)
+ timeout = MIN_UPDATE_TIMEOUT;
+ result = dns_request_createvia3(uctx->view->requestmgr,
+ uctx->updatemsg,
+ NULL,
+ uctx->currentserver, 0,
+ uctx->tsigkey,
+ timeout,
+ client->update_udptimeout,
+ client->update_udpretries,
+ client->task,
+ update_done, uctx,
+ &uctx->updatereq);
+ UNLOCK(&uctx->lock);
+
+ if (result == ISC_R_SUCCESS) {
+ /* XXX: should we keep the 'done' state here? */
+ uctx->state = dns_clientupdatestate_sent;
+ return;
+ }
+ } else
+ UNLOCK(&uctx->lock);
+
+ update_sendevent(uctx, result);
+}
+
+static isc_result_t
+send_update(updatectx_t *uctx) {
+ isc_result_t result;
+ dns_name_t *name = NULL;
+ dns_rdataset_t *rdataset = NULL;
+ dns_client_t *client = uctx->client;
+ unsigned int timeout;
+
+ REQUIRE(uctx->zonename != NULL && uctx->currentserver != NULL);
+
+ result = dns_message_gettempname(uctx->updatemsg, &name);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ dns_name_init(name, NULL);
+ dns_name_clone(uctx->zonename, name);
+ result = dns_message_gettemprdataset(uctx->updatemsg, &rdataset);
+ if (result != ISC_R_SUCCESS) {
+ dns_message_puttempname(uctx->updatemsg, &name);
+ return (result);
+ }
+ dns_rdataset_makequestion(rdataset, uctx->rdclass, dns_rdatatype_soa);
+ ISC_LIST_INIT(name->list);
+ ISC_LIST_APPEND(name->list, rdataset, link);
+ dns_message_addname(uctx->updatemsg, name, DNS_SECTION_ZONE);
+ if (uctx->tsigkey == NULL && uctx->sig0key != NULL) {
+ result = dns_message_setsig0key(uctx->updatemsg,
+ uctx->sig0key);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+ timeout = client->update_timeout / uctx->nservers;
+ if (timeout < MIN_UPDATE_TIMEOUT)
+ timeout = MIN_UPDATE_TIMEOUT;
+ result = dns_request_createvia3(uctx->view->requestmgr,
+ uctx->updatemsg,
+ NULL, uctx->currentserver, 0,
+ uctx->tsigkey, timeout,
+ client->update_udptimeout,
+ client->update_udpretries,
+ client->task, update_done, uctx,
+ &uctx->updatereq);
+ if (result == ISC_R_SUCCESS &&
+ uctx->state == dns_clientupdatestate_prepare) {
+ uctx->state = dns_clientupdatestate_sent;
+ }
+
+ return (result);
+}
+
+static void
+resolveaddr_done(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result;
+ int family;
+ dns_rdatatype_t qtype;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ updatectx_t *uctx;
+ isc_boolean_t completed = ISC_FALSE;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_arg != NULL);
+ uctx = *(updatectx_t **)event->ev_arg;
+ REQUIRE(UCTX_VALID(uctx));
+
+ if (event->ev_arg == &uctx->bp4) {
+ family = AF_INET;
+ qtype = dns_rdatatype_a;
+ LOCK(&uctx->lock);
+ dns_client_destroyrestrans(&uctx->restrans);
+ UNLOCK(&uctx->lock);
+ } else {
+ INSIST(event->ev_arg == &uctx->bp6);
+ family = AF_INET6;
+ qtype = dns_rdatatype_aaaa;
+ LOCK(&uctx->lock);
+ dns_client_destroyrestrans(&uctx->restrans2);
+ UNLOCK(&uctx->lock);
+ }
+
+ result = rev->result;
+ if (result != ISC_R_SUCCESS)
+ goto done;
+
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (!dns_rdataset_isassociated(rdataset))
+ continue;
+ if (rdataset->type != qtype)
+ continue;
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_t rdata;
+ dns_rdata_in_a_t rdata_a;
+ dns_rdata_in_aaaa_t rdata_aaaa;
+ isc_sockaddr_t *sa;
+
+ sa = isc_mem_get(uctx->client->mctx,
+ sizeof(*sa));
+ if (sa == NULL) {
+ /*
+ * If we fail to get a sockaddr,
+ we simply move forward with the
+ * addresses we've got so far.
+ */
+ goto done;
+ }
+
+ dns_rdata_init(&rdata);
+ switch (family) {
+ case AF_INET:
+ dns_rdataset_current(rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &rdata_a,
+ NULL);
+ isc_sockaddr_fromin(sa,
+ &rdata_a.in_addr,
+ 53);
+ dns_rdata_freestruct(&rdata_a);
+ break;
+ case AF_INET6:
+ dns_rdataset_current(rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &rdata_aaaa,
+ NULL);
+ isc_sockaddr_fromin6(sa,
+ &rdata_aaaa.in6_addr,
+ 53);
+ dns_rdata_freestruct(&rdata_aaaa);
+ break;
+ }
+
+ ISC_LINK_INIT(sa, link);
+ ISC_LIST_APPEND(uctx->servers, sa, link);
+ uctx->nservers++;
+ }
+ }
+ }
+
+ done:
+ dns_client_freeresanswer(uctx->client, &rev->answerlist);
+ isc_event_free(&event);
+
+ LOCK(&uctx->lock);
+ if (uctx->restrans == NULL && uctx->restrans2 == NULL)
+ completed = ISC_TRUE;
+ UNLOCK(&uctx->lock);
+
+ if (completed) {
+ INSIST(uctx->currentserver == NULL);
+ uctx->currentserver = ISC_LIST_HEAD(uctx->servers);
+ if (uctx->currentserver != NULL && !uctx->canceled)
+ send_update(uctx);
+ else {
+ if (result == ISC_R_SUCCESS)
+ result = ISC_R_NOTFOUND;
+ update_sendevent(uctx, result);
+ }
+ }
+}
+
+static isc_result_t
+process_soa(updatectx_t *uctx, dns_rdataset_t *soaset, dns_name_t *soaname) {
+ isc_result_t result;
+ dns_rdata_t soarr = DNS_RDATA_INIT;
+ dns_rdata_soa_t soa;
+ dns_name_t primary;
+
+ result = dns_rdataset_first(soaset);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ dns_rdata_init(&soarr);
+ dns_rdataset_current(soaset, &soarr);
+ result = dns_rdata_tostruct(&soarr, &soa, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dns_name_init(&primary, NULL);
+ dns_name_clone(&soa.origin, &primary);
+
+ if (uctx->zonename == NULL) {
+ uctx->zonename = dns_fixedname_name(&uctx->zonefname);
+ result = dns_name_copy(soaname, uctx->zonename, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto out;
+ }
+
+ if (uctx->currentserver != NULL)
+ result = send_update(uctx);
+ else {
+ /*
+ * Get addresses of the primary server. We don't use the ADB
+ * feature so that we could avoid caching data.
+ */
+ LOCK(&uctx->lock);
+ uctx->bp4 = uctx;
+ result = dns_client_startresolve(uctx->client, &primary,
+ uctx->rdclass,
+ dns_rdatatype_a,
+ 0, uctx->client->task,
+ resolveaddr_done, &uctx->bp4,
+ &uctx->restrans);
+ if (result == ISC_R_SUCCESS) {
+ uctx->bp6 = uctx;
+ result = dns_client_startresolve(uctx->client,
+ &primary,
+ uctx->rdclass,
+ dns_rdatatype_aaaa,
+ 0, uctx->client->task,
+ resolveaddr_done,
+ &uctx->bp6,
+ &uctx->restrans2);
+ }
+ UNLOCK(&uctx->lock);
+ }
+
+ out:
+ dns_rdata_freestruct(&soa);
+
+ return (result);
+}
+
+static void
+receive_soa(isc_task_t *task, isc_event_t *event) {
+ dns_requestevent_t *reqev = NULL;
+ updatectx_t *uctx;
+ dns_client_t *client;
+ isc_result_t result, eresult;
+ dns_request_t *request;
+ dns_message_t *rcvmsg = NULL;
+ dns_section_t section;
+ dns_rdataset_t *soaset = NULL;
+ int pass = 0;
+ dns_name_t *name;
+ dns_message_t *soaquery = NULL;
+ isc_sockaddr_t *addr;
+ isc_boolean_t seencname = ISC_FALSE;
+ isc_boolean_t droplabel = ISC_FALSE;
+ dns_name_t tname;
+ unsigned int nlabels;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE);
+ reqev = (dns_requestevent_t *)event;
+ request = reqev->request;
+ result = eresult = reqev->result;
+ uctx = reqev->ev_arg;
+ client = uctx->client;
+ soaquery = uctx->soaquery;
+ addr = uctx->currentserver;
+ INSIST(addr != NULL);
+
+ isc_event_free(&event);
+
+ if (eresult != ISC_R_SUCCESS) {
+ result = eresult;
+ goto out;
+ }
+
+ result = dns_message_create(uctx->client->mctx,
+ DNS_MESSAGE_INTENTPARSE, &rcvmsg);
+ if (result != ISC_R_SUCCESS)
+ goto out;
+ result = dns_request_getresponse(request, rcvmsg,
+ DNS_MESSAGEPARSE_PRESERVEORDER);
+
+ if (result == DNS_R_TSIGERRORSET) {
+ dns_request_t *newrequest = NULL;
+
+ /* Retry SOA request without TSIG */
+ dns_message_destroy(&rcvmsg);
+ dns_message_renderreset(uctx->soaquery);
+ result = dns_request_createvia3(uctx->view->requestmgr,
+ uctx->soaquery, NULL, addr, 0,
+ NULL,
+ client->find_timeout * 20,
+ client->find_timeout, 3,
+ uctx->client->task,
+ receive_soa, uctx,
+ &newrequest);
+ if (result == ISC_R_SUCCESS) {
+ LOCK(&uctx->lock);
+ dns_request_destroy(&uctx->soareq);
+ uctx->soareq = newrequest;
+ UNLOCK(&uctx->lock);
+
+ return;
+ }
+ goto out;
+ }
+
+ section = DNS_SECTION_ANSWER;
+
+ if (rcvmsg->rcode != dns_rcode_noerror &&
+ rcvmsg->rcode != dns_rcode_nxdomain) {
+ result = rcode2result(rcvmsg->rcode);
+ goto out;
+ }
+
+ lookforsoa:
+ if (pass == 0)
+ section = DNS_SECTION_ANSWER;
+ else if (pass == 1)
+ section = DNS_SECTION_AUTHORITY;
+ else {
+ droplabel = ISC_TRUE;
+ goto out;
+ }
+
+ result = dns_message_firstname(rcvmsg, section);
+ if (result != ISC_R_SUCCESS) {
+ pass++;
+ goto lookforsoa;
+ }
+ while (result == ISC_R_SUCCESS) {
+ name = NULL;
+ dns_message_currentname(rcvmsg, section, &name);
+ soaset = NULL;
+ result = dns_message_findtype(name, dns_rdatatype_soa, 0,
+ &soaset);
+ if (result == ISC_R_SUCCESS)
+ break;
+ if (section == DNS_SECTION_ANSWER) {
+ dns_rdataset_t *tset = NULL;
+ if (dns_message_findtype(name, dns_rdatatype_cname, 0,
+ &tset) == ISC_R_SUCCESS
+ ||
+ dns_message_findtype(name, dns_rdatatype_dname, 0,
+ &tset) == ISC_R_SUCCESS
+ )
+ {
+ seencname = ISC_TRUE;
+ break;
+ }
+ }
+
+ result = dns_message_nextname(rcvmsg, section);
+ }
+
+ if (soaset == NULL && !seencname) {
+ pass++;
+ goto lookforsoa;
+ }
+
+ if (seencname) {
+ droplabel = ISC_TRUE;
+ goto out;
+ }
+
+ result = process_soa(uctx, soaset, name);
+
+ out:
+ if (droplabel) {
+ result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION);
+ INSIST(result == ISC_R_SUCCESS);
+ name = NULL;
+ dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name);
+ nlabels = dns_name_countlabels(name);
+ if (nlabels == 1)
+ result = DNS_R_SERVFAIL; /* is there a better error? */
+ else {
+ dns_name_init(&tname, NULL);
+ dns_name_getlabelsequence(name, 1, nlabels - 1,
+ &tname);
+ dns_name_clone(&tname, name);
+ dns_request_destroy(&request);
+ LOCK(&uctx->lock);
+ uctx->soareq = NULL;
+ UNLOCK(&uctx->lock);
+ dns_message_renderreset(soaquery);
+ dns_message_settsigkey(soaquery, NULL);
+ result = dns_request_createvia3(uctx->view->requestmgr,
+ soaquery, NULL,
+ uctx->currentserver, 0,
+ uctx->tsigkey,
+ client->find_timeout *
+ 20,
+ client->find_timeout,
+ 3, client->task,
+ receive_soa, uctx,
+ &uctx->soareq);
+ }
+ }
+
+ if (!droplabel || result != ISC_R_SUCCESS) {
+ dns_message_destroy(&uctx->soaquery);
+ LOCK(&uctx->lock);
+ dns_request_destroy(&uctx->soareq);
+ UNLOCK(&uctx->lock);
+ }
+
+ if (rcvmsg != NULL)
+ dns_message_destroy(&rcvmsg);
+
+ if (result != ISC_R_SUCCESS)
+ update_sendevent(uctx, result);
+}
+
+static isc_result_t
+request_soa(updatectx_t *uctx) {
+ isc_result_t result;
+ dns_message_t *soaquery = uctx->soaquery;
+ dns_name_t *name = NULL;
+ dns_rdataset_t *rdataset = NULL;
+
+ if (soaquery == NULL) {
+ result = dns_message_create(uctx->client->mctx,
+ DNS_MESSAGE_INTENTRENDER,
+ &soaquery);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+ soaquery->flags |= DNS_MESSAGEFLAG_RD;
+ result = dns_message_gettempname(soaquery, &name);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ result = dns_message_gettemprdataset(soaquery, &rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_rdataset_makequestion(rdataset, uctx->rdclass, dns_rdatatype_soa);
+ dns_name_clone(uctx->firstname, name);
+ ISC_LIST_APPEND(name->list, rdataset, link);
+ dns_message_addname(soaquery, name, DNS_SECTION_QUESTION);
+ rdataset = NULL;
+ name = NULL;
+
+ result = dns_request_createvia3(uctx->view->requestmgr,
+ soaquery, NULL, uctx->currentserver, 0,
+ uctx->tsigkey,
+ uctx->client->find_timeout * 20,
+ uctx->client->find_timeout, 3,
+ uctx->client->task, receive_soa, uctx,
+ &uctx->soareq);
+ if (result == ISC_R_SUCCESS) {
+ uctx->soaquery = soaquery;
+ return (ISC_R_SUCCESS);
+ }
+
+ fail:
+ if (rdataset != NULL) {
+ ISC_LIST_UNLINK(name->list, rdataset, link); /* for safety */
+ dns_message_puttemprdataset(soaquery, &rdataset);
+ }
+ if (name != NULL)
+ dns_message_puttempname(soaquery, &name);
+ dns_message_destroy(&soaquery);
+
+ return (result);
+}
+
+static void
+resolvesoa_done(isc_task_t *task, isc_event_t *event) {
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ updatectx_t *uctx;
+ dns_name_t *name, tname;
+ dns_rdataset_t *rdataset = NULL;
+ isc_result_t result = rev->result;
+ unsigned int nlabels;
+
+ UNUSED(task);
+
+ uctx = event->ev_arg;
+ REQUIRE(UCTX_VALID(uctx));
+
+ LOCK(&uctx->lock);
+ dns_client_destroyrestrans(&uctx->restrans);
+ UNLOCK(&uctx->lock);
+
+ uctx = event->ev_arg;
+ if (result != ISC_R_SUCCESS &&
+ result != DNS_R_NCACHENXDOMAIN &&
+ result != DNS_R_NCACHENXRRSET) {
+ /* XXX: what about DNSSEC failure? */
+ goto out;
+ }
+
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (dns_rdataset_isassociated(rdataset) &&
+ rdataset->type == dns_rdatatype_soa)
+ break;
+ }
+ }
+
+ if (rdataset == NULL) {
+ /* Drop one label and retry resolution. */
+ nlabels = dns_name_countlabels(&uctx->soaqname);
+ if (nlabels == 1) {
+ result = DNS_R_SERVFAIL; /* is there a better error? */
+ goto out;
+ }
+ dns_name_init(&tname, NULL);
+ dns_name_getlabelsequence(&uctx->soaqname, 1, nlabels - 1,
+ &tname);
+ dns_name_clone(&tname, &uctx->soaqname);
+
+ result = dns_client_startresolve(uctx->client, &uctx->soaqname,
+ uctx->rdclass,
+ dns_rdatatype_soa, 0,
+ uctx->client->task,
+ resolvesoa_done, uctx,
+ &uctx->restrans);
+ } else
+ result = process_soa(uctx, rdataset, &uctx->soaqname);
+
+ out:
+ dns_client_freeresanswer(uctx->client, &rev->answerlist);
+ isc_event_free(&event);
+
+ if (result != ISC_R_SUCCESS)
+ update_sendevent(uctx, result);
+}
+
+static isc_result_t
+copy_name(isc_mem_t *mctx, dns_message_t *msg, dns_name_t *name,
+ dns_name_t **newnamep)
+{
+ isc_result_t result;
+ dns_name_t *newname = NULL;
+ isc_region_t r;
+ isc_buffer_t *namebuf = NULL, *rdatabuf = NULL;
+ dns_rdatalist_t *rdatalist;
+ dns_rdataset_t *rdataset, *newrdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT, *newrdata;
+
+ result = dns_message_gettempname(msg, &newname);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_buffer_allocate(mctx, &namebuf, DNS_NAME_MAXWIRE);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_name_init(newname, NULL);
+ dns_name_setbuffer(newname, namebuf);
+ dns_message_takebuffer(msg, &namebuf);
+ result = dns_name_copy(name, newname, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ rdatalist = NULL;
+ result = dns_message_gettemprdatalist(msg, &rdatalist);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_rdatalist_init(rdatalist);
+ rdatalist->type = rdataset->type;
+ rdatalist->rdclass = rdataset->rdclass;
+ rdatalist->covers = rdataset->covers;
+ rdatalist->ttl = rdataset->ttl;
+
+ result = dns_rdataset_first(rdataset);
+ while (result == ISC_R_SUCCESS) {
+ dns_rdata_reset(&rdata);
+ dns_rdataset_current(rdataset, &rdata);
+
+ newrdata = NULL;
+ result = dns_message_gettemprdata(msg, &newrdata);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_rdata_toregion(&rdata, &r);
+ rdatabuf = NULL;
+ result = isc_buffer_allocate(mctx, &rdatabuf,
+ r.length);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ isc_buffer_putmem(rdatabuf, r.base, r.length);
+ isc_buffer_usedregion(rdatabuf, &r);
+ dns_rdata_init(newrdata);
+ dns_rdata_fromregion(newrdata, rdata.rdclass,
+ rdata.type, &r);
+ newrdata->flags = rdata.flags;
+
+ ISC_LIST_APPEND(rdatalist->rdata, newrdata, link);
+ dns_message_takebuffer(msg, &rdatabuf);
+
+ result = dns_rdataset_next(rdataset);
+ }
+
+ newrdataset = NULL;
+ result = dns_message_gettemprdataset(msg, &newrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_rdataset_init(newrdataset);
+ dns_rdatalist_tordataset(rdatalist, newrdataset);
+
+ ISC_LIST_APPEND(newname->list, newrdataset, link);
+ }
+
+ *newnamep = newname;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ dns_message_puttempname(msg, &newname);
+
+ return (result);
+
+}
+
+static void
+internal_update_callback(isc_task_t *task, isc_event_t *event) {
+ updatearg_t *uarg = event->ev_arg;
+ dns_clientupdateevent_t *uev = (dns_clientupdateevent_t *)event;
+
+ UNUSED(task);
+
+ LOCK(&uarg->lock);
+
+ uarg->result = uev->result;
+
+ dns_client_destroyupdatetrans(&uarg->trans);
+ isc_event_free(&event);
+
+ if (!uarg->canceled) {
+ UNLOCK(&uarg->lock);
+
+ /* Exit from the internal event loop */
+ isc_app_ctxsuspend(uarg->actx);
+ } else {
+ /*
+ * We have already exited from the loop (due to some
+ * unexpected event). Just clean the arg up.
+ */
+ UNLOCK(&uarg->lock);
+ DESTROYLOCK(&uarg->lock);
+ isc_mem_put(uarg->client->mctx, uarg, sizeof(*uarg));
+ }
+}
+
+isc_result_t
+dns_client_update(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *zonename, dns_namelist_t *prerequisites,
+ dns_namelist_t *updates, isc_sockaddrlist_t *servers,
+ dns_tsec_t *tsec, unsigned int options)
+{
+ isc_result_t result;
+ isc_appctx_t *actx;
+ updatearg_t *uarg;
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+
+ if ((client->attributes & DNS_CLIENTATTR_OWNCTX) == 0 &&
+ (options & DNS_CLIENTRESOPT_ALLOWRUN) == 0) {
+ /*
+ * If the client is run under application's control, we need
+ * to create a new running (sub)environment for this
+ * particular resolution.
+ */
+ return (ISC_R_NOTIMPLEMENTED); /* XXXTBD */
+ } else
+ actx = client->actx;
+
+ uarg = isc_mem_get(client->mctx, sizeof(*uarg));
+ if (uarg == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&uarg->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(client->mctx, uarg, sizeof(*uarg));
+ return (result);
+ }
+
+ uarg->actx = actx;
+ uarg->client = client;
+ uarg->result = ISC_R_FAILURE;
+ uarg->trans = NULL;
+ uarg->canceled = ISC_FALSE;
+
+ result = dns_client_startupdate(client, rdclass, zonename,
+ prerequisites, updates, servers,
+ tsec, options, client->task,
+ internal_update_callback, uarg,
+ &uarg->trans);
+ if (result != ISC_R_SUCCESS) {
+ DESTROYLOCK(&uarg->lock);
+ isc_mem_put(client->mctx, uarg, sizeof(*uarg));
+ return (result);
+ }
+
+ /*
+ * Start internal event loop. It blocks until the entire process
+ * is completed.
+ */
+ result = isc_app_ctxrun(actx);
+
+ LOCK(&uarg->lock);
+ if (result == ISC_R_SUCCESS || result == ISC_R_SUSPEND)
+ result = uarg->result;
+
+ if (uarg->trans != NULL) {
+ /*
+ * Unusual termination (perhaps due to signal). We need some
+ * tricky cleanup process.
+ */
+ uarg->canceled = ISC_TRUE;
+ dns_client_cancelupdate(uarg->trans);
+
+ UNLOCK(&uarg->lock);
+
+ /* uarg will be freed in the event handler. */
+ } else {
+ UNLOCK(&uarg->lock);
+
+ DESTROYLOCK(&uarg->lock);
+ isc_mem_put(client->mctx, uarg, sizeof(*uarg));
+ }
+
+ return (result);
+}
+
+isc_result_t
+dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *zonename, dns_namelist_t *prerequisites,
+ dns_namelist_t *updates, isc_sockaddrlist_t *servers,
+ dns_tsec_t *tsec, unsigned int options,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
+ dns_clientupdatetrans_t **transp)
+{
+ dns_view_t *view = NULL;
+ isc_result_t result;
+ dns_name_t *name, *newname;
+ updatectx_t *uctx;
+ isc_task_t *clone = NULL;
+ dns_section_t section = DNS_SECTION_UPDATE;
+ isc_sockaddr_t *server, *sa = NULL;
+ dns_tsectype_t tsectype = dns_tsectype_none;
+
+ UNUSED(options);
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(transp != NULL && *transp == NULL);
+ REQUIRE(updates != NULL);
+ REQUIRE(task != NULL);
+
+ if (tsec != NULL) {
+ tsectype = dns_tsec_gettype(tsec);
+ if (tsectype != dns_tsectype_tsig)
+ return (ISC_R_NOTIMPLEMENTED); /* XXX */
+ }
+
+ LOCK(&client->lock);
+ result = dns_viewlist_find(&client->viewlist, DNS_CLIENTVIEW_NAME,
+ rdclass, &view);
+ UNLOCK(&client->lock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /* Create a context and prepare some resources */
+ uctx = isc_mem_get(client->mctx, sizeof(*uctx));
+ if (uctx == NULL) {
+ dns_view_detach(&view);
+ return (ISC_R_NOMEMORY);
+ }
+ result = isc_mutex_init(&uctx->lock);
+ if (result != ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ isc_mem_put(client->mctx, uctx, sizeof(*uctx));
+ return (ISC_R_NOMEMORY);
+ }
+ clone = NULL;
+ isc_task_attach(task, &clone);
+ uctx->client = client;
+ ISC_LINK_INIT(uctx, link);
+ uctx->state = dns_clientupdatestate_prepare;
+ uctx->view = view;
+ uctx->rdclass = rdclass;
+ uctx->canceled = ISC_FALSE;
+ uctx->updatemsg = NULL;
+ uctx->soaquery = NULL;
+ uctx->updatereq = NULL;
+ uctx->restrans = NULL;
+ uctx->restrans2 = NULL;
+ uctx->bp4 = NULL;
+ uctx->bp6 = NULL;
+ uctx->soareq = NULL;
+ uctx->event = NULL;
+ uctx->tsigkey = NULL;
+ uctx->sig0key = NULL;
+ uctx->zonename = NULL;
+ dns_name_init(&uctx->soaqname, NULL);
+ ISC_LIST_INIT(uctx->servers);
+ uctx->nservers = 0;
+ uctx->currentserver = NULL;
+ dns_fixedname_init(&uctx->zonefname);
+ if (tsec != NULL)
+ dns_tsec_getkey(tsec, &uctx->tsigkey);
+ uctx->event = (dns_clientupdateevent_t *)
+ isc_event_allocate(client->mctx, clone, DNS_EVENT_UPDATEDONE,
+ action, arg, sizeof(*uctx->event));
+ if (uctx->event == NULL)
+ goto fail;
+ if (zonename != NULL) {
+ uctx->zonename = dns_fixedname_name(&uctx->zonefname);
+ result = dns_name_copy(zonename, uctx->zonename, NULL);
+ }
+ if (servers != NULL) {
+ for (server = ISC_LIST_HEAD(*servers);
+ server != NULL;
+ server = ISC_LIST_NEXT(server, link)) {
+ sa = isc_mem_get(client->mctx, sizeof(*sa));
+ if (sa == NULL)
+ goto fail;
+ sa->type = server->type;
+ sa->length = server->length;
+ ISC_LINK_INIT(sa, link);
+ ISC_LIST_APPEND(uctx->servers, sa, link);
+ if (uctx->currentserver == NULL)
+ uctx->currentserver = sa;
+ uctx->nservers++;
+ }
+ }
+
+ /* Make update message */
+ result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTRENDER,
+ &uctx->updatemsg);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ uctx->updatemsg->opcode = dns_opcode_update;
+
+ if (prerequisites != NULL) {
+ for (name = ISC_LIST_HEAD(*prerequisites); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ newname = NULL;
+ result = copy_name(client->mctx, uctx->updatemsg,
+ name, &newname);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_message_addname(uctx->updatemsg, newname,
+ DNS_SECTION_PREREQUISITE);
+ }
+ }
+
+ for (name = ISC_LIST_HEAD(*updates); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ newname = NULL;
+ result = copy_name(client->mctx, uctx->updatemsg, name,
+ &newname);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_message_addname(uctx->updatemsg, newname,
+ DNS_SECTION_UPDATE);
+ }
+
+ uctx->firstname = NULL;
+ result = dns_message_firstname(uctx->updatemsg, section);
+ if (result == ISC_R_NOMORE) {
+ section = DNS_SECTION_PREREQUISITE;
+ result = dns_message_firstname(uctx->updatemsg, section);
+ }
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ dns_message_currentname(uctx->updatemsg, section, &uctx->firstname);
+
+ uctx->magic = UCTX_MAGIC;
+
+ LOCK(&client->lock);
+ ISC_LIST_APPEND(client->updatectxs, uctx, link);
+ UNLOCK(&client->lock);
+
+ if (uctx->zonename != NULL && uctx->currentserver != NULL) {
+ result = send_update(uctx);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ } else if (uctx->currentserver != NULL) {
+ result = request_soa(uctx);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ } else {
+ dns_name_clone(uctx->firstname, &uctx->soaqname);
+ result = dns_client_startresolve(uctx->client, &uctx->soaqname,
+ uctx->rdclass,
+ dns_rdatatype_soa, 0,
+ client->task, resolvesoa_done,
+ uctx, &uctx->restrans);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ }
+
+ *transp = (dns_clientupdatetrans_t *)uctx;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ if (ISC_LINK_LINKED(uctx, link)) {
+ LOCK(&client->lock);
+ ISC_LIST_UNLINK(client->updatectxs, uctx, link);
+ UNLOCK(&client->lock);
+ }
+ if (uctx->updatemsg != NULL)
+ dns_message_destroy(&uctx->updatemsg);
+ while ((sa = ISC_LIST_HEAD(uctx->servers)) != NULL) {
+ ISC_LIST_UNLINK(uctx->servers, sa, link);
+ isc_mem_put(client->mctx, sa, sizeof(*sa));
+ }
+ if (uctx->event != NULL)
+ isc_event_free(ISC_EVENT_PTR(&uctx->event));
+ if (uctx->tsigkey != NULL)
+ dns_tsigkey_detach(&uctx->tsigkey);
+ isc_task_detach(&clone);
+ DESTROYLOCK(&uctx->lock);
+ uctx->magic = 0;
+ isc_mem_put(client->mctx, uctx, sizeof(*uctx));
+ dns_view_detach(&view);
+
+ return (result);
+}
+
+void
+dns_client_cancelupdate(dns_clientupdatetrans_t *trans) {
+ updatectx_t *uctx;
+
+ REQUIRE(trans != NULL);
+ uctx = (updatectx_t *)trans;
+ REQUIRE(UCTX_VALID(uctx));
+
+ LOCK(&uctx->lock);
+
+ if (!uctx->canceled) {
+ uctx->canceled = ISC_TRUE;
+ if (uctx->updatereq != NULL)
+ dns_request_cancel(uctx->updatereq);
+ if (uctx->soareq != NULL)
+ dns_request_cancel(uctx->soareq);
+ if (uctx->restrans != NULL)
+ dns_client_cancelresolve(uctx->restrans);
+ if (uctx->restrans2 != NULL)
+ dns_client_cancelresolve(uctx->restrans2);
+ }
+
+ UNLOCK(&uctx->lock);
+}
+
+void
+dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp) {
+ updatectx_t *uctx;
+ isc_mem_t *mctx;
+ dns_client_t *client;
+ isc_boolean_t need_destroyclient = ISC_FALSE;
+ isc_sockaddr_t *sa;
+
+ REQUIRE(transp != NULL);
+ uctx = (updatectx_t *)*transp;
+ REQUIRE(UCTX_VALID(uctx));
+ client = uctx->client;
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(uctx->updatereq == NULL && uctx->updatemsg == NULL &&
+ uctx->soareq == NULL && uctx->soaquery == NULL &&
+ uctx->event == NULL && uctx->tsigkey == NULL &&
+ uctx->sig0key == NULL);
+
+ mctx = client->mctx;
+ dns_view_detach(&uctx->view);
+ while ((sa = ISC_LIST_HEAD(uctx->servers)) != NULL) {
+ ISC_LIST_UNLINK(uctx->servers, sa, link);
+ isc_mem_put(mctx, sa, sizeof(*sa));
+ }
+
+ LOCK(&client->lock);
+
+ INSIST(ISC_LINK_LINKED(uctx, link));
+ ISC_LIST_UNLINK(client->updatectxs, uctx, link);
+
+ if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
+ ISC_LIST_EMPTY(client->reqctxs) &&
+ ISC_LIST_EMPTY(client->updatectxs))
+ need_destroyclient = ISC_TRUE;
+
+ UNLOCK(&client->lock);
+
+ DESTROYLOCK(&uctx->lock);
+ uctx->magic = 0;
+
+ isc_mem_put(mctx, uctx, sizeof(*uctx));
+
+ if (need_destroyclient)
+ destroyclient(&client);
+
+ *transp = NULL;
+}
+
+isc_mem_t *
+dns_client_mctx(dns_client_t *client) {
+
+ REQUIRE(DNS_CLIENT_VALID(client));
+ return (client->mctx);
+}
+
+typedef struct {
+ isc_buffer_t buffer;
+ dns_rdataset_t rdataset;
+ dns_rdatalist_t rdatalist;
+ dns_rdata_t rdata;
+ size_t size;
+ isc_mem_t * mctx;
+ unsigned char data[FLEXIBLE_ARRAY_MEMBER];
+} dns_client_updaterec_t;
+
+isc_result_t
+dns_client_updaterec(dns_client_updateop_t op, dns_name_t *owner,
+ dns_rdatatype_t type, dns_rdata_t *source,
+ dns_ttl_t ttl, dns_name_t *target,
+ dns_rdataset_t *rdataset, dns_rdatalist_t *rdatalist,
+ dns_rdata_t *rdata, isc_mem_t *mctx)
+{
+ dns_client_updaterec_t *updaterec = NULL;
+ size_t size = offsetof(dns_client_updaterec_t, data);
+
+ REQUIRE(op < updateop_max);
+ REQUIRE(owner != NULL);
+ REQUIRE((rdataset != NULL && rdatalist != NULL && rdata != NULL) ||
+ (rdataset == NULL && rdatalist == NULL && rdata == NULL &&
+ mctx != NULL));
+ if (op == updateop_add)
+ REQUIRE(source != NULL);
+ if (source != NULL) {
+ REQUIRE(source->type == type);
+ REQUIRE(op == updateop_add || op == updateop_delete ||
+ op == updateop_exist);
+ }
+
+ size += owner->length;
+ if (source != NULL)
+ size += source->length;
+
+ if (rdataset == NULL) {
+ updaterec = isc_mem_get(mctx, size);
+ if (updaterec == NULL)
+ return (ISC_R_NOMEMORY);
+ rdataset = &updaterec->rdataset;
+ rdatalist = &updaterec->rdatalist;
+ rdata = &updaterec->rdata;
+ dns_rdataset_init(rdataset);
+ dns_rdatalist_init(&updaterec->rdatalist);
+ dns_rdata_init(&updaterec->rdata);
+ isc_buffer_init(&updaterec->buffer, updaterec->data,
+ size - offsetof(dns_client_updaterec_t, data));
+ dns_name_copy(owner, target, &updaterec->buffer);
+ if (source != NULL) {
+ isc_region_t r;
+ dns_rdata_clone(source, rdata);
+ dns_rdata_toregion(rdata, &r);
+ rdata->data = isc_buffer_used(&updaterec->buffer);
+ isc_buffer_copyregion(&updaterec->buffer, &r);
+ }
+ updaterec->mctx = NULL;
+ isc_mem_attach(mctx, &updaterec->mctx);
+ } else if (source != NULL)
+ dns_rdata_clone(source, rdata);
+
+ switch (op) {
+ case updateop_add:
+ break;
+ case updateop_delete:
+ if (source != NULL) {
+ ttl = 0;
+ dns_rdata_makedelete(rdata);
+ } else
+ dns_rdata_deleterrset(rdata, type);
+ break;
+ case updateop_notexist:
+ dns_rdata_notexist(rdata, type);
+ break;
+ case updateop_exist:
+ if (source == NULL) {
+ ttl = 0;
+ dns_rdata_exists(rdata, type);
+ }
+ case updateop_none:
+ break;
+ default:
+ INSIST(0);
+ }
+
+ rdatalist->type = rdata->type;
+ rdatalist->rdclass = rdata->rdclass;
+ if (source != NULL) {
+ rdatalist->covers = dns_rdata_covers(rdata);
+ rdatalist->ttl = ttl;
+ }
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ dns_rdatalist_tordataset(rdatalist, rdataset);
+ ISC_LIST_APPEND(target->list, rdataset, link);
+ if (updaterec != NULL) {
+ target->attributes |= DNS_NAMEATTR_HASUPDATEREC;
+ dns_name_setbuffer(target, &updaterec->buffer);
+ }
+ if (op == updateop_add || op == updateop_delete)
+ target->attributes |= DNS_NAMEATTR_UPDATE;
+ else
+ target->attributes |= DNS_NAMEATTR_PREREQUISITE;
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_client_freeupdate(dns_name_t **namep) {
+ dns_client_updaterec_t *updaterec;
+ dns_rdatalist_t *rdatalist;
+ dns_rdataset_t *rdataset;
+ dns_rdata_t *rdata;
+ dns_name_t *name;
+
+ REQUIRE(namep != NULL && *namep != NULL);
+
+ name = *namep;
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_HEAD(name->list)) {
+ ISC_LIST_UNLINK(name->list, rdataset, link);
+ rdatalist = NULL;
+ dns_rdatalist_fromrdataset(rdataset, &rdatalist);
+ if (rdatalist == NULL) {
+ dns_rdataset_disassociate(rdataset);
+ continue;
+ }
+ for (rdata = ISC_LIST_HEAD(rdatalist->rdata);
+ rdata != NULL;
+ rdata = ISC_LIST_HEAD(rdatalist->rdata))
+ ISC_LIST_UNLINK(rdatalist->rdata, rdata, link);
+ dns_rdataset_disassociate(rdataset);
+ }
+
+ if ((name->attributes & DNS_NAMEATTR_HASUPDATEREC) != 0) {
+ updaterec = (dns_client_updaterec_t *)name->buffer;
+ INSIST(updaterec != NULL);
+ isc_mem_putanddetach(&updaterec->mctx, updaterec,
+ updaterec->size);
+ *namep = NULL;
+ }
+}
diff --git a/lib/dns/db.c b/lib/dns/db.c
index f52f6744a547..c74d24df5b09 100644
--- a/lib/dns/db.c
+++ b/lib/dns/db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.c,v 1.88.50.2 2009-06-23 00:19:34 tbox Exp $ */
+/* $Id: db.c,v 1.97 2011-01-13 04:59:25 tbox Exp $ */
/*! \file */
@@ -34,10 +34,12 @@
#include <dns/callbacks.h>
#include <dns/db.h>
+#include <dns/dbiterator.h>
#include <dns/log.h>
#include <dns/master.h>
#include <dns/rdata.h>
#include <dns/rdataset.h>
+#include <dns/rdatasetiter.h>
#include <dns/result.h>
/***
@@ -61,14 +63,18 @@ struct dns_dbimplementation {
*/
#include "rbtdb.h"
+#ifdef BIND9
#include "rbtdb64.h"
+#endif
static ISC_LIST(dns_dbimplementation_t) implementations;
static isc_rwlock_t implock;
static isc_once_t once = ISC_ONCE_INIT;
static dns_dbimplementation_t rbtimp;
+#ifdef BIND9
static dns_dbimplementation_t rbt64imp;
+#endif
static void
initialize(void) {
@@ -80,15 +86,19 @@ initialize(void) {
rbtimp.driverarg = NULL;
ISC_LINK_INIT(&rbtimp, link);
+#ifdef BIND9
rbt64imp.name = "rbt64";
rbt64imp.create = dns_rbtdb64_create;
rbt64imp.mctx = NULL;
rbt64imp.driverarg = NULL;
ISC_LINK_INIT(&rbt64imp, link);
+#endif
ISC_LIST_INIT(implementations);
ISC_LIST_APPEND(implementations, &rbtimp, link);
+#ifdef BIND9
ISC_LIST_APPEND(implementations, &rbt64imp, link);
+#endif
}
static inline dns_dbimplementation_t *
@@ -290,6 +300,7 @@ dns_db_class(dns_db_t *db) {
return (db->rdclass);
}
+#ifdef BIND9
isc_result_t
dns_db_beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp,
dns_dbload_t **dbloadp) {
@@ -318,14 +329,19 @@ dns_db_endload(dns_db_t *db, dns_dbload_t **dbloadp) {
isc_result_t
dns_db_load(dns_db_t *db, const char *filename) {
- return (dns_db_load2(db, filename, dns_masterformat_text));
+ return (dns_db_load3(db, filename, dns_masterformat_text, 0));
}
isc_result_t
dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format) {
+ return (dns_db_load3(db, filename, format, 0));
+}
+
+isc_result_t
+dns_db_load3(dns_db_t *db, const char *filename, dns_masterformat_t format,
+ unsigned int options) {
isc_result_t result, eresult;
dns_rdatacallbacks_t callbacks;
- unsigned int options = 0;
/*
* Load master file 'filename' into 'db'.
@@ -376,6 +392,7 @@ dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename,
return ((db->methods->dump)(db, version, filename, masterformat));
}
+#endif /* BIND9 */
/***
*** Version Methods
@@ -921,8 +938,27 @@ dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name)
}
void
-dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version)
+dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset,
+ dns_dbversion_t *version)
{
if (db->methods->resigned != NULL)
(db->methods->resigned)(db, rdataset, version);
}
+
+void
+dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
+{
+ if (db->methods->rpz_enabled != NULL)
+ (db->methods->rpz_enabled)(db, st);
+}
+
+isc_result_t
+dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
+ dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
+ dns_rdataset_t *ardataset, dns_rpz_st_t *st)
+{
+ if (db->methods->rpz_findips == NULL)
+ return (ISC_R_NOTIMPLEMENTED);
+ return ((db->methods->rpz_findips)(rpz, rpz_type, zone, db, version,
+ ardataset, st));
+}
diff --git a/lib/dns/diff.c b/lib/dns/diff.c
index a92a4967919c..3dbb5cf6955a 100644
--- a/lib/dns/diff.c
+++ b/lib/dns/diff.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: diff.c,v 1.18.50.2 2009-01-05 23:47:22 tbox Exp $ */
+/* $Id: diff.c,v 1.23 2009-12-01 00:47:09 each Exp $ */
/*! \file */
@@ -387,10 +387,22 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
* from a server that is not as careful.
* Issue a warning and continue.
*/
- if (warn)
+ if (warn) {
+ char classbuf[DNS_RDATATYPE_FORMATSIZE];
+ char namebuf[DNS_NAME_FORMATSIZE];
+
+ dns_name_format(dns_db_origin(db),
+ namebuf,
+ sizeof(namebuf));
+ dns_rdataclass_format(dns_db_class(db),
+ classbuf,
+ sizeof(classbuf));
isc_log_write(DIFF_COMMON_LOGARGS,
ISC_LOG_WARNING,
- "update with no effect");
+ "%s/%s: dns_diff_apply: "
+ "update with no effect",
+ namebuf, classbuf);
+ }
} else if (result == DNS_R_NXRRSET) {
/*
* OK.
@@ -478,6 +490,7 @@ dns_diff_load(dns_diff_t *diff, dns_addrdatasetfunc_t addfunc,
if (result == DNS_R_UNCHANGED) {
isc_log_write(DIFF_COMMON_LOGARGS,
ISC_LOG_WARNING,
+ "dns_diff_load: "
"update with no effect");
} else if (result == ISC_R_SUCCESS ||
result == DNS_R_NXRRSET) {
diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index 632d349577ac..c07491129e46 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.c,v 1.155.12.11 2009-12-02 23:26:28 marka Exp $ */
+/* $Id: dispatch.c,v 1.168.248.1.2.1 2011-06-02 23:47:34 tbox Exp $ */
/*! \file */
@@ -417,7 +417,7 @@ request_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
/*%
* ARC4 random number generator derived from OpenBSD.
- * Only dispatch_arc4random() and dispatch_arc4uniformrandom() are expected
+ * Only dispatch_random() and dispatch_uniformrandom() are expected
* to be called from general dispatch routines; the rest of them are subroutines
* for these two.
*
@@ -437,8 +437,11 @@ request_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef BIND9
static void
-dispatch_arc4init(arc4ctx_t *actx, isc_entropy_t *entropy, isc_mutex_t *lock) {
+dispatch_initrandom(arc4ctx_t *actx, isc_entropy_t *entropy,
+ isc_mutex_t *lock)
+{
int n;
for (n = 0; n < 256; n++)
actx->s[n] = n;
@@ -527,7 +530,7 @@ dispatch_arc4stir(arc4ctx_t *actx) {
}
static isc_uint16_t
-dispatch_arc4random(arc4ctx_t *actx) {
+dispatch_random(arc4ctx_t *actx) {
isc_uint16_t result;
if (actx->lock != NULL)
@@ -543,9 +546,38 @@ dispatch_arc4random(arc4ctx_t *actx) {
return (result);
}
+#else
+/*
+ * For general purpose library, we don't have to be too strict about the
+ * quality of random values. Performance doesn't matter much, either.
+ * So we simply use the isc_random module to keep the library as small as
+ * possible.
+ */
+
+static void
+dispatch_initrandom(arc4ctx_t *actx, isc_entropy_t *entropy,
+ isc_mutex_t *lock)
+{
+ UNUSED(actx);
+ UNUSED(entropy);
+ UNUSED(lock);
+
+ return;
+}
static isc_uint16_t
-dispatch_arc4uniformrandom(arc4ctx_t *actx, isc_uint16_t upper_bound) {
+dispatch_random(arc4ctx_t *actx) {
+ isc_uint32_t r;
+
+ UNUSED(actx);
+
+ isc_random_get(&r);
+ return (r & 0xffff);
+}
+#endif /* BIND9 */
+
+static isc_uint16_t
+dispatch_uniformrandom(arc4ctx_t *actx, isc_uint16_t upper_bound) {
isc_uint16_t min, r;
if (upper_bound < 2)
@@ -568,7 +600,7 @@ dispatch_arc4uniformrandom(arc4ctx_t *actx, isc_uint16_t upper_bound) {
* to re-roll.
*/
for (;;) {
- r = dispatch_arc4random(actx);
+ r = dispatch_random(actx);
if (r >= min)
break;
}
@@ -859,7 +891,7 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
*/
localaddr = disp->local;
for (i = 0; i < 64; i++) {
- port = ports[dispatch_arc4uniformrandom(DISP_ARC4CTX(disp),
+ port = ports[dispatch_uniformrandom(DISP_ARC4CTX(disp),
nports)];
isc_sockaddr_setport(&localaddr, port);
@@ -964,6 +996,7 @@ deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
INSIST(dispsock->portentry != NULL);
deref_portentry(disp, &dispsock->portentry);
+#ifdef BIND9
if (disp->nsockets > DNS_DISPATCH_POOLSOCKS)
destroy_dispsocket(disp, &dispsock);
else {
@@ -987,6 +1020,13 @@ deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
destroy_dispsocket(disp, &dispsock);
}
}
+#else
+ /* This kind of optimization isn't necessary for normal use */
+ UNUSED(qid);
+ UNUSED(result);
+
+ destroy_dispsocket(disp, &dispsock);
+#endif
}
/*
@@ -1707,13 +1747,17 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) {
isc_mempool_destroy(&mgr->epool);
isc_mempool_destroy(&mgr->rpool);
isc_mempool_destroy(&mgr->dpool);
- isc_mempool_destroy(&mgr->bpool);
- isc_mempool_destroy(&mgr->spool);
+ if (mgr->bpool != NULL)
+ isc_mempool_destroy(&mgr->bpool);
+ if (mgr->spool != NULL)
+ isc_mempool_destroy(&mgr->spool);
DESTROYLOCK(&mgr->pool_lock);
+#ifdef BIND9
if (mgr->entropy != NULL)
isc_entropy_detach(&mgr->entropy);
+#endif /* BIND9 */
if (mgr->qid != NULL)
qid_destroy(mctx, &mgr->qid);
@@ -1752,9 +1796,13 @@ open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
return (result);
isc_socket_setname(sock, "dispatcher", NULL);
} else {
+#ifdef BIND9
result = isc_socket_open(sock);
if (result != ISC_R_SUCCESS)
return (result);
+#else
+ INSIST(0);
+#endif
}
#ifndef ISC_ALLOW_MAPPED
@@ -1764,8 +1812,13 @@ open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
if (result != ISC_R_SUCCESS) {
if (*sockp == NULL)
isc_socket_detach(&sock);
- else
+ else {
+#ifdef BIND9
isc_socket_close(sock);
+#else
+ INSIST(0);
+#endif
+ }
return (result);
}
@@ -1897,10 +1950,14 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
if (result != ISC_R_SUCCESS)
goto kill_dpool;
+#ifdef BIND9
if (entropy != NULL)
isc_entropy_attach(entropy, &mgr->entropy);
+#else
+ UNUSED(entropy);
+#endif
- dispatch_arc4init(&mgr->arc4ctx, mgr->entropy, &mgr->arc4_lock);
+ dispatch_initrandom(&mgr->arc4ctx, mgr->entropy, &mgr->arc4_lock);
*mgrp = mgr;
return (ISC_R_SUCCESS);
@@ -2411,7 +2468,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
ISC_LIST_INIT(disp->activesockets);
ISC_LIST_INIT(disp->inactivesockets);
disp->nsockets = 0;
- dispatch_arc4init(&disp->arc4ctx, mgr->entropy, NULL);
+ dispatch_initrandom(&disp->arc4ctx, mgr->entropy, NULL);
disp->port_table = NULL;
disp->portpool = NULL;
@@ -2708,7 +2765,7 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
for (i = 0; i < 1024; i++) {
in_port_t prt;
- prt = ports[dispatch_arc4uniformrandom(
+ prt = ports[dispatch_uniformrandom(
DISP_ARC4CTX(disp),
nports)];
isc_sockaddr_setport(&localaddr_bound, prt);
@@ -2844,8 +2901,10 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
disp->task[i] = NULL;
result = isc_task_create(taskmgr, 0, &disp->task[i]);
if (result != ISC_R_SUCCESS) {
- while (--i >= 0)
- isc_task_destroy(&disp->task[i]);
+ while (--i >= 0) {
+ isc_task_shutdown(disp->task[i]);
+ isc_task_detach(&disp->task[i]);
+ }
goto kill_socket;
}
isc_task_setname(disp->task[i], "udpdispatch", disp);
@@ -3045,7 +3104,7 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
/*
* Try somewhat hard to find an unique ID.
*/
- id = (dns_messageid_t)dispatch_arc4random(DISP_ARC4CTX(disp));
+ id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp));
bucket = dns_hash(qid, dest, id, localport);
ok = ISC_FALSE;
for (i = 0; i < 64; i++) {
diff --git a/lib/dns/dlz.c b/lib/dns/dlz.c
index f8482308b445..5a508e9c4bf6 100644
--- a/lib/dns/dlz.c
+++ b/lib/dns/dlz.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dlz.c,v 1.5.332.2 2009-01-18 23:47:35 tbox Exp $ */
+/* $Id: dlz.c,v 1.10 2010-12-20 23:47:20 tbox Exp $ */
/*! \file */
@@ -64,6 +64,8 @@
#include <dns/log.h>
#include <dns/master.h>
#include <dns/dlz.h>
+#include <dns/ssu.h>
+#include <dns/zone.h>
#include <isc/buffer.h>
@@ -230,6 +232,12 @@ dns_dlzdestroy(dns_dlzdb_t **dbp) {
*/
REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp));
+#ifdef BIND9
+ if ((*dbp)->ssutable != NULL) {
+ dns_ssutable_detach(&(*dbp)->ssutable);
+ }
+#endif
+
/* call the drivers destroy method */
if ((*dbp) != NULL) {
mctx = (*dbp)->mctx;
@@ -499,7 +507,7 @@ dns_dlzunregister(dns_dlzimplementation_t **dlzimp) {
mctx = dlz_imp->mctx;
/*
- * return the memory back to the available memory pool and
+ * Return the memory back to the available memory pool and
* remove it from the memory context.
*/
isc_mem_put(mctx, dlz_imp, sizeof(dns_dlzimplementation_t));
@@ -508,3 +516,143 @@ dns_dlzunregister(dns_dlzimplementation_t **dlzimp) {
/* Unlock the dlz_implementations list. */
RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
}
+
+#ifdef BIND9
+/*
+ * Create a writeable DLZ zone. This can be called by DLZ drivers
+ * during configure() to create a zone that can be updated. The zone
+ * type is set to dns_zone_dlz, which is equivalent to a master zone
+ *
+ * This function uses a callback setup in dns_dlzconfigure() to call
+ * into the server zone code to setup the remaining pieces of server
+ * specific functionality on the zone
+ */
+isc_result_t
+dns_dlz_writeablezone(dns_view_t *view, const char *zone_name) {
+ dns_zone_t *zone = NULL;
+ dns_zone_t *dupzone = NULL;
+ isc_result_t result;
+ isc_buffer_t buffer;
+ dns_fixedname_t fixorigin;
+ dns_name_t *origin;
+ dns_rdataclass_t zclass;
+ dns_dlzdb_t *dlzdatabase;
+
+ REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
+
+ dlzdatabase = view->dlzdatabase;
+
+ REQUIRE(dlzdatabase->configure_callback != NULL);
+
+ isc_buffer_init(&buffer, zone_name, strlen(zone_name));
+ isc_buffer_add(&buffer, strlen(zone_name));
+ dns_fixedname_init(&fixorigin);
+ result = dns_name_fromtext(dns_fixedname_name(&fixorigin),
+ &buffer, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ origin = dns_fixedname_name(&fixorigin);
+
+ zclass = view->rdclass;
+
+ /* See if the zone already exists */
+ result = dns_view_findzone(view, origin, &dupzone);
+ if (result == ISC_R_SUCCESS) {
+ dns_zone_detach(&dupzone);
+ result = ISC_R_EXISTS;
+ goto cleanup;
+ }
+ INSIST(dupzone == NULL);
+
+ /* Create it */
+ result = dns_zone_create(&zone, view->mctx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_zone_setorigin(zone, origin);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_zone_setview(zone, view);
+
+ dns_zone_setadded(zone, ISC_TRUE);
+
+ if (dlzdatabase->ssutable == NULL) {
+ result = dns_ssutable_createdlz(dlzdatabase->mctx,
+ &dlzdatabase->ssutable,
+ view->dlzdatabase);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+ dns_zone_setssutable(zone, dlzdatabase->ssutable);
+
+ result = dlzdatabase->configure_callback(view, zone);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /*
+ * Add the zone to its view in the new view list.
+ */
+ result = dns_view_addzone(view, zone);
+
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+
+ return (result);
+}
+#endif
+
+/*%
+ * Configure a DLZ driver. This is optional, and if supplied gives
+ * the backend an opportunity to configure parameters related to DLZ.
+ */
+isc_result_t
+dns_dlzconfigure(dns_view_t *view, isc_result_t (*callback)(dns_view_t *,
+ dns_zone_t *))
+{
+ dns_dlzimplementation_t *impl;
+ dns_dlzdb_t *dlzdatabase;
+ isc_result_t result;
+
+ REQUIRE(view != NULL);
+ REQUIRE(DNS_DLZ_VALID(view->dlzdatabase));
+ REQUIRE(view->dlzdatabase->implementation != NULL);
+
+ dlzdatabase = view->dlzdatabase;
+ impl = dlzdatabase->implementation;
+
+ if (impl->methods->configure == NULL)
+ return (ISC_R_SUCCESS);
+
+ dlzdatabase->configure_callback = callback;
+
+ result = impl->methods->configure(impl->driverarg,
+ dlzdatabase->dbdata, view);
+ return (result);
+}
+
+isc_boolean_t
+dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase,
+ dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr,
+ dns_rdatatype_t type, const dst_key_t *key)
+{
+ dns_dlzimplementation_t *impl;
+ isc_boolean_t r;
+
+ REQUIRE(dlzdatabase != NULL);
+ REQUIRE(dlzdatabase->implementation != NULL);
+ REQUIRE(dlzdatabase->implementation->methods != NULL);
+ impl = dlzdatabase->implementation;
+
+ if (impl->methods->ssumatch == NULL) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
+ "No ssumatch method for DLZ database");
+ return (ISC_FALSE);
+ }
+
+ r = impl->methods->ssumatch(signer, name, tcpaddr, type, key,
+ impl->driverarg, dlzdatabase->dbdata);
+ return (r);
+}
diff --git a/lib/dns/dns64.c b/lib/dns/dns64.c
new file mode 100644
index 000000000000..180c0a9bf150
--- /dev/null
+++ b/lib/dns/dns64.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: dns64.c,v 1.6 2010-12-09 04:59:09 marka Exp $ */
+
+#include <config.h>
+
+#include <isc/list.h>
+#include <isc/mem.h>
+#include <isc/netaddr.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/acl.h>
+#include <dns/dns64.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/result.h>
+
+struct dns_dns64 {
+ unsigned char bits[16]; /*
+ * Prefix + suffix bits.
+ */
+ dns_acl_t * clients; /*
+ * Which clients get mapped
+ * addresses.
+ */
+ dns_acl_t * mapped; /*
+ * IPv4 addresses to be mapped.
+ */
+ dns_acl_t * excluded; /*
+ * IPv6 addresses that are
+ * treated as not existing.
+ */
+ unsigned int prefixlen; /*
+ * Start of mapped address.
+ */
+ unsigned int flags;
+ isc_mem_t * mctx;
+ ISC_LINK(dns_dns64_t) link;
+};
+
+isc_result_t
+dns_dns64_create(isc_mem_t *mctx, isc_netaddr_t *prefix,
+ unsigned int prefixlen, isc_netaddr_t *suffix,
+ dns_acl_t *clients, dns_acl_t *mapped, dns_acl_t *excluded,
+ unsigned int flags, dns_dns64_t **dns64)
+{
+ dns_dns64_t *new;
+ unsigned int nbytes = 16;
+
+ REQUIRE(prefix != NULL && prefix->family == AF_INET6);
+ /* Legal prefix lengths from draft-ietf-behave-address-format-04. */
+ REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 ||
+ prefixlen == 56 || prefixlen == 64 || prefixlen == 96);
+ REQUIRE(isc_netaddr_prefixok(prefix, prefixlen) == ISC_R_SUCCESS);
+ REQUIRE(dns64 != NULL && *dns64 == NULL);
+
+ if (suffix != NULL) {
+ static const unsigned char zeros[16];
+ REQUIRE(prefix->family == AF_INET6);
+ nbytes = prefixlen / 8 + 4;
+ /* Bits 64-71 are zeros. draft-ietf-behave-address-format-04 */
+ if (prefixlen >= 32 && prefixlen <= 64)
+ nbytes++;
+ REQUIRE(memcmp(suffix->type.in6.s6_addr, zeros, nbytes) == 0);
+ }
+
+ new = isc_mem_get(mctx, sizeof(dns_dns64_t));
+ if (new == NULL)
+ return (ISC_R_NOMEMORY);
+ memset(new->bits, 0, sizeof(new->bits));
+ memcpy(new->bits, prefix->type.in6.s6_addr, prefixlen / 8);
+ if (suffix != NULL)
+ memcpy(new->bits + nbytes, suffix->type.in6.s6_addr + nbytes,
+ 16 - nbytes);
+ new->clients = NULL;
+ if (clients != NULL)
+ dns_acl_attach(clients, &new->clients);
+ new->mapped = NULL;
+ if (mapped != NULL)
+ dns_acl_attach(mapped, &new->mapped);
+ new->excluded = NULL;
+ if (excluded != NULL)
+ dns_acl_attach(excluded, &new->excluded);
+ new->prefixlen = prefixlen;
+ new->flags = flags;
+ ISC_LINK_INIT(new, link);
+ new->mctx = NULL;
+ isc_mem_attach(mctx, &new->mctx);
+ *dns64 = new;
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_dns64_destroy(dns_dns64_t **dns64p) {
+ dns_dns64_t *dns64;
+
+ REQUIRE(dns64p != NULL && *dns64p != NULL);
+
+ dns64 = *dns64p;
+ *dns64p = NULL;
+
+ REQUIRE(!ISC_LINK_LINKED(dns64, link));
+
+ if (dns64->clients != NULL)
+ dns_acl_detach(&dns64->clients);
+ if (dns64->mapped != NULL)
+ dns_acl_detach(&dns64->mapped);
+ if (dns64->excluded != NULL)
+ dns_acl_detach(&dns64->excluded);
+ isc_mem_putanddetach(&dns64->mctx, dns64, sizeof(*dns64));
+}
+
+isc_result_t
+dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
+ const dns_name_t *reqsigner, const dns_aclenv_t *env,
+ unsigned int flags, unsigned char *a, unsigned char *aaaa)
+{
+ unsigned int nbytes, i;
+ isc_result_t result;
+ int match;
+
+ if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 &&
+ (flags & DNS_DNS64_RECURSIVE) == 0)
+ return (DNS_R_DISALLOWED);
+
+ if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 &&
+ (flags & DNS_DNS64_DNSSEC) != 0)
+ return (DNS_R_DISALLOWED);
+
+ if (dns64->clients != NULL) {
+ result = dns_acl_match(reqaddr, reqsigner, dns64->clients, env,
+ &match, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ if (match <= 0)
+ return (DNS_R_DISALLOWED);
+ }
+
+ if (dns64->mapped != NULL) {
+ struct in_addr ina;
+ isc_netaddr_t netaddr;
+
+ memcpy(&ina.s_addr, a, 4);
+ isc_netaddr_fromin(&netaddr, &ina);
+ result = dns_acl_match(&netaddr, NULL, dns64->mapped, env,
+ &match, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ if (match <= 0)
+ return (DNS_R_DISALLOWED);
+ }
+
+ nbytes = dns64->prefixlen / 8;
+ INSIST(nbytes <= 12);
+ /* Copy prefix. */
+ memcpy(aaaa, dns64->bits, nbytes);
+ /* Bits 64-71 are zeros. draft-ietf-behave-address-format-04 */
+ if (nbytes == 8)
+ aaaa[nbytes++] = 0;
+ /* Copy mapped address. */
+ for (i = 0; i < 4U; i++) {
+ aaaa[nbytes++] = a[i];
+ /* Bits 64-71 are zeros. draft-ietf-behave-address-format-04 */
+ if (nbytes == 8)
+ aaaa[nbytes++] = 0;
+ }
+ /* Copy suffix. */
+ memcpy(aaaa + nbytes, dns64->bits + nbytes, 16 - nbytes);
+ return (ISC_R_SUCCESS);
+}
+
+dns_dns64_t *
+dns_dns64_next(dns_dns64_t *dns64) {
+ dns64 = ISC_LIST_NEXT(dns64, link);
+ return (dns64);
+}
+
+void
+dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64) {
+ ISC_LIST_APPEND(*list, dns64, link);
+}
+
+void
+dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64) {
+ ISC_LIST_UNLINK(*list, dns64, link);
+}
+
+isc_boolean_t
+dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
+ const dns_name_t *reqsigner, const dns_aclenv_t *env,
+ unsigned int flags, dns_rdataset_t *rdataset,
+ isc_boolean_t *aaaaok, size_t aaaaoklen)
+{
+ struct in6_addr in6;
+ isc_netaddr_t netaddr;
+ isc_result_t result;
+ int match;
+ isc_boolean_t answer = ISC_FALSE;
+ isc_boolean_t found = ISC_FALSE;
+ unsigned int i, ok;
+
+ REQUIRE(rdataset != NULL);
+ REQUIRE(rdataset->type == dns_rdatatype_aaaa);
+ REQUIRE(rdataset->rdclass == dns_rdataclass_in);
+ if (aaaaok != NULL)
+ REQUIRE(aaaaoklen == dns_rdataset_count(rdataset));
+
+ for (;dns64 != NULL; dns64 = ISC_LIST_NEXT(dns64, link)) {
+ if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 &&
+ (flags & DNS_DNS64_RECURSIVE) == 0)
+ continue;
+
+ if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 &&
+ (flags & DNS_DNS64_DNSSEC) != 0)
+ continue;
+ /*
+ * Work out if this dns64 structure applies to this client.
+ */
+ if (dns64->clients != NULL) {
+ result = dns_acl_match(reqaddr, reqsigner,
+ dns64->clients, env,
+ &match, NULL);
+ if (result != ISC_R_SUCCESS)
+ continue;
+ if (match <= 0)
+ continue;
+ }
+
+ if (!found && aaaaok != NULL) {
+ for (i = 0; i < aaaaoklen; i++)
+ aaaaok[i] = ISC_FALSE;
+ }
+ found = ISC_TRUE;
+
+ /*
+ * If we are not excluding any addresses then any AAAA
+ * will do.
+ */
+ if (dns64->excluded == NULL) {
+ answer = ISC_TRUE;
+ for (i = 0; i < aaaaoklen; i++)
+ aaaaok[i] = ISC_TRUE;
+ goto done;
+ }
+
+ i = 0; ok = 0;
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ if (aaaaok == NULL || !aaaaok[i]) {
+
+ dns_rdataset_current(rdataset, &rdata);
+ memcpy(&in6.s6_addr, rdata.data, 16);
+ isc_netaddr_fromin6(&netaddr, &in6);
+
+ result = dns_acl_match(&netaddr, NULL,
+ dns64->excluded,
+ env, &match, NULL);
+ if (result == ISC_R_SUCCESS && match <= 0) {
+ answer = ISC_TRUE;
+ if (aaaaok == NULL)
+ goto done;
+ aaaaok[i] = ISC_TRUE;
+ ok++;
+ }
+ } else
+ ok++;
+ i++;
+ }
+ /*
+ * Are all addresses ok?
+ */
+ if (aaaaok != NULL && ok == aaaaoklen)
+ goto done;
+ }
+
+ done:
+ if (!found && aaaaok != NULL) {
+ for (i = 0; i < aaaaoklen; i++)
+ aaaaok[i] = ISC_TRUE;
+ }
+ return (found ? answer : ISC_TRUE);
+}
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index 67a2c6784598..dc249b73266f 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,7 +16,7 @@
*/
/*
- * $Id: dnssec.c,v 1.93.12.6 2009-06-22 23:47:18 tbox Exp $
+ * $Id: dnssec.c,v 1.119 2010-01-13 23:48:59 tbox Exp $
*/
/*! \file */
@@ -26,15 +26,18 @@
#include <stdlib.h>
#include <isc/buffer.h>
+#include <isc/dir.h>
#include <isc/mem.h>
#include <isc/serial.h>
#include <isc/string.h>
#include <isc/util.h>
#include <dns/db.h>
+#include <dns/diff.h>
#include <dns/dnssec.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
+#include <dns/log.h>
#include <dns/message.h>
#include <dns/rdata.h>
#include <dns/rdatalist.h>
@@ -539,6 +542,59 @@ dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
return (result);
}
+static isc_boolean_t
+key_active(dst_key_t *key) {
+ isc_result_t result;
+ isc_stdtime_t now, publish, active, revoke, inactive, delete;
+ isc_boolean_t pubset = ISC_FALSE, actset = ISC_FALSE;
+ isc_boolean_t revset = ISC_FALSE, inactset = ISC_FALSE;
+ isc_boolean_t delset = ISC_FALSE;
+ int major, minor;
+
+ /* Is this an old-style key? */
+ result = dst_key_getprivateformat(key, &major, &minor);
+
+ /*
+ * Smart signing started with key format 1.3; prior to that, all
+ * keys are assumed active
+ */
+ if (major == 1 && minor <= 2)
+ return (ISC_TRUE);
+
+ isc_stdtime_get(&now);
+
+ result = dst_key_gettime(key, DST_TIME_PUBLISH, &publish);
+ if (result == ISC_R_SUCCESS)
+ pubset = ISC_TRUE;
+
+ result = dst_key_gettime(key, DST_TIME_ACTIVATE, &active);
+ if (result == ISC_R_SUCCESS)
+ actset = ISC_TRUE;
+
+ result = dst_key_gettime(key, DST_TIME_REVOKE, &revoke);
+ if (result == ISC_R_SUCCESS)
+ revset = ISC_TRUE;
+
+ result = dst_key_gettime(key, DST_TIME_INACTIVE, &inactive);
+ if (result == ISC_R_SUCCESS)
+ inactset = ISC_TRUE;
+
+ result = dst_key_gettime(key, DST_TIME_DELETE, &delete);
+ if (result == ISC_R_SUCCESS)
+ delset = ISC_TRUE;
+
+ if ((inactset && inactive <= now) || (delset && delete <= now))
+ return (ISC_FALSE);
+
+ if (revset && revoke <= now && pubset && publish <= now)
+ return (ISC_TRUE);
+
+ if (actset && active <= now)
+ return (ISC_TRUE);
+
+ return (ISC_FALSE);
+}
+
#define is_zone_key(key) ((dst_key_flags(key) & DNS_KEYFLAG_OWNERMASK) \
== DNS_KEYOWNER_ZONE)
@@ -580,14 +636,70 @@ dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver,
DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
directory,
mctx, &keys[count]);
+
+ /*
+ * If the key was revoked and the private file
+ * doesn't exist, maybe it was revoked internally
+ * by named. Try loading the unrevoked version.
+ */
if (result == ISC_R_FILENOTFOUND) {
+ isc_uint32_t flags;
+ flags = dst_key_flags(pubkey);
+ if ((flags & DNS_KEYFLAG_REVOKE) != 0) {
+ dst_key_setflags(pubkey,
+ flags & ~DNS_KEYFLAG_REVOKE);
+ result = dst_key_fromfile(dst_key_name(pubkey),
+ dst_key_id(pubkey),
+ dst_key_alg(pubkey),
+ DST_TYPE_PUBLIC|
+ DST_TYPE_PRIVATE,
+ directory,
+ mctx, &keys[count]);
+ if (result == ISC_R_SUCCESS &&
+ dst_key_pubcompare(pubkey, keys[count],
+ ISC_FALSE)) {
+ dst_key_setflags(keys[count], flags);
+ }
+ dst_key_setflags(pubkey, flags);
+ }
+ }
+
+ if (result != ISC_R_SUCCESS) {
+ char keybuf[DNS_NAME_FORMATSIZE];
+ char algbuf[DNS_SECALG_FORMATSIZE];
+ dns_name_format(dst_key_name(pubkey), keybuf,
+ sizeof(keybuf));
+ dns_secalg_format(dst_key_alg(pubkey), algbuf,
+ sizeof(algbuf));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING,
+ "dns_dnssec_findzonekeys2: error "
+ "reading private key file %s/%s/%d: %s",
+ keybuf, algbuf, dst_key_id(pubkey),
+ isc_result_totext(result));
+ }
+
+ if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) {
keys[count] = pubkey;
pubkey = NULL;
count++;
goto next;
}
+
if (result != ISC_R_SUCCESS)
goto failure;
+
+ /*
+ * If a key is marked inactive, skip it
+ */
+ if (!key_active(keys[count])) {
+ dst_key_free(&keys[count]);
+ keys[count] = pubkey;
+ pubkey = NULL;
+ count++;
+ goto next;
+ }
+
if ((dst_key_flags(keys[count]) & DNS_KEYTYPE_NOAUTH) != 0) {
/* We should never get here. */
dst_key_free(&keys[count]);
@@ -951,3 +1063,691 @@ dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
dst_key_free(&dstkey);
return (ISC_FALSE);
}
+
+isc_result_t
+dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey,
+ dns_dnsseckey_t **dkp)
+{
+ isc_result_t result;
+ dns_dnsseckey_t *dk;
+ int major, minor;
+
+ REQUIRE(dkp != NULL && *dkp == NULL);
+ dk = isc_mem_get(mctx, sizeof(dns_dnsseckey_t));
+ if (dk == NULL)
+ return (ISC_R_NOMEMORY);
+
+ dk->key = *dstkey;
+ *dstkey = NULL;
+ dk->force_publish = ISC_FALSE;
+ dk->force_sign = ISC_FALSE;
+ dk->hint_publish = ISC_FALSE;
+ dk->hint_sign = ISC_FALSE;
+ dk->hint_remove = ISC_FALSE;
+ dk->first_sign = ISC_FALSE;
+ dk->is_active = ISC_FALSE;
+ dk->prepublish = 0;
+ dk->source = dns_keysource_unknown;
+ dk->index = 0;
+
+ /* KSK or ZSK? */
+ dk->ksk = ISC_TF((dst_key_flags(dk->key) & DNS_KEYFLAG_KSK) != 0);
+
+ /* Is this an old-style key? */
+ result = dst_key_getprivateformat(dk->key, &major, &minor);
+
+ /* Smart signing started with key format 1.3 */
+ dk->legacy = ISC_TF(major == 1 && minor <= 2);
+
+ ISC_LINK_INIT(dk, link);
+ *dkp = dk;
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp) {
+ dns_dnsseckey_t *dk;
+
+ REQUIRE(dkp != NULL && *dkp != NULL);
+ dk = *dkp;
+ if (dk->key != NULL)
+ dst_key_free(&dk->key);
+ isc_mem_put(mctx, dk, sizeof(dns_dnsseckey_t));
+ *dkp = NULL;
+}
+
+static void
+get_hints(dns_dnsseckey_t *key) {
+ isc_result_t result;
+ isc_stdtime_t now, publish, active, revoke, inactive, delete;
+ isc_boolean_t pubset = ISC_FALSE, actset = ISC_FALSE;
+ isc_boolean_t revset = ISC_FALSE, inactset = ISC_FALSE;
+ isc_boolean_t delset = ISC_FALSE;
+
+ REQUIRE(key != NULL && key->key != NULL);
+
+ isc_stdtime_get(&now);
+
+ result = dst_key_gettime(key->key, DST_TIME_PUBLISH, &publish);
+ if (result == ISC_R_SUCCESS)
+ pubset = ISC_TRUE;
+
+ result = dst_key_gettime(key->key, DST_TIME_ACTIVATE, &active);
+ if (result == ISC_R_SUCCESS)
+ actset = ISC_TRUE;
+
+ result = dst_key_gettime(key->key, DST_TIME_REVOKE, &revoke);
+ if (result == ISC_R_SUCCESS)
+ revset = ISC_TRUE;
+
+ result = dst_key_gettime(key->key, DST_TIME_INACTIVE, &inactive);
+ if (result == ISC_R_SUCCESS)
+ inactset = ISC_TRUE;
+
+ result = dst_key_gettime(key->key, DST_TIME_DELETE, &delete);
+ if (result == ISC_R_SUCCESS)
+ delset = ISC_TRUE;
+
+ /* Metadata says publish (but possibly not activate) */
+ if (pubset && publish <= now)
+ key->hint_publish = ISC_TRUE;
+
+ /* Metadata says activate (so we must also publish) */
+ if (actset && active <= now) {
+ key->hint_sign = ISC_TRUE;
+ key->hint_publish = ISC_TRUE;
+ }
+
+ /*
+ * Activation date is set (maybe in the future), but
+ * publication date isn't. Most likely the user wants to
+ * publish now and activate later.
+ */
+ if (actset && !pubset)
+ key->hint_publish = ISC_TRUE;
+
+ /*
+ * If activation date is in the future, make note of how far off
+ */
+ if (key->hint_publish && actset && active > now) {
+ key->prepublish = active - now;
+ }
+
+ /*
+ * Key has been marked inactive: we can continue publishing,
+ * but don't sign.
+ */
+ if (key->hint_publish && inactset && inactive <= now) {
+ key->hint_sign = ISC_FALSE;
+ }
+
+ /*
+ * Metadata says revoke. If the key is published,
+ * we *have to* sign with it per RFC5011--even if it was
+ * not active before.
+ *
+ * If it hasn't already been done, we should also revoke it now.
+ */
+ if (key->hint_publish && (revset && revoke <= now)) {
+ isc_uint32_t flags;
+ key->hint_sign = ISC_TRUE;
+ flags = dst_key_flags(key->key);
+ if ((flags & DNS_KEYFLAG_REVOKE) == 0) {
+ flags |= DNS_KEYFLAG_REVOKE;
+ dst_key_setflags(key->key, flags);
+ }
+ }
+
+ /*
+ * Metadata says delete, so don't publish this key or sign with it.
+ */
+ if (delset && delete <= now) {
+ key->hint_publish = ISC_FALSE;
+ key->hint_sign = ISC_FALSE;
+ key->hint_remove = ISC_TRUE;
+ }
+}
+
+/*%
+ * Get a list of DNSSEC keys from the key repository
+ */
+isc_result_t
+dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory,
+ isc_mem_t *mctx, dns_dnsseckeylist_t *keylist)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_boolean_t dir_open = ISC_FALSE;
+ dns_dnsseckeylist_t list;
+ isc_dir_t dir;
+ dns_dnsseckey_t *key = NULL;
+ dst_key_t *dstkey = NULL;
+ char namebuf[DNS_NAME_FORMATSIZE], *p;
+ isc_buffer_t b;
+ unsigned int len;
+
+ REQUIRE(keylist != NULL);
+ ISC_LIST_INIT(list);
+ isc_dir_init(&dir);
+
+ isc_buffer_init(&b, namebuf, sizeof(namebuf) - 1);
+ RETERR(dns_name_totext(origin, ISC_FALSE, &b));
+ len = isc_buffer_usedlength(&b);
+ namebuf[len] = '\0';
+
+ if (directory == NULL)
+ directory = ".";
+ RETERR(isc_dir_open(&dir, directory));
+ dir_open = ISC_TRUE;
+
+ while (isc_dir_read(&dir) == ISC_R_SUCCESS) {
+ if (dir.entry.name[0] == 'K' &&
+ dir.entry.length > len + 1 &&
+ dir.entry.name[len + 1] == '+' &&
+ strncasecmp(dir.entry.name + 1, namebuf, len) == 0) {
+ p = strrchr(dir.entry.name, '.');
+ if (p != NULL && strcmp(p, ".private") != 0)
+ continue;
+
+ dstkey = NULL;
+ result = dst_key_fromnamedfile(dir.entry.name,
+ directory,
+ DST_TYPE_PUBLIC |
+ DST_TYPE_PRIVATE,
+ mctx, &dstkey);
+
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx,
+ DNS_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_DNSSEC,
+ ISC_LOG_WARNING,
+ "dns_dnssec_findmatchingkeys: "
+ "error reading key file %s: %s",
+ dir.entry.name,
+ isc_result_totext(result));
+ continue;
+ }
+
+ RETERR(dns_dnsseckey_create(mctx, &dstkey, &key));
+ key->source = dns_keysource_repository;
+ get_hints(key);
+
+ if (key->legacy) {
+ dns_dnsseckey_destroy(mctx, &key);
+ } else {
+ ISC_LIST_APPEND(list, key, link);
+ key = NULL;
+ }
+ }
+ }
+
+ if (!ISC_LIST_EMPTY(list))
+ ISC_LIST_APPENDLIST(*keylist, list, link);
+ else
+ result = ISC_R_NOTFOUND;
+
+ failure:
+ if (dir_open)
+ isc_dir_close(&dir);
+ INSIST(key == NULL);
+ while ((key = ISC_LIST_HEAD(list)) != NULL) {
+ ISC_LIST_UNLINK(list, key, link);
+ INSIST(key->key != NULL);
+ dst_key_free(&key->key);
+ dns_dnsseckey_destroy(mctx, &key);
+ }
+ if (dstkey != NULL)
+ dst_key_free(&dstkey);
+ return (result);
+}
+
+/*%
+ * Add 'newkey' to 'keylist' if it's not already there.
+ *
+ * If 'savekeys' is ISC_TRUE, then we need to preserve all
+ * the keys in the keyset, regardless of whether they have
+ * metadata indicating they should be deactivated or removed.
+ */
+static void
+addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey,
+ isc_boolean_t savekeys, isc_mem_t *mctx)
+{
+ dns_dnsseckey_t *key;
+
+ /* Skip duplicates */
+ for (key = ISC_LIST_HEAD(*keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ if (dst_key_id(key->key) == dst_key_id(*newkey) &&
+ dst_key_alg(key->key) == dst_key_alg(*newkey) &&
+ dns_name_equal(dst_key_name(key->key),
+ dst_key_name(*newkey)))
+ break;
+ }
+
+ if (key != NULL) {
+ /*
+ * Found a match. If the old key was only public and the
+ * new key is private, replace the old one; otherwise
+ * leave it. But either way, mark the key as having
+ * been found in the zone.
+ */
+ if (dst_key_isprivate(key->key)) {
+ dst_key_free(newkey);
+ } else if (dst_key_isprivate(*newkey)) {
+ dst_key_free(&key->key);
+ key->key = *newkey;
+ }
+
+ key->source = dns_keysource_zoneapex;
+ return;
+ }
+
+ dns_dnsseckey_create(mctx, newkey, &key);
+ if (key->legacy || savekeys) {
+ key->force_publish = ISC_TRUE;
+ key->force_sign = dst_key_isprivate(key->key);
+ }
+ key->source = dns_keysource_zoneapex;
+ ISC_LIST_APPEND(*keylist, key, link);
+ *newkey = NULL;
+}
+
+
+/*%
+ * Mark all keys which signed the DNSKEY/SOA RRsets as "active",
+ * for future reference.
+ */
+static isc_result_t
+mark_active_keys(dns_dnsseckeylist_t *keylist, dns_rdataset_t *rrsigs) {
+ isc_result_t result = ISC_R_SUCCESS;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_t sigs;
+ dns_dnsseckey_t *key;
+
+ REQUIRE(rrsigs != NULL && dns_rdataset_isassociated(rrsigs));
+
+ dns_rdataset_init(&sigs);
+ dns_rdataset_clone(rrsigs, &sigs);
+ for (key = ISC_LIST_HEAD(*keylist);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ isc_uint16_t keyid, sigid;
+ dns_secalg_t keyalg, sigalg;
+ keyid = dst_key_id(key->key);
+ keyalg = dst_key_alg(key->key);
+
+ for (result = dns_rdataset_first(&sigs);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&sigs)) {
+ dns_rdata_rrsig_t sig;
+
+ dns_rdata_reset(&rdata);
+ dns_rdataset_current(&sigs, &rdata);
+ result = dns_rdata_tostruct(&rdata, &sig, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ sigalg = sig.algorithm;
+ sigid = sig.keyid;
+ if (keyid == sigid && keyalg == sigalg) {
+ key->is_active = ISC_TRUE;
+ break;
+ }
+ }
+ }
+
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+
+ if (dns_rdataset_isassociated(&sigs))
+ dns_rdataset_disassociate(&sigs);
+ return (result);
+}
+
+/*%
+ * Add the contents of a DNSKEY rdataset 'keyset' to 'keylist'.
+ */
+isc_result_t
+dns_dnssec_keylistfromrdataset(dns_name_t *origin,
+ const char *directory, isc_mem_t *mctx,
+ dns_rdataset_t *keyset, dns_rdataset_t *keysigs,
+ dns_rdataset_t *soasigs, isc_boolean_t savekeys,
+ isc_boolean_t public,
+ dns_dnsseckeylist_t *keylist)
+{
+ dns_rdataset_t keys;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dst_key_t *pubkey = NULL, *privkey = NULL;
+ isc_result_t result;
+
+ REQUIRE(keyset != NULL && dns_rdataset_isassociated(keyset));
+
+ dns_rdataset_init(&keys);
+
+ dns_rdataset_clone(keyset, &keys);
+ for (result = dns_rdataset_first(&keys);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&keys)) {
+ dns_rdata_reset(&rdata);
+ dns_rdataset_current(&keys, &rdata);
+ RETERR(dns_dnssec_keyfromrdata(origin, &rdata, mctx, &pubkey));
+
+ if (!is_zone_key(pubkey) ||
+ (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0)
+ goto skip;
+
+ /* Corrupted .key file? */
+ if (!dns_name_equal(origin, dst_key_name(pubkey)))
+ goto skip;
+
+ if (public) {
+ addkey(keylist, &pubkey, savekeys, mctx);
+ goto skip;
+ }
+
+ result = dst_key_fromfile(dst_key_name(pubkey),
+ dst_key_id(pubkey),
+ dst_key_alg(pubkey),
+ DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
+ directory, mctx, &privkey);
+
+ /*
+ * If the key was revoked and the private file
+ * doesn't exist, maybe it was revoked internally
+ * by named. Try loading the unrevoked version.
+ */
+ if (result == ISC_R_FILENOTFOUND) {
+ isc_uint32_t flags;
+ flags = dst_key_flags(pubkey);
+ if ((flags & DNS_KEYFLAG_REVOKE) != 0) {
+ dst_key_setflags(pubkey,
+ flags & ~DNS_KEYFLAG_REVOKE);
+ result = dst_key_fromfile(dst_key_name(pubkey),
+ dst_key_id(pubkey),
+ dst_key_alg(pubkey),
+ DST_TYPE_PUBLIC|
+ DST_TYPE_PRIVATE,
+ directory,
+ mctx, &privkey);
+ if (result == ISC_R_SUCCESS &&
+ dst_key_pubcompare(pubkey, privkey,
+ ISC_FALSE)) {
+ dst_key_setflags(privkey, flags);
+ }
+ dst_key_setflags(pubkey, flags);
+ }
+ }
+
+ if (result != ISC_R_SUCCESS) {
+ char keybuf[DNS_NAME_FORMATSIZE];
+ char algbuf[DNS_SECALG_FORMATSIZE];
+ dns_name_format(dst_key_name(pubkey), keybuf,
+ sizeof(keybuf));
+ dns_secalg_format(dst_key_alg(pubkey), algbuf,
+ sizeof(algbuf));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING,
+ "dns_dnssec_keylistfromrdataset: error "
+ "reading private key file %s/%s/%d: %s",
+ keybuf, algbuf, dst_key_id(pubkey),
+ isc_result_totext(result));
+ }
+
+ if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) {
+ addkey(keylist, &pubkey, savekeys, mctx);
+ goto skip;
+ }
+ RETERR(result);
+
+ /* This should never happen. */
+ if ((dst_key_flags(privkey) & DNS_KEYTYPE_NOAUTH) != 0)
+ goto skip;
+
+ addkey(keylist, &privkey, savekeys, mctx);
+ skip:
+ if (pubkey != NULL)
+ dst_key_free(&pubkey);
+ if (privkey != NULL)
+ dst_key_free(&privkey);
+ }
+
+ if (result != ISC_R_NOMORE)
+ RETERR(result);
+
+ if (keysigs != NULL && dns_rdataset_isassociated(keysigs))
+ RETERR(mark_active_keys(keylist, keysigs));
+
+ if (soasigs != NULL && dns_rdataset_isassociated(soasigs))
+ RETERR(mark_active_keys(keylist, soasigs));
+
+ result = ISC_R_SUCCESS;
+
+ failure:
+ if (dns_rdataset_isassociated(&keys))
+ dns_rdataset_disassociate(&keys);
+ if (pubkey != NULL)
+ dst_key_free(&pubkey);
+ if (privkey != NULL)
+ dst_key_free(&privkey);
+ return (result);
+}
+
+static isc_result_t
+make_dnskey(dst_key_t *key, unsigned char *buf, int bufsize,
+ dns_rdata_t *target)
+{
+ isc_result_t result;
+ isc_buffer_t b;
+ isc_region_t r;
+
+ isc_buffer_init(&b, buf, bufsize);
+ result = dst_key_todns(key, &b);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dns_rdata_reset(target);
+ isc_buffer_usedregion(&b, &r);
+ dns_rdata_fromregion(target, dst_key_class(key),
+ dns_rdatatype_dnskey, &r);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+publish_key(dns_diff_t *diff, dns_dnsseckey_t *key, dns_name_t *origin,
+ dns_ttl_t ttl, isc_mem_t *mctx, isc_boolean_t allzsk,
+ void (*report)(const char *, ...))
+{
+ isc_result_t result;
+ dns_difftuple_t *tuple = NULL;
+ unsigned char buf[DST_KEY_MAXSIZE];
+ dns_rdata_t dnskey = DNS_RDATA_INIT;
+ char alg[80];
+
+ dns_rdata_reset(&dnskey);
+ RETERR(make_dnskey(key->key, buf, sizeof(buf), &dnskey));
+
+ dns_secalg_format(dst_key_alg(key->key), alg, sizeof(alg));
+ report("Fetching %s %d/%s from key %s.",
+ key->ksk ? (allzsk ? "KSK/ZSK" : "KSK") : "ZSK",
+ dst_key_id(key->key), alg,
+ key->source == dns_keysource_user ? "file" : "repository");
+
+ if (key->prepublish && ttl > key->prepublish) {
+ char keystr[DST_KEY_FORMATSIZE];
+ isc_stdtime_t now;
+
+ dst_key_format(key->key, keystr, sizeof(keystr));
+ report("Key %s: Delaying activation to match the DNSKEY TTL.\n",
+ keystr, ttl);
+
+ isc_stdtime_get(&now);
+ dst_key_settime(key->key, DST_TIME_ACTIVATE, now + ttl);
+ }
+
+ /* publish key */
+ RETERR(dns_difftuple_create(mctx, DNS_DIFFOP_ADD, origin, ttl,
+ &dnskey, &tuple));
+ dns_diff_appendminimal(diff, &tuple);
+ result = ISC_R_SUCCESS;
+
+ failure:
+ return (result);
+}
+
+static isc_result_t
+remove_key(dns_diff_t *diff, dns_dnsseckey_t *key, dns_name_t *origin,
+ dns_ttl_t ttl, isc_mem_t *mctx, const char *reason,
+ void (*report)(const char *, ...))
+{
+ isc_result_t result;
+ dns_difftuple_t *tuple = NULL;
+ unsigned char buf[DST_KEY_MAXSIZE];
+ dns_rdata_t dnskey = DNS_RDATA_INIT;
+ char alg[80];
+
+ dns_secalg_format(dst_key_alg(key->key), alg, sizeof(alg));
+ report("Removing %s key %d/%s from DNSKEY RRset.",
+ reason, dst_key_id(key->key), alg);
+
+ RETERR(make_dnskey(key->key, buf, sizeof(buf), &dnskey));
+ RETERR(dns_difftuple_create(mctx, DNS_DIFFOP_DEL, origin, ttl, &dnskey,
+ &tuple));
+ dns_diff_appendminimal(diff, &tuple);
+ result = ISC_R_SUCCESS;
+
+ failure:
+ return (result);
+}
+
+/*
+ * Update 'keys' with information from 'newkeys'.
+ *
+ * If 'removed' is not NULL, any keys that are being removed from
+ * the zone will be added to the list for post-removal processing.
+ */
+isc_result_t
+dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
+ dns_dnsseckeylist_t *removed, dns_name_t *origin,
+ dns_ttl_t ttl, dns_diff_t *diff, isc_boolean_t allzsk,
+ isc_mem_t *mctx, void (*report)(const char *, ...))
+{
+ isc_result_t result;
+ dns_dnsseckey_t *key, *key1, *key2, *next;
+
+ /*
+ * First, look through the existing key list to find keys
+ * supplied from the command line which are not in the zone.
+ * Update the zone to include them.
+ */
+ for (key = ISC_LIST_HEAD(*keys);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ if (key->source == dns_keysource_user &&
+ (key->hint_publish || key->force_publish)) {
+ RETERR(publish_key(diff, key, origin, ttl,
+ mctx, allzsk, report));
+ }
+ }
+
+ /*
+ * Second, scan the list of newly found keys looking for matches
+ * with known keys, and update accordingly.
+ */
+ for (key1 = ISC_LIST_HEAD(*newkeys); key1 != NULL; key1 = next) {
+ isc_boolean_t key_revoked = ISC_FALSE;
+
+ next = ISC_LIST_NEXT(key1, link);
+
+ for (key2 = ISC_LIST_HEAD(*keys);
+ key2 != NULL;
+ key2 = ISC_LIST_NEXT(key2, link)) {
+ if (dst_key_pubcompare(key1->key, key2->key,
+ ISC_TRUE)) {
+ int r1, r2;
+ r1 = dst_key_flags(key1->key) &
+ DNS_KEYFLAG_REVOKE;
+ r2 = dst_key_flags(key2->key) &
+ DNS_KEYFLAG_REVOKE;
+ key_revoked = ISC_TF(r1 != r2);
+ break;
+ }
+ }
+
+ /* No match found in keys; add the new key. */
+ if (key2 == NULL) {
+ dns_dnsseckey_t *next;
+
+ next = ISC_LIST_NEXT(key1, link);
+ ISC_LIST_UNLINK(*newkeys, key1, link);
+ ISC_LIST_APPEND(*keys, key1, link);
+
+ if (key1->source != dns_keysource_zoneapex &&
+ (key1->hint_publish || key1->force_publish)) {
+ RETERR(publish_key(diff, key1, origin, ttl,
+ mctx, allzsk, report));
+ if (key1->hint_sign || key1->force_sign)
+ key1->first_sign = ISC_TRUE;
+ }
+
+ continue;
+ }
+
+ /* Match found: remove or update it as needed */
+ if (key1->hint_remove) {
+ RETERR(remove_key(diff, key2, origin, ttl, mctx,
+ "expired", report));
+ ISC_LIST_UNLINK(*keys, key2, link);
+ if (removed != NULL)
+ ISC_LIST_APPEND(*removed, key2, link);
+ else
+ dns_dnsseckey_destroy(mctx, &key2);
+ } else if (key_revoked &&
+ (dst_key_flags(key1->key) & DNS_KEYFLAG_REVOKE) != 0) {
+
+ /*
+ * A previously valid key has been revoked.
+ * We need to remove the old version and pull
+ * in the new one.
+ */
+ RETERR(remove_key(diff, key2, origin, ttl, mctx,
+ "revoked", report));
+ ISC_LIST_UNLINK(*keys, key2, link);
+ if (removed != NULL)
+ ISC_LIST_APPEND(*removed, key2, link);
+ else
+ dns_dnsseckey_destroy(mctx, &key2);
+
+ RETERR(publish_key(diff, key1, origin, ttl,
+ mctx, allzsk, report));
+ ISC_LIST_UNLINK(*newkeys, key1, link);
+ ISC_LIST_APPEND(*keys, key1, link);
+
+ /*
+ * XXX: The revoke flag is only defined for trust
+ * anchors. Setting the flag on a non-KSK is legal,
+ * but not defined in any RFC. It seems reasonable
+ * to treat it the same as a KSK: keep it in the
+ * zone, sign the DNSKEY set with it, but not
+ * sign other records with it.
+ */
+ key1->ksk = ISC_TRUE;
+ continue;
+ } else {
+ if (!key2->is_active &&
+ (key1->hint_sign || key1->force_sign))
+ key2->first_sign = ISC_TRUE;
+ key2->hint_sign = key1->hint_sign;
+ key2->hint_publish = key1->hint_publish;
+ }
+ }
+
+ /* Free any leftover keys in newkeys */
+ while (!ISC_LIST_EMPTY(*newkeys)) {
+ key1 = ISC_LIST_HEAD(*newkeys);
+ ISC_LIST_UNLINK(*newkeys, key1, link);
+ dns_dnsseckey_destroy(mctx, &key1);
+ }
+
+ result = ISC_R_SUCCESS;
+
+ failure:
+ return (result);
+}
diff --git a/lib/dns/ds.c b/lib/dns/ds.c
index 9cf56593a848..80e1503f1528 100644
--- a/lib/dns/ds.c
+++ b/lib/dns/ds.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ds.c,v 1.11 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: ds.c,v 1.13 2010-12-23 23:47:08 tbox Exp $ */
/*! \file */
@@ -38,6 +38,13 @@
#include <dst/dst.h>
+#ifdef HAVE_OPENSSL_GOST
+#include <dst/result.h>
+#include <openssl/evp.h>
+
+extern const EVP_MD * EVP_gost(void);
+#endif
+
isc_result_t
dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
unsigned int digest_type, unsigned char *buffer,
@@ -49,6 +56,12 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
isc_region_t r;
isc_buffer_t b;
dns_rdata_ds_t ds;
+ isc_sha1_t sha1;
+ isc_sha256_t sha256;
+#ifdef HAVE_OPENSSL_GOST
+ EVP_MD_CTX ctx;
+ const EVP_MD *md;
+#endif
REQUIRE(key != NULL);
REQUIRE(key->type == dns_rdatatype_dnskey);
@@ -63,8 +76,8 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
memset(buffer, 0, DNS_DS_BUFFERSIZE);
isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE);
- if (digest_type == DNS_DSDIGEST_SHA1) {
- isc_sha1_t sha1;
+ switch (digest_type) {
+ case DNS_DSDIGEST_SHA1:
isc_sha1_init(&sha1);
dns_name_toregion(name, &r);
isc_sha1_update(&sha1, r.base, r.length);
@@ -72,8 +85,33 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
INSIST(r.length >= 4);
isc_sha1_update(&sha1, r.base, r.length);
isc_sha1_final(&sha1, digest);
- } else {
- isc_sha256_t sha256;
+ break;
+#ifdef HAVE_OPENSSL_GOST
+#define CHECK(x) \
+ if ((x) != 1) { \
+ EVP_MD_CTX_cleanup(&ctx); \
+ return (DST_R_OPENSSLFAILURE); \
+ }
+
+ case DNS_DSDIGEST_GOST:
+ md = EVP_gost();
+ if (md == NULL)
+ return (DST_R_OPENSSLFAILURE);
+ EVP_MD_CTX_init(&ctx);
+ CHECK(EVP_DigestInit(&ctx, md));
+ dns_name_toregion(name, &r);
+ CHECK(EVP_DigestUpdate(&ctx,
+ (const void *) r.base,
+ (size_t) r.length));
+ dns_rdata_toregion(key, &r);
+ INSIST(r.length >= 4);
+ CHECK(EVP_DigestUpdate(&ctx,
+ (const void *) r.base,
+ (size_t) r.length));
+ CHECK(EVP_DigestFinal(&ctx, digest, NULL));
+ break;
+#endif
+ default:
isc_sha256_init(&sha256);
dns_name_toregion(name, &r);
isc_sha256_update(&sha256, r.base, r.length);
@@ -81,6 +119,7 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
INSIST(r.length >= 4);
isc_sha256_update(&sha256, r.base, r.length);
isc_sha256_final(digest, &sha256);
+ break;
}
ds.mctx = NULL;
@@ -89,8 +128,19 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
ds.algorithm = r.base[3];
ds.key_tag = dst_region_computeid(&r, ds.algorithm);
ds.digest_type = digest_type;
- ds.length = (digest_type == DNS_DSDIGEST_SHA1) ?
- ISC_SHA1_DIGESTLENGTH : ISC_SHA256_DIGESTLENGTH;
+ switch (digest_type) {
+ case DNS_DSDIGEST_SHA1:
+ ds.length = ISC_SHA1_DIGESTLENGTH;
+ break;
+#ifdef HAVE_OPENSSL_GOST
+ case DNS_DSDIGEST_GOST:
+ ds.length = ISC_GOST_DIGESTLENGTH;
+ break;
+#endif
+ default:
+ ds.length = ISC_SHA256_DIGESTLENGTH;
+ break;
+ }
ds.digest = digest;
return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds,
@@ -99,6 +149,12 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
isc_boolean_t
dns_ds_digest_supported(unsigned int digest_type) {
+#ifdef HAVE_OPENSSL_GOST
+ return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
+ digest_type == DNS_DSDIGEST_SHA256 ||
+ digest_type == DNS_DSDIGEST_GOST));
+#else
return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
digest_type == DNS_DSDIGEST_SHA256));
+#endif
}
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c
index 97d2657a171b..1ece31276610 100644
--- a/lib/dns/dst_api.c
+++ b/lib/dns/dst_api.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: dst_api.c,v 1.16.12.12 2010-12-09 01:12:55 marka Exp $
+ * $Id: dst_api.c,v 1.57 2011-01-11 23:47:13 tbox Exp $
*/
/*! \file */
@@ -39,6 +39,7 @@
#include <config.h>
#include <stdlib.h>
+#include <time.h>
#include <isc/buffer.h>
#include <isc/dir.h>
@@ -48,6 +49,7 @@
#include <isc/lex.h>
#include <isc/mem.h>
#include <isc/once.h>
+#include <isc/platform.h>
#include <isc/print.h>
#include <isc/refcount.h>
#include <isc/random.h>
@@ -70,7 +72,9 @@
#define DST_AS_STR(t) ((t).value.as_textregion.base)
static dst_func_t *dst_t_func[DST_MAX_ALGS];
+#ifdef BIND9
static isc_entropy_t *dst_entropy_pool = NULL;
+#endif
static unsigned int dst_entropy_flags = 0;
static isc_boolean_t dst_initialized = ISC_FALSE;
@@ -108,10 +112,11 @@ static isc_result_t frombuffer(dns_name_t *name,
static isc_result_t algorithm_status(unsigned int alg);
-static isc_result_t addsuffix(char *filename, unsigned int len,
- const char *ofilename, const char *suffix);
+static isc_result_t addsuffix(char *filename, int len,
+ const char *dirname, const char *ofilename,
+ const char *suffix);
-#define RETERR(x) \
+#define RETERR(x) \
do { \
result = (x); \
if (result != ISC_R_SUCCESS) \
@@ -126,7 +131,7 @@ static isc_result_t addsuffix(char *filename, unsigned int len,
return (_r); \
} while (0); \
-#ifdef OPENSSL
+#if defined(OPENSSL) && defined(BIND9)
static void *
default_memalloc(void *arg, size_t size) {
UNUSED(arg);
@@ -144,14 +149,29 @@ default_memfree(void *arg, void *ptr) {
isc_result_t
dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
+ return (dst_lib_init2(mctx, ectx, NULL, eflags));
+}
+
+isc_result_t
+dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx,
+ const char *engine, unsigned int eflags) {
isc_result_t result;
- REQUIRE(mctx != NULL && ectx != NULL);
+ REQUIRE(mctx != NULL);
+#ifdef BIND9
+ REQUIRE(ectx != NULL);
+#else
+ UNUSED(ectx);
+#endif
REQUIRE(dst_initialized == ISC_FALSE);
+#ifndef OPENSSL
+ UNUSED(engine);
+#endif
+
dst__memory_pool = NULL;
-#ifdef OPENSSL
+#if defined(OPENSSL) && defined(BIND9)
UNUSED(mctx);
/*
* When using --with-openssl, there seems to be no good way of not
@@ -166,11 +186,15 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
if (result != ISC_R_SUCCESS)
return (result);
isc_mem_setname(dst__memory_pool, "dst", NULL);
+#ifndef OPENSSL_LEAKS
isc_mem_setdestroycheck(dst__memory_pool, ISC_FALSE);
+#endif
#else
isc_mem_attach(mctx, &dst__memory_pool);
#endif
+#ifdef BIND9
isc_entropy_attach(ectx, &dst_entropy_pool);
+#endif
dst_entropy_flags = eflags;
dst_result_register();
@@ -183,7 +207,7 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
RETERR(dst__hmacsha384_init(&dst_t_func[DST_ALG_HMACSHA384]));
RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512]));
#ifdef OPENSSL
- RETERR(dst__openssl_init());
+ RETERR(dst__openssl_init(engine));
RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5],
DST_ALG_RSAMD5));
RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1],
@@ -199,6 +223,9 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_NSEC3DSA]));
#endif
RETERR(dst__openssldh_init(&dst_t_func[DST_ALG_DH]));
+#ifdef HAVE_OPENSSL_GOST
+ RETERR(dst__opensslgost_init(&dst_t_func[DST_ALG_ECCGOST]));
+#endif
#endif /* OPENSSL */
#ifdef GSSAPI
RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI]));
@@ -207,6 +234,8 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
return (ISC_R_SUCCESS);
out:
+ /* avoid immediate crash! */
+ dst_initialized = ISC_TRUE;
dst_lib_destroy();
return (result);
}
@@ -225,9 +254,10 @@ dst_lib_destroy(void) {
#endif
if (dst__memory_pool != NULL)
isc_mem_detach(&dst__memory_pool);
+#ifdef BIND9
if (dst_entropy_pool != NULL)
isc_entropy_detach(&dst_entropy_pool);
-
+#endif
}
isc_boolean_t
@@ -402,7 +432,7 @@ dst_key_fromfile(dns_name_t *name, dns_keytag_t id,
return (result);
key = NULL;
- result = dst_key_fromnamedfile(filename, type, mctx, &key);
+ result = dst_key_fromnamedfile(filename, NULL, type, mctx, &key);
if (result != ISC_R_SUCCESS)
return (result);
@@ -424,12 +454,11 @@ dst_key_fromfile(dns_name_t *name, dns_keytag_t id,
}
isc_result_t
-dst_key_fromnamedfile(const char *filename, int type, isc_mem_t *mctx,
- dst_key_t **keyp)
+dst_key_fromnamedfile(const char *filename, const char *dirname,
+ int type, isc_mem_t *mctx, dst_key_t **keyp)
{
isc_result_t result;
dst_key_t *pubkey = NULL, *key = NULL;
- dns_keytag_t id;
char *newfilename = NULL;
int newfilenamelen = 0;
isc_lex_t *lex = NULL;
@@ -440,11 +469,23 @@ dst_key_fromnamedfile(const char *filename, int type, isc_mem_t *mctx,
REQUIRE(mctx != NULL);
REQUIRE(keyp != NULL && *keyp == NULL);
+ /* If an absolute path is specified, don't use the key directory */
+#ifndef WIN32
+ if (filename[0] == '/')
+ dirname = NULL;
+#else /* WIN32 */
+ if (filename[0] == '/' || filename[0] == '\\')
+ dirname = NULL;
+#endif
+
newfilenamelen = strlen(filename) + 5;
+ if (dirname != NULL)
+ newfilenamelen += strlen(dirname) + 1;
newfilename = isc_mem_get(mctx, newfilenamelen);
if (newfilename == NULL)
return (ISC_R_NOMEMORY);
- result = addsuffix(newfilename, newfilenamelen, filename, ".key");
+ result = addsuffix(newfilename, newfilenamelen,
+ dirname, filename, ".key");
INSIST(result == ISC_R_SUCCESS);
result = dst_key_read_public(newfilename, type, mctx, &pubkey);
@@ -474,38 +515,43 @@ dst_key_fromnamedfile(const char *filename, int type, isc_mem_t *mctx,
key = get_key_struct(pubkey->key_name, pubkey->key_alg,
pubkey->key_flags, pubkey->key_proto, 0,
pubkey->key_class, mctx);
- id = pubkey->key_id;
- dst_key_free(&pubkey);
-
- if (key == NULL)
+ if (key == NULL) {
+ dst_key_free(&pubkey);
return (ISC_R_NOMEMORY);
+ }
if (key->func->parse == NULL)
RETERR(DST_R_UNSUPPORTEDALG);
newfilenamelen = strlen(filename) + 9;
+ if (dirname != NULL)
+ newfilenamelen += strlen(dirname) + 1;
newfilename = isc_mem_get(mctx, newfilenamelen);
if (newfilename == NULL)
RETERR(ISC_R_NOMEMORY);
- result = addsuffix(newfilename, newfilenamelen, filename, ".private");
+ result = addsuffix(newfilename, newfilenamelen,
+ dirname, filename, ".private");
INSIST(result == ISC_R_SUCCESS);
RETERR(isc_lex_create(mctx, 1500, &lex));
RETERR(isc_lex_openfile(lex, newfilename));
isc_mem_put(mctx, newfilename, newfilenamelen);
- RETERR(key->func->parse(key, lex));
+ RETERR(key->func->parse(key, lex, pubkey));
isc_lex_destroy(&lex);
RETERR(computeid(key));
- if (id != key->key_id)
+ if (pubkey->key_id != key->key_id)
RETERR(DST_R_INVALIDPRIVATEKEY);
+ dst_key_free(&pubkey);
*keyp = key;
return (ISC_R_SUCCESS);
out:
+ if (pubkey != NULL)
+ dst_key_free(&pubkey);
if (newfilename != NULL)
isc_mem_put(mctx, newfilename, newfilenamelen);
if (lex != NULL)
@@ -640,7 +686,7 @@ dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer) {
RETERR(isc_lex_create(key->mctx, 1500, &lex));
RETERR(isc_lex_openbuffer(lex, buffer));
- RETERR(key->func->parse(key, lex));
+ RETERR(key->func->parse(key, lex, NULL));
out:
if (lex != NULL)
isc_lex_destroy(&lex);
@@ -657,9 +703,10 @@ dst_key_getgssctx(const dst_key_t *key)
isc_result_t
dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx,
- dst_key_t **keyp)
+ dst_key_t **keyp, isc_region_t *intoken)
{
dst_key_t *key;
+ isc_result_t result;
REQUIRE(gssctx != NULL);
REQUIRE(keyp != NULL && *keyp == NULL);
@@ -669,9 +716,21 @@ dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx,
if (key == NULL)
return (ISC_R_NOMEMORY);
+ if (intoken != NULL) {
+ /*
+ * Keep the token for use by external ssu rules. They may need
+ * to examine the PAC in the kerberos ticket.
+ */
+ RETERR(isc_buffer_allocate(key->mctx, &key->key_tkeytoken,
+ intoken->length));
+ RETERR(isc_buffer_copyregion(key->key_tkeytoken, intoken));
+ }
+
key->keydata.gssctx = gssctx;
*keyp = key;
- return (ISC_R_SUCCESS);
+ result = ISC_R_SUCCESS;
+out:
+ return result;
}
isc_result_t
@@ -723,6 +782,18 @@ dst_key_generate(dns_name_t *name, unsigned int alg,
dns_rdataclass_t rdclass,
isc_mem_t *mctx, dst_key_t **keyp)
{
+ return (dst_key_generate2(name, alg, bits, param, flags, protocol,
+ rdclass, mctx, keyp, NULL));
+}
+
+isc_result_t
+dst_key_generate2(dns_name_t *name, unsigned int alg,
+ unsigned int bits, unsigned int param,
+ unsigned int flags, unsigned int protocol,
+ dns_rdataclass_t rdclass,
+ isc_mem_t *mctx, dst_key_t **keyp,
+ void (*callback)(int))
+{
dst_key_t *key;
isc_result_t ret;
@@ -748,7 +819,7 @@ dst_key_generate(dns_name_t *name, unsigned int alg,
return (DST_R_UNSUPPORTEDALG);
}
- ret = key->func->generate(key, param);
+ ret = key->func->generate(key, param, callback);
if (ret != ISC_R_SUCCESS) {
dst_key_free(&key);
return (ret);
@@ -764,25 +835,185 @@ dst_key_generate(dns_name_t *name, unsigned int alg,
return (ISC_R_SUCCESS);
}
-isc_boolean_t
-dst_key_compare(const dst_key_t *key1, const dst_key_t *key2) {
+isc_result_t
+dst_key_getnum(const dst_key_t *key, int type, isc_uint32_t *valuep)
+{
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(valuep != NULL);
+ REQUIRE(type <= DST_MAX_NUMERIC);
+ if (!key->numset[type])
+ return (ISC_R_NOTFOUND);
+ *valuep = key->nums[type];
+ return (ISC_R_SUCCESS);
+}
+
+void
+dst_key_setnum(dst_key_t *key, int type, isc_uint32_t value)
+{
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(type <= DST_MAX_NUMERIC);
+ key->nums[type] = value;
+ key->numset[type] = ISC_TRUE;
+}
+
+void
+dst_key_unsetnum(dst_key_t *key, int type)
+{
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(type <= DST_MAX_NUMERIC);
+ key->numset[type] = ISC_FALSE;
+}
+
+isc_result_t
+dst_key_gettime(const dst_key_t *key, int type, isc_stdtime_t *timep) {
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(timep != NULL);
+ REQUIRE(type <= DST_MAX_TIMES);
+ if (!key->timeset[type])
+ return (ISC_R_NOTFOUND);
+ *timep = key->times[type];
+ return (ISC_R_SUCCESS);
+}
+
+void
+dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when) {
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(type <= DST_MAX_TIMES);
+ key->times[type] = when;
+ key->timeset[type] = ISC_TRUE;
+}
+
+void
+dst_key_unsettime(dst_key_t *key, int type) {
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(type <= DST_MAX_TIMES);
+ key->timeset[type] = ISC_FALSE;
+}
+
+isc_result_t
+dst_key_getprivateformat(const dst_key_t *key, int *majorp, int *minorp) {
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(majorp != NULL);
+ REQUIRE(minorp != NULL);
+ *majorp = key->fmt_major;
+ *minorp = key->fmt_minor;
+ return (ISC_R_SUCCESS);
+}
+
+void
+dst_key_setprivateformat(dst_key_t *key, int major, int minor) {
+ REQUIRE(VALID_KEY(key));
+ key->fmt_major = major;
+ key->fmt_minor = minor;
+}
+
+static isc_boolean_t
+comparekeys(const dst_key_t *key1, const dst_key_t *key2,
+ isc_boolean_t match_revoked_key,
+ isc_boolean_t (*compare)(const dst_key_t *key1,
+ const dst_key_t *key2))
+{
REQUIRE(dst_initialized == ISC_TRUE);
REQUIRE(VALID_KEY(key1));
REQUIRE(VALID_KEY(key2));
if (key1 == key2)
return (ISC_TRUE);
+
if (key1 == NULL || key2 == NULL)
return (ISC_FALSE);
- if (key1->key_alg == key2->key_alg &&
- key1->key_id == key2->key_id &&
- key1->func->compare != NULL &&
- key1->func->compare(key1, key2) == ISC_TRUE)
- return (ISC_TRUE);
+
+ if (key1->key_alg != key2->key_alg)
+ return (ISC_FALSE);
+
+ /*
+ * For all algorithms except RSAMD5, revoking the key
+ * changes the key ID, increasing it by 128. If we want to
+ * be able to find matching keys even if one of them is the
+ * revoked version of the other one, then we need to check
+ * for that possibility.
+ */
+ if (key1->key_id != key2->key_id) {
+ if (!match_revoked_key)
+ return (ISC_FALSE);
+ if (key1->key_alg == DST_ALG_RSAMD5)
+ return (ISC_FALSE);
+ if ((key1->key_flags & DNS_KEYFLAG_REVOKE) ==
+ (key2->key_flags & DNS_KEYFLAG_REVOKE))
+ return (ISC_FALSE);
+ if ((key1->key_flags & DNS_KEYFLAG_REVOKE) != 0 &&
+ key1->key_id != ((key2->key_id + 128) & 0xffff))
+ return (ISC_FALSE);
+ if ((key2->key_flags & DNS_KEYFLAG_REVOKE) != 0 &&
+ key2->key_id != ((key1->key_id + 128) & 0xffff))
+ return (ISC_FALSE);
+ }
+
+ if (compare != NULL)
+ return (compare(key1, key2));
else
return (ISC_FALSE);
}
+
+/*
+ * Compares only the public portion of two keys, by converting them
+ * both to wire format and comparing the results.
+ */
+static isc_boolean_t
+pub_compare(const dst_key_t *key1, const dst_key_t *key2) {
+ isc_result_t result;
+ unsigned char buf1[DST_KEY_MAXSIZE], buf2[DST_KEY_MAXSIZE];
+ isc_buffer_t b1, b2;
+ isc_region_t r1, r2;
+
+ isc_buffer_init(&b1, buf1, sizeof(buf1));
+ result = dst_key_todns(key1, &b1);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+ /* Zero out flags. */
+ buf1[0] = buf1[1] = 0;
+ if ((key1->key_flags & DNS_KEYFLAG_EXTENDED) != 0)
+ isc_buffer_subtract(&b1, 2);
+
+ isc_buffer_init(&b2, buf2, sizeof(buf2));
+ result = dst_key_todns(key2, &b2);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+ /* Zero out flags. */
+ buf2[0] = buf2[1] = 0;
+ if ((key2->key_flags & DNS_KEYFLAG_EXTENDED) != 0)
+ isc_buffer_subtract(&b2, 2);
+
+ isc_buffer_usedregion(&b1, &r1);
+ /* Remove extended flags. */
+ if ((key1->key_flags & DNS_KEYFLAG_EXTENDED) != 0) {
+ memmove(&buf1[4], &buf1[6], r1.length - 6);
+ r1.length -= 2;
+ }
+
+ isc_buffer_usedregion(&b2, &r2);
+ /* Remove extended flags. */
+ if ((key2->key_flags & DNS_KEYFLAG_EXTENDED) != 0) {
+ memmove(&buf2[4], &buf2[6], r2.length - 6);
+ r2.length -= 2;
+ }
+ return (ISC_TF(isc_region_compare(&r1, &r2) == 0));
+}
+
+isc_boolean_t
+dst_key_compare(const dst_key_t *key1, const dst_key_t *key2) {
+ return (comparekeys(key1, key2, ISC_FALSE, key1->func->compare));
+}
+
+isc_boolean_t
+dst_key_pubcompare(const dst_key_t *key1, const dst_key_t *key2,
+ isc_boolean_t match_revoked_key)
+{
+ return (comparekeys(key1, key2, match_revoked_key, pub_compare));
+}
+
+
isc_boolean_t
dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
REQUIRE(dst_initialized == ISC_TRUE);
@@ -839,6 +1070,9 @@ dst_key_free(dst_key_t **keyp) {
isc_mem_free(mctx, key->label);
dns_name_free(key->key_name, mctx);
isc_mem_put(mctx, key->key_name, sizeof(dns_name_t));
+ if (key->key_tkeytoken) {
+ isc_buffer_free(&key->key_tkeytoken);
+ }
memset(key, 0, sizeof(dst_key_t));
isc_mem_put(mctx, key, sizeof(dst_key_t));
*keyp = NULL;
@@ -882,6 +1116,9 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) {
case DST_ALG_NSEC3DSA:
*n = DNS_SIG_DSASIGSIZE;
break;
+ case DST_ALG_ECCGOST:
+ *n = DNS_SIG_GOSTSIGSIZE;
+ break;
case DST_ALG_HMACMD5:
*n = 16;
break;
@@ -923,6 +1160,69 @@ dst_key_secretsize(const dst_key_t *key, unsigned int *n) {
return (ISC_R_SUCCESS);
}
+/*%
+ * Set the flags on a key, then recompute the key ID
+ */
+isc_result_t
+dst_key_setflags(dst_key_t *key, isc_uint32_t flags) {
+ REQUIRE(VALID_KEY(key));
+ key->key_flags = flags;
+ return (computeid(key));
+}
+
+void
+dst_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));
+ dns_secalg_format((dns_secalg_t) dst_key_alg(key), algstr,
+ sizeof(algstr));
+ snprintf(cp, size, "%s/%s/%d", namestr, algstr, dst_key_id(key));
+}
+
+isc_result_t
+dst_key_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) {
+
+ REQUIRE(buffer != NULL && *buffer == NULL);
+ REQUIRE(length != NULL && *length == 0);
+ REQUIRE(VALID_KEY(key));
+
+ if (key->func->isprivate == NULL)
+ return (ISC_R_NOTIMPLEMENTED);
+ return (key->func->dump(key, mctx, buffer, length));
+}
+
+isc_result_t
+dst_key_restore(dns_name_t *name, unsigned int alg, unsigned int flags,
+ unsigned int protocol, dns_rdataclass_t rdclass,
+ isc_mem_t *mctx, const char *keystr, dst_key_t **keyp)
+{
+ isc_result_t result;
+ dst_key_t *key;
+
+ REQUIRE(dst_initialized == ISC_TRUE);
+ REQUIRE(keyp != NULL && *keyp == NULL);
+
+ if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL)
+ return (DST_R_UNSUPPORTEDALG);
+
+ if (dst_t_func[alg]->restore == NULL)
+ return (ISC_R_NOTIMPLEMENTED);
+
+ key = get_key_struct(name, alg, flags, protocol, 0, rdclass, mctx);
+ if (key == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = (dst_t_func[alg]->restore)(key, keystr);
+ if (result == ISC_R_SUCCESS)
+ *keyp = key;
+ else
+ dst_key_free(&key);
+
+ return (result);
+}
+
/***
*** Static methods
***/
@@ -938,6 +1238,7 @@ get_key_struct(dns_name_t *name, unsigned int alg,
{
dst_key_t *key;
isc_result_t result;
+ int i;
key = (dst_key_t *) isc_mem_get(mctx, sizeof(dst_key_t));
if (key == NULL)
@@ -974,6 +1275,12 @@ get_key_struct(dns_name_t *name, unsigned int alg,
key->key_size = bits;
key->key_class = rdclass;
key->func = dst_t_func[alg];
+ key->fmt_major = 0;
+ key->fmt_minor = 0;
+ for (i = 0; i < (DST_MAX_TIMES + 1); i++) {
+ key->times[i] = 0;
+ key->timeset[i] = ISC_FALSE;
+ }
return (key);
}
@@ -1046,7 +1353,7 @@ dst_key_read_public(const char *filename, int type,
isc_buffer_init(&b, DST_AS_STR(token), strlen(DST_AS_STR(token)));
isc_buffer_add(&b, strlen(DST_AS_STR(token)));
ret = dns_name_fromtext(dns_fixedname_name(&name), &b, dns_rootname,
- ISC_FALSE, NULL);
+ 0, NULL);
if (ret != ISC_R_SUCCESS)
goto cleanup;
@@ -1116,6 +1423,7 @@ issymmetric(const dst_key_t *key) {
case DST_ALG_DSA:
case DST_ALG_NSEC3DSA:
case DST_ALG_DH:
+ case DST_ALG_ECCGOST:
return (ISC_FALSE);
case DST_ALG_HMACMD5:
case DST_ALG_GSSAPI:
@@ -1126,6 +1434,55 @@ issymmetric(const dst_key_t *key) {
}
/*%
+ * Write key timing metadata to a file pointer, preceded by 'tag'
+ */
+static void
+printtime(const dst_key_t *key, int type, const char *tag, FILE *stream) {
+ isc_result_t result;
+#ifdef ISC_PLATFORM_USETHREADS
+ char output[26]; /* Minimum buffer as per ctime_r() specification. */
+#else
+ const char *output;
+#endif
+ isc_stdtime_t when;
+ time_t t;
+ char utc[sizeof("YYYYMMDDHHSSMM")];
+ isc_buffer_t b;
+ isc_region_t r;
+
+ result = dst_key_gettime(key, type, &when);
+ if (result == ISC_R_NOTFOUND)
+ return;
+
+ /* time_t and isc_stdtime_t might be different sizes */
+ t = when;
+#ifdef ISC_PLATFORM_USETHREADS
+#ifdef WIN32
+ if (ctime_s(output, sizeof(output), &t) != 0)
+ goto error;
+#else
+ if (ctime_r(&t, output) == NULL)
+ goto error;
+#endif
+#else
+ output = ctime(&t);
+#endif
+
+ isc_buffer_init(&b, utc, sizeof(utc));
+ result = dns_time32_totext(when, &b);
+ if (result != ISC_R_SUCCESS)
+ goto error;
+
+ isc_buffer_usedregion(&b, &r);
+ fprintf(stream, "%s: %.*s (%.*s)\n", tag, (int)r.length, r.base,
+ (int)strlen(output) - 1, output);
+ return;
+
+ error:
+ fprintf(stream, "%s: (set, unable to display)\n", tag);
+}
+
+/*%
* Writes a public key to disk in DNS format.
*/
static isc_result_t
@@ -1184,12 +1541,34 @@ write_public_key(const dst_key_t *key, int type, const char *directory) {
(void)isc_fsaccess_set(filename, access);
}
- ret = dns_name_print(key->key_name, fp);
- if (ret != ISC_R_SUCCESS) {
- fclose(fp);
- return (ret);
+ /* Write key information in comments */
+ if ((type & DST_TYPE_KEY) == 0) {
+ fprintf(fp, "; This is a %s%s-signing key, keyid %d, for ",
+ (key->key_flags & DNS_KEYFLAG_REVOKE) != 0 ?
+ "revoked " :
+ "",
+ (key->key_flags & DNS_KEYFLAG_KSK) != 0 ?
+ "key" :
+ "zone",
+ key->key_id);
+ ret = dns_name_print(key->key_name, fp);
+ if (ret != ISC_R_SUCCESS) {
+ fclose(fp);
+ return (ret);
+ }
+ fputc('\n', fp);
+
+ printtime(key, DST_TIME_CREATED, "; Created", fp);
+ printtime(key, DST_TIME_PUBLISH, "; Publish", fp);
+ printtime(key, DST_TIME_ACTIVATE, "; Activate", fp);
+ printtime(key, DST_TIME_REVOKE, "; Revoke", fp);
+ printtime(key, DST_TIME_INACTIVE, "; Inactive", fp);
+ printtime(key, DST_TIME_DELETE, "; Delete", fp);
}
+ /* Now print the actual key */
+ ret = dns_name_print(key->key_name, fp);
+
fprintf(fp, " ");
isc_buffer_usedregion(&classb, &r);
@@ -1317,15 +1696,16 @@ algorithm_status(unsigned int alg) {
alg == DST_ALG_DSA || alg == DST_ALG_DH ||
alg == DST_ALG_HMACMD5 || alg == DST_ALG_NSEC3DSA ||
alg == DST_ALG_NSEC3RSASHA1 ||
- alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512)
+ alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512 ||
+ alg == DST_ALG_ECCGOST)
return (DST_R_NOCRYPTO);
#endif
return (DST_R_UNSUPPORTEDALG);
}
static isc_result_t
-addsuffix(char *filename, unsigned int len, const char *ofilename,
- const char *suffix)
+addsuffix(char *filename, int len, const char *odirname,
+ const char *ofilename, const char *suffix)
{
int olen = strlen(ofilename);
int n;
@@ -1337,27 +1717,42 @@ addsuffix(char *filename, unsigned int len, const char *ofilename,
else if (olen > 4 && strcmp(ofilename + olen - 4, ".key") == 0)
olen -= 4;
- n = snprintf(filename, len, "%.*s%s", olen, ofilename, suffix);
+ if (odirname == NULL)
+ n = snprintf(filename, len, "%.*s%s", olen, ofilename, suffix);
+ else
+ n = snprintf(filename, len, "%s/%.*s%s",
+ odirname, olen, ofilename, suffix);
if (n < 0)
return (ISC_R_FAILURE);
- if ((unsigned int)n >= len)
+ if (n >= len)
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
}
isc_result_t
dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) {
+#ifdef BIND9
unsigned int flags = dst_entropy_flags;
if (len == 0)
return (ISC_R_SUCCESS);
if (pseudo)
flags &= ~ISC_ENTROPY_GOODONLY;
+ else
+ flags |= ISC_ENTROPY_BLOCKING;
return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags));
+#else
+ UNUSED(buf);
+ UNUSED(len);
+ UNUSED(pseudo);
+
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
}
unsigned int
dst__entropy_status(void) {
+#ifdef BIND9
#ifdef GSSAPI
unsigned int flags = dst_entropy_flags;
isc_result_t ret;
@@ -1376,4 +1771,12 @@ dst__entropy_status(void) {
}
#endif
return (isc_entropy_status(dst_entropy_pool));
+#else
+ return (0);
+#endif
+}
+
+isc_buffer_t *
+dst_key_tkeytoken(const dst_key_t *key) {
+ return (key->key_tkeytoken);
}
diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h
index 01bf1f270e9e..220b3da836f1 100644
--- a/lib/dns/dst_internal.h
+++ b/lib/dns/dst_internal.h
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst_internal.h,v 1.11.120.3 2010-12-09 01:12:55 marka Exp $ */
+/* $Id: dst_internal.h,v 1.29 2011-01-11 23:47:13 tbox Exp $ */
#ifndef DST_DST_INTERNAL_H
#define DST_DST_INTERNAL_H 1
@@ -44,9 +44,12 @@
#include <isc/refcount.h>
#include <isc/sha1.h>
#include <isc/sha2.h>
+#include <isc/stdtime.h>
#include <isc/hmacmd5.h>
#include <isc/hmacsha.h>
+#include <dns/time.h>
+
#include <dst/dst.h>
#ifdef OPENSSL
@@ -60,8 +63,8 @@
ISC_LANG_BEGINDECLS
-#define KEY_MAGIC ISC_MAGIC('D','S','T','K')
-#define CTX_MAGIC ISC_MAGIC('D','S','T','C')
+#define KEY_MAGIC ISC_MAGIC('D','S','T','K')
+#define CTX_MAGIC ISC_MAGIC('D','S','T','C')
#define VALID_KEY(x) ISC_MAGIC_VALID(x, KEY_MAGIC)
#define VALID_CTX(x) ISC_MAGIC_VALID(x, CTX_MAGIC)
@@ -74,7 +77,7 @@ extern isc_mem_t *dst__memory_pool;
typedef struct dst_func dst_func_t;
-typedef struct dst_hmacmd5_key dst_hmacmd5_key_t;
+typedef struct dst_hmacmd5_key dst_hmacmd5_key_t;
typedef struct dst_hmacsha1_key dst_hmacsha1_key_t;
typedef struct dst_hmacsha224_key dst_hmacsha224_key_t;
typedef struct dst_hmacsha256_key dst_hmacsha256_key_t;
@@ -115,7 +118,17 @@ struct dst_key {
dst_hmacsha512_key_t *hmacsha512;
} keydata; /*%< pointer to key in crypto pkg fmt */
- dst_func_t * func; /*%< crypto package specific functions */
+
+ isc_stdtime_t times[DST_MAX_TIMES + 1]; /*%< timing metadata */
+ isc_boolean_t timeset[DST_MAX_TIMES + 1]; /*%< data set? */
+ isc_stdtime_t nums[DST_MAX_NUMERIC + 1]; /*%< numeric metadata */
+ isc_boolean_t numset[DST_MAX_NUMERIC + 1]; /*%< data set? */
+
+ int fmt_major; /*%< private key format, major version */
+ int fmt_minor; /*%< private key format, minor version */
+
+ dst_func_t * func; /*%< crypto package specific functions */
+ isc_buffer_t *key_tkeytoken; /*%< TKEY token data */
};
struct dst_context {
@@ -160,7 +173,8 @@ struct dst_func {
isc_boolean_t (*compare)(const dst_key_t *key1, const dst_key_t *key2);
isc_boolean_t (*paramcompare)(const dst_key_t *key1,
const dst_key_t *key2);
- isc_result_t (*generate)(dst_key_t *key, int parms);
+ isc_result_t (*generate)(dst_key_t *key, int parms,
+ void (*callback)(int));
isc_boolean_t (*isprivate)(const dst_key_t *key);
void (*destroy)(dst_key_t *key);
@@ -168,19 +182,24 @@ struct dst_func {
isc_result_t (*todns)(const dst_key_t *key, isc_buffer_t *data);
isc_result_t (*fromdns)(dst_key_t *key, isc_buffer_t *data);
isc_result_t (*tofile)(const dst_key_t *key, const char *directory);
- isc_result_t (*parse)(dst_key_t *key, isc_lex_t *lexer);
+ isc_result_t (*parse)(dst_key_t *key,
+ isc_lex_t *lexer,
+ dst_key_t *pub);
/* cleanup */
void (*cleanup)(void);
isc_result_t (*fromlabel)(dst_key_t *key, const char *engine,
const char *label, const char *pin);
+ isc_result_t (*dump)(dst_key_t *key, isc_mem_t *mctx, char **buffer,
+ int *length);
+ isc_result_t (*restore)(dst_key_t *key, const char *keystr);
};
/*%
* Initializers
*/
-isc_result_t dst__openssl_init(void);
+isc_result_t dst__openssl_init(const char *engine);
isc_result_t dst__hmacmd5_init(struct dst_func **funcp);
isc_result_t dst__hmacsha1_init(struct dst_func **funcp);
@@ -193,6 +212,9 @@ isc_result_t dst__opensslrsa_init(struct dst_func **funcp,
isc_result_t dst__openssldsa_init(struct dst_func **funcp);
isc_result_t dst__openssldh_init(struct dst_func **funcp);
isc_result_t dst__gssapi_init(struct dst_func **funcp);
+#ifdef HAVE_OPENSSL_GOST
+isc_result_t dst__opensslgost_init(struct dst_func **funcp);
+#endif
/*%
* Destructors
diff --git a/lib/dns/dst_openssl.h b/lib/dns/dst_openssl.h
index a095d45ee936..781085b73a0f 100644
--- a/lib/dns/dst_openssl.h
+++ b/lib/dns/dst_openssl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst_openssl.h,v 1.7 2008-04-01 23:47:10 tbox Exp $ */
+/* $Id: dst_openssl.h,v 1.9 2009-10-06 04:40:14 tbox Exp $ */
#ifndef DST_OPENSSL_H
#define DST_OPENSSL_H 1
@@ -29,10 +29,7 @@ isc_result_t
dst__openssl_toresult(isc_result_t fallback);
ENGINE *
-dst__openssl_getengine(const char *name);
-
-isc_result_t
-dst__openssl_setdefault(const char *name);
+dst__openssl_getengine(const char *engine);
ISC_LANG_ENDDECLS
diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c
index 37264be35188..4d7d784f6370 100644
--- a/lib/dns/dst_parse.c
+++ b/lib/dns/dst_parse.c
@@ -31,7 +31,7 @@
/*%
* Principal Author: Brian Wellington
- * $Id: dst_parse.c,v 1.14.120.6 2010-01-15 19:38:53 each Exp $
+ * $Id: dst_parse.c,v 1.27 2010-12-23 04:07:58 marka Exp $
*/
#include <config.h>
@@ -41,9 +41,12 @@
#include <isc/fsaccess.h>
#include <isc/lex.h>
#include <isc/mem.h>
+#include <isc/stdtime.h>
#include <isc/string.h>
#include <isc/util.h>
+#include <dns/time.h>
+
#include "dst_internal.h"
#include "dst_parse.h"
#include "dst/result.h"
@@ -53,6 +56,25 @@
#define PRIVATE_KEY_STR "Private-key-format:"
#define ALGORITHM_STR "Algorithm:"
+#define TIMING_NTAGS (DST_MAX_TIMES + 1)
+static const char *timetags[TIMING_NTAGS] = {
+ "Created:",
+ "Publish:",
+ "Activate:",
+ "Revoke:",
+ "Inactive:",
+ "Delete:",
+ "DSPublish:"
+};
+
+#define NUMERIC_NTAGS (DST_MAX_NUMERIC + 1)
+static const char *numerictags[NUMERIC_NTAGS] = {
+ "Predecessor:",
+ "Successor:",
+ "MaxTTL:",
+ "RollPeriod:"
+};
+
struct parse_map {
const int value;
const char *tag;
@@ -82,6 +104,8 @@ static struct parse_map map[] = {
{TAG_DSA_PRIVATE, "Private_value(x):"},
{TAG_DSA_PUBLIC, "Public_value(y):"},
+ {TAG_GOST_PRIVASN1, "GostAsn1:"},
+
{TAG_HMACMD5_KEY, "Key:"},
{TAG_HMACMD5_BITS, "Bits:"},
@@ -107,13 +131,12 @@ static int
find_value(const char *s, const unsigned int alg) {
int i;
- for (i = 0; ; i++) {
- if (map[i].tag == NULL)
- return (-1);
- else if (strcasecmp(s, map[i].tag) == 0 &&
- TAG_ALG(map[i].value) == alg)
+ for (i = 0; map[i].tag != NULL; i++) {
+ if (strcasecmp(s, map[i].tag) == 0 &&
+ (TAG_ALG(map[i].value) == alg))
return (map[i].value);
}
+ return (-1);
}
static const char *
@@ -129,6 +152,28 @@ find_tag(const int value) {
}
static int
+find_metadata(const char *s, const char *tags[], int ntags) {
+ int i;
+
+ for (i = 0; i < ntags; i++) {
+ if (strcasecmp(s, tags[i]) == 0)
+ return (i);
+ }
+
+ return (-1);
+}
+
+static int
+find_timedata(const char *s) {
+ return (find_metadata(s, timetags, TIMING_NTAGS));
+}
+
+static int
+find_numericdata(const char *s) {
+ return (find_metadata(s, numerictags, NUMERIC_NTAGS));
+}
+
+static int
check_rsa(const dst_private_t *priv) {
int i, j;
isc_boolean_t have[RSA_NTAGS];
@@ -197,6 +242,15 @@ check_dsa(const dst_private_t *priv) {
}
static int
+check_gost(const dst_private_t *priv) {
+ if (priv->nelements != GOST_NTAGS)
+ return (-1);
+ if (priv->elements[0].tag != TAG(DST_ALG_ECCGOST, 0))
+ return (-1);
+ return (0);
+}
+
+static int
check_hmac_md5(const dst_private_t *priv, isc_boolean_t old) {
int i, j;
@@ -253,6 +307,8 @@ check_data(const dst_private_t *priv, const unsigned int alg,
return (check_dh(priv));
case DST_ALG_DSA:
return (check_dsa(priv));
+ case DST_ALG_ECCGOST:
+ return (check_gost(priv));
case DST_ALG_HMACMD5:
return (check_hmac_md5(priv, old));
case DST_ALG_HMACSHA1:
@@ -285,7 +341,7 @@ dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx) {
priv->nelements = 0;
}
-int
+isc_result_t
dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
isc_mem_t *mctx, dst_private_t *priv)
{
@@ -294,6 +350,7 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
isc_token_t token;
unsigned char *data = NULL;
unsigned int opt = ISC_LEXOPT_EOL;
+ isc_stdtime_t when;
isc_result_t ret;
REQUIRE(priv != NULL);
@@ -341,13 +398,16 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
goto fail;
}
- if (major > MAJOR_VERSION ||
- (major == MAJOR_VERSION && minor > MINOR_VERSION))
- {
+ if (major > DST_MAJOR_VERSION) {
ret = DST_R_INVALIDPRIVATEKEY;
goto fail;
}
+ /*
+ * Store the private key format version number
+ */
+ dst_key_setprivateformat(key, major, minor);
+
READLINE(lex, opt, &token);
/*
@@ -377,7 +437,6 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
for (n = 0; n < MAXFIELDS; n++) {
int tag;
isc_region_t r;
-
do {
ret = isc_lex_gettoken(lex, opt, &token);
if (ret == ISC_R_EOF)
@@ -391,11 +450,50 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
goto fail;
}
+ /* Numeric metadata */
+ tag = find_numericdata(DST_AS_STR(token));
+ if (tag >= 0) {
+ INSIST(tag < NUMERIC_NTAGS);
+
+ NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token);
+ if (token.type != isc_tokentype_number) {
+ ret = DST_R_INVALIDPRIVATEKEY;
+ goto fail;
+ }
+
+ dst_key_setnum(key, tag, token.value.as_ulong);
+ goto next;
+ }
+
+ /* Timing metadata */
+ tag = find_timedata(DST_AS_STR(token));
+ if (tag >= 0) {
+ INSIST(tag < TIMING_NTAGS);
+
+ NEXTTOKEN(lex, opt, &token);
+ if (token.type != isc_tokentype_string) {
+ ret = DST_R_INVALIDPRIVATEKEY;
+ goto fail;
+ }
+
+ ret = dns_time32_fromtext(DST_AS_STR(token), &when);
+ if (ret != ISC_R_SUCCESS)
+ goto fail;
+
+ dst_key_settime(key, tag, when);
+
+ goto next;
+ }
+
+ /* Key data */
tag = find_value(DST_AS_STR(token), alg);
- if (tag < 0 || TAG_ALG(tag) != alg) {
+ if (tag < 0 && minor > DST_MINOR_VERSION)
+ goto next;
+ else if (tag < 0) {
ret = DST_R_INVALIDPRIVATEKEY;
goto fail;
}
+
priv->elements[n].tag = tag;
data = (unsigned char *) isc_mem_get(mctx, MAXFIELDSIZE);
@@ -406,23 +504,23 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
ret = isc_base64_tobuffer(lex, &b, -1);
if (ret != ISC_R_SUCCESS)
goto fail;
+
isc_buffer_usedregion(&b, &r);
priv->elements[n].length = r.length;
priv->elements[n].data = r.base;
+ priv->nelements++;
+ next:
READLINE(lex, opt, &token);
data = NULL;
}
done:
- priv->nelements = n;
-
if (check_data(priv, alg, ISC_TRUE) < 0)
goto fail;
return (ISC_R_SUCCESS);
fail:
- priv->nelements = n;
dst__privstruct_free(priv, mctx);
if (data != NULL)
isc_mem_put(mctx, data, MAXFIELDSIZE);
@@ -430,17 +528,21 @@ fail:
return (ret);
}
-int
+isc_result_t
dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
const char *directory)
{
FILE *fp;
int ret, i;
- isc_result_t iret;
+ isc_result_t result;
char filename[ISC_DIR_NAMEMAX];
char buffer[MAXFIELDSIZE * 2];
- isc_buffer_t b;
isc_fsaccess_t access;
+ isc_stdtime_t when;
+ isc_uint32_t value;
+ isc_buffer_t b;
+ isc_region_t r;
+ int major, minor;
REQUIRE(priv != NULL);
@@ -461,11 +563,17 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
&access);
(void)isc_fsaccess_set(filename, access);
+ dst_key_getprivateformat(key, &major, &minor);
+ if (major == 0 && minor == 0) {
+ major = DST_MAJOR_VERSION;
+ minor = DST_MINOR_VERSION;
+ }
+
/* XXXDCL return value should be checked for full filesystem */
- fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, MAJOR_VERSION,
- MINOR_VERSION);
+ fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, major, minor);
fprintf(fp, "%s %d ", ALGORITHM_STR, dst_key_alg(key));
+
/* XXXVIX this switch statement is too sparse to gen a jump table. */
switch (dst_key_alg(key)) {
case DST_ALG_RSAMD5:
@@ -480,18 +588,21 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
case DST_ALG_RSASHA1:
fprintf(fp, "(RSASHA1)\n");
break;
- case DST_ALG_NSEC3DSA:
- fprintf(fp, "(NSEC3DSA)\n");
- break;
case DST_ALG_NSEC3RSASHA1:
fprintf(fp, "(NSEC3RSASHA1)\n");
break;
+ case DST_ALG_NSEC3DSA:
+ fprintf(fp, "(NSEC3DSA)\n");
+ break;
case DST_ALG_RSASHA256:
fprintf(fp, "(RSASHA256)\n");
break;
case DST_ALG_RSASHA512:
fprintf(fp, "(RSASHA512)\n");
break;
+ case DST_ALG_ECCGOST:
+ fprintf(fp, "(ECC-GOST)\n");
+ break;
case DST_ALG_HMACMD5:
fprintf(fp, "(HMAC_MD5)\n");
break;
@@ -516,8 +627,6 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
}
for (i = 0; i < priv->nelements; i++) {
- isc_buffer_t b;
- isc_region_t r;
const char *s;
s = find_tag(priv->elements[i].tag);
@@ -525,8 +634,8 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
r.base = priv->elements[i].data;
r.length = priv->elements[i].length;
isc_buffer_init(&b, buffer, sizeof(buffer));
- iret = isc_base64_totext(&r, sizeof(buffer), "", &b);
- if (iret != ISC_R_SUCCESS) {
+ result = isc_base64_totext(&r, sizeof(buffer), "", &b);
+ if (result != ISC_R_SUCCESS) {
fclose(fp);
return (DST_R_INVALIDPRIVATEKEY);
}
@@ -537,10 +646,36 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
fprintf(fp, "\n");
}
+ /* Add the metadata tags */
+ if (major > 1 || (major == 1 && minor >= 3)) {
+ for (i = 0; i < NUMERIC_NTAGS; i++) {
+ result = dst_key_getnum(key, i, &value);
+ if (result != ISC_R_SUCCESS)
+ continue;
+ fprintf(fp, "%s %u\n", numerictags[i], value);
+ }
+ for (i = 0; i < TIMING_NTAGS; i++) {
+ result = dst_key_gettime(key, i, &when);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ isc_buffer_init(&b, buffer, sizeof(buffer));
+ result = dns_time32_totext(when, &b);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ isc_buffer_usedregion(&b, &r);
+
+ fprintf(fp, "%s ", timetags[i]);
+ isc_util_fwrite(r.base, 1, r.length, fp);
+ fprintf(fp, "\n");
+ }
+ }
+
fflush(fp);
- iret = ferror(fp) ? DST_R_WRITEERROR : ISC_R_SUCCESS;
+ result = ferror(fp) ? DST_R_WRITEERROR : ISC_R_SUCCESS;
fclose(fp);
- return (iret);
+ return (result);
}
/*! \file */
diff --git a/lib/dns/dst_parse.h b/lib/dns/dst_parse.h
index 11e2b3355812..d1034ce6edfb 100644
--- a/lib/dns/dst_parse.h
+++ b/lib/dns/dst_parse.h
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst_parse.h,v 1.11 2008-05-15 00:50:26 each Exp $ */
+/* $Id: dst_parse.h,v 1.17 2010-12-23 23:47:08 tbox Exp $ */
/*! \file */
#ifndef DST_DST_PARSE_H
@@ -39,11 +39,13 @@
#include <dst/dst.h>
-#define MAJOR_VERSION 1
-#define MINOR_VERSION 2
-
#define MAXFIELDSIZE 512
-#define MAXFIELDS 12
+
+/*
+ * Maximum number of fields in a private file is 18 (12 algorithm-
+ * specific fields for RSA, plus 6 generic fields).
+ */
+#define MAXFIELDS 12+6
#define TAG_SHIFT 4
#define TAG_ALG(tag) ((unsigned int)(tag) >> TAG_SHIFT)
@@ -76,6 +78,9 @@
#define TAG_DSA_PRIVATE ((DST_ALG_DSA << TAG_SHIFT) + 3)
#define TAG_DSA_PUBLIC ((DST_ALG_DSA << TAG_SHIFT) + 4)
+#define GOST_NTAGS 1
+#define TAG_GOST_PRIVASN1 ((DST_ALG_ECCGOST << TAG_SHIFT) + 0)
+
#define OLD_HMACMD5_NTAGS 1
#define HMACMD5_NTAGS 2
#define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0)
@@ -121,11 +126,11 @@ ISC_LANG_BEGINDECLS
void
dst__privstruct_free(dst_private_t *priv, isc_mem_t *mctx);
-int
+isc_result_t
dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
isc_mem_t *mctx, dst_private_t *priv);
-int
+isc_result_t
dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
const char *directory);
diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c
new file mode 100644
index 000000000000..d98a3eb83c69
--- /dev/null
+++ b/lib/dns/ecdb.c
@@ -0,0 +1,810 @@
+/*
+ * Copyright (C) 2009-2011 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ecdb.c,v 1.8 2011-01-14 00:51:43 tbox Exp $ */
+
+#include "config.h"
+
+#include <isc/result.h>
+#include <isc/util.h>
+#include <isc/mutex.h>
+#include <isc/mem.h>
+
+#include <dns/db.h>
+#include <dns/ecdb.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatasetiter.h>
+#include <dns/rdataslab.h>
+
+#define ECDB_MAGIC ISC_MAGIC('E', 'C', 'D', 'B')
+#define VALID_ECDB(db) ((db) != NULL && \
+ (db)->common.impmagic == ECDB_MAGIC)
+
+#define ECDBNODE_MAGIC ISC_MAGIC('E', 'C', 'D', 'N')
+#define VALID_ECDBNODE(ecdbn) ISC_MAGIC_VALID(ecdbn, ECDBNODE_MAGIC)
+
+#if DNS_RDATASET_FIXED
+#error "Fixed rdataset isn't supported in this implementation"
+#endif
+
+/*%
+ * The 'ephemeral' cache DB (ecdb) implementation. An ecdb just provides
+ * temporary storage for ongoing name resolution with the common DB interfaces.
+ * It actually doesn't cache anything. The implementation expects any stored
+ * data is released within a short period, and does not care about the
+ * scalability in terms of the number of nodes.
+ */
+
+typedef struct dns_ecdb {
+ /* Unlocked */
+ dns_db_t common;
+ isc_mutex_t lock;
+
+ /* Locked */
+ unsigned int references;
+ ISC_LIST(struct dns_ecdbnode) nodes;
+} dns_ecdb_t;
+
+typedef struct dns_ecdbnode {
+ /* Unlocked */
+ unsigned int magic;
+ isc_mutex_t lock;
+ dns_ecdb_t *ecdb;
+ dns_name_t name;
+ ISC_LINK(struct dns_ecdbnode) link;
+
+ /* Locked */
+ ISC_LIST(struct rdatasetheader) rdatasets;
+ unsigned int references;
+} dns_ecdbnode_t;
+
+typedef struct rdatasetheader {
+ dns_rdatatype_t type;
+ dns_ttl_t ttl;
+ dns_trust_t trust;
+ dns_rdatatype_t covers;
+ unsigned int attributes;
+
+ ISC_LINK(struct rdatasetheader) link;
+} rdatasetheader_t;
+
+/* Copied from rbtdb.c */
+#define RDATASET_ATTR_NXDOMAIN 0x0010
+#define NXDOMAIN(header) \
+ (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
+
+static isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin,
+ dns_dbtype_t type,
+ dns_rdataclass_t rdclass,
+ unsigned int argc, char *argv[],
+ void *driverarg, dns_db_t **dbp);
+
+static void rdataset_disassociate(dns_rdataset_t *rdataset);
+static isc_result_t rdataset_first(dns_rdataset_t *rdataset);
+static isc_result_t rdataset_next(dns_rdataset_t *rdataset);
+static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
+static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target);
+static unsigned int rdataset_count(dns_rdataset_t *rdataset);
+static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
+
+static dns_rdatasetmethods_t rdataset_methods = {
+ rdataset_disassociate,
+ rdataset_first,
+ rdataset_next,
+ rdataset_current,
+ rdataset_clone,
+ rdataset_count,
+ NULL, /* addnoqname */
+ NULL, /* getnoqname */
+ NULL, /* addclosest */
+ NULL, /* getclosest */
+ NULL, /* getadditional */
+ NULL, /* setadditional */
+ NULL, /* putadditional */
+ rdataset_settrust, /* settrust */
+ NULL /* expire */
+};
+
+typedef struct ecdb_rdatasetiter {
+ dns_rdatasetiter_t common;
+ rdatasetheader_t *current;
+} ecdb_rdatasetiter_t;
+
+static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
+static isc_result_t rdatasetiter_first(dns_rdatasetiter_t *iterator);
+static isc_result_t rdatasetiter_next(dns_rdatasetiter_t *iterator);
+static void rdatasetiter_current(dns_rdatasetiter_t *iterator,
+ dns_rdataset_t *rdataset);
+
+static dns_rdatasetitermethods_t rdatasetiter_methods = {
+ rdatasetiter_destroy,
+ rdatasetiter_first,
+ rdatasetiter_next,
+ rdatasetiter_current
+};
+
+isc_result_t
+dns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp) {
+ REQUIRE(mctx != NULL);
+ REQUIRE(dbimp != NULL && *dbimp == NULL);
+
+ return (dns_db_register("ecdb", dns_ecdb_create, NULL, mctx, dbimp));
+}
+
+void
+dns_ecdb_unregister(dns_dbimplementation_t **dbimp) {
+ REQUIRE(dbimp != NULL && *dbimp != NULL);
+
+ dns_db_unregister(dbimp);
+}
+
+/*%
+ * DB routines
+ */
+
+static void
+attach(dns_db_t *source, dns_db_t **targetp) {
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)source;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+
+ LOCK(&ecdb->lock);
+ ecdb->references++;
+ UNLOCK(&ecdb->lock);
+
+ *targetp = source;
+}
+
+static void
+destroy_ecdb(dns_ecdb_t **ecdbp) {
+ dns_ecdb_t *ecdb = *ecdbp;
+ isc_mem_t *mctx = ecdb->common.mctx;
+
+ if (dns_name_dynamic(&ecdb->common.origin))
+ dns_name_free(&ecdb->common.origin, mctx);
+
+ DESTROYLOCK(&ecdb->lock);
+
+ ecdb->common.impmagic = 0;
+ ecdb->common.magic = 0;
+
+ isc_mem_putanddetach(&mctx, ecdb, sizeof(*ecdb));
+
+ *ecdbp = NULL;
+}
+
+static void
+detach(dns_db_t **dbp) {
+ dns_ecdb_t *ecdb;
+ isc_boolean_t need_destroy = ISC_FALSE;
+
+ REQUIRE(dbp != NULL);
+ ecdb = (dns_ecdb_t *)*dbp;
+ REQUIRE(VALID_ECDB(ecdb));
+
+ LOCK(&ecdb->lock);
+ ecdb->references--;
+ if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
+ need_destroy = ISC_TRUE;
+ UNLOCK(&ecdb->lock);
+
+ if (need_destroy)
+ destroy_ecdb(&ecdb);
+
+ *dbp = NULL;
+}
+
+static void
+attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+ dns_ecdbnode_t *node = (dns_ecdbnode_t *)source;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(VALID_ECDBNODE(node));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+
+ LOCK(&node->lock);
+ INSIST(node->references > 0);
+ node->references++;
+ INSIST(node->references != 0); /* Catch overflow. */
+ UNLOCK(&node->lock);
+
+ *targetp = node;
+}
+
+static void
+destroynode(dns_ecdbnode_t *node) {
+ isc_mem_t *mctx;
+ dns_ecdb_t *ecdb = node->ecdb;
+ isc_boolean_t need_destroydb = ISC_FALSE;
+ rdatasetheader_t *header;
+
+ mctx = ecdb->common.mctx;
+
+ LOCK(&ecdb->lock);
+ ISC_LIST_UNLINK(ecdb->nodes, node, link);
+ if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
+ need_destroydb = ISC_TRUE;
+ UNLOCK(&ecdb->lock);
+
+ dns_name_free(&node->name, mctx);
+
+ while ((header = ISC_LIST_HEAD(node->rdatasets)) != NULL) {
+ unsigned int headersize;
+
+ ISC_LIST_UNLINK(node->rdatasets, header, link);
+ headersize =
+ dns_rdataslab_size((unsigned char *)header,
+ sizeof(*header));
+ isc_mem_put(mctx, header, headersize);
+ }
+
+ DESTROYLOCK(&node->lock);
+
+ node->magic = 0;
+ isc_mem_put(mctx, node, sizeof(*node));
+
+ if (need_destroydb)
+ destroy_ecdb(&ecdb);
+}
+
+static void
+detachnode(dns_db_t *db, dns_dbnode_t **nodep) {
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+ dns_ecdbnode_t *node;
+ isc_boolean_t need_destroy = ISC_FALSE;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(nodep != NULL);
+ node = (dns_ecdbnode_t *)*nodep;
+ REQUIRE(VALID_ECDBNODE(node));
+
+ UNUSED(ecdb); /* in case REQUIRE() is empty */
+
+ LOCK(&node->lock);
+ INSIST(node->references > 0);
+ node->references--;
+ if (node->references == 0)
+ need_destroy = ISC_TRUE;
+ UNLOCK(&node->lock);
+
+ if (need_destroy)
+ destroynode(node);
+
+ *nodep = NULL;
+}
+
+static isc_result_t
+find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
+ dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
+ dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset,
+ dns_rdataset_t *sigrdataset)
+{
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+
+ REQUIRE(VALID_ECDB(ecdb));
+
+ UNUSED(name);
+ UNUSED(version);
+ UNUSED(type);
+ UNUSED(options);
+ UNUSED(now);
+ UNUSED(nodep);
+ UNUSED(foundname);
+ UNUSED(rdataset);
+ UNUSED(sigrdataset);
+
+ return (ISC_R_NOTFOUND);
+}
+
+static isc_result_t
+findzonecut(dns_db_t *db, dns_name_t *name,
+ unsigned int options, isc_stdtime_t now,
+ dns_dbnode_t **nodep, dns_name_t *foundname,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
+{
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+
+ REQUIRE(VALID_ECDB(ecdb));
+
+ UNUSED(name);
+ UNUSED(options);
+ UNUSED(now);
+ UNUSED(nodep);
+ UNUSED(foundname);
+ UNUSED(rdataset);
+ UNUSED(sigrdataset);
+
+ return (ISC_R_NOTFOUND);
+}
+
+static isc_result_t
+findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
+ dns_dbnode_t **nodep)
+{
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+ isc_mem_t *mctx;
+ dns_ecdbnode_t *node;
+ isc_result_t result;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(nodep != NULL && *nodep == NULL);
+
+ UNUSED(name);
+
+ if (create != ISC_TRUE) {
+ /* an 'ephemeral' node is never reused. */
+ return (ISC_R_NOTFOUND);
+ }
+
+ mctx = ecdb->common.mctx;
+ node = isc_mem_get(mctx, sizeof(*node));
+ if (node == NULL)
+ return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&node->lock);
+ if (result != ISC_R_SUCCESS) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_mutex_init() failed: %s",
+ isc_result_totext(result));
+ isc_mem_put(mctx, node, sizeof(*node));
+ return (ISC_R_UNEXPECTED);
+ }
+
+ dns_name_init(&node->name, NULL);
+ result = dns_name_dup(name, mctx, &node->name);
+ if (result != ISC_R_SUCCESS) {
+ DESTROYLOCK(&node->lock);
+ isc_mem_put(mctx, node, sizeof(*node));
+ return (result);
+ }
+ node->ecdb= ecdb;
+ node->references = 1;
+ ISC_LIST_INIT(node->rdatasets);
+
+ ISC_LINK_INIT(node, link);
+
+ LOCK(&ecdb->lock);
+ ISC_LIST_APPEND(ecdb->nodes, node, link);
+ UNLOCK(&ecdb->lock);
+
+ node->magic = ECDBNODE_MAGIC;
+
+ *nodep = node;
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+bind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node,
+ rdatasetheader_t *header, dns_rdataset_t *rdataset)
+{
+ unsigned char *raw;
+
+ /*
+ * Caller must be holding the node lock.
+ */
+
+ REQUIRE(!dns_rdataset_isassociated(rdataset));
+
+ rdataset->methods = &rdataset_methods;
+ rdataset->rdclass = ecdb->common.rdclass;
+ rdataset->type = header->type;
+ rdataset->covers = header->covers;
+ rdataset->ttl = header->ttl;
+ rdataset->trust = header->trust;
+ if (NXDOMAIN(header))
+ rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN;
+
+ rdataset->private1 = ecdb;
+ rdataset->private2 = node;
+ raw = (unsigned char *)header + sizeof(*header);
+ rdataset->private3 = raw;
+ rdataset->count = 0;
+
+ /*
+ * Reset iterator state.
+ */
+ rdataset->privateuint4 = 0;
+ rdataset->private5 = NULL;
+
+ INSIST(node->references > 0);
+ node->references++;
+}
+
+static isc_result_t
+addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
+ isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
+ dns_rdataset_t *addedrdataset)
+{
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+ isc_region_t r;
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_mem_t *mctx;
+ dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node;
+ rdatasetheader_t *header;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(VALID_ECDBNODE(ecdbnode));
+
+ UNUSED(version);
+ UNUSED(now);
+ UNUSED(options);
+
+ mctx = ecdb->common.mctx;
+
+ LOCK(&ecdbnode->lock);
+
+ /*
+ * Sanity check: this implementation does not allow overriding an
+ * existing rdataset of the same type.
+ */
+ for (header = ISC_LIST_HEAD(ecdbnode->rdatasets); header != NULL;
+ header = ISC_LIST_NEXT(header, link)) {
+ INSIST(header->type != rdataset->type ||
+ header->covers != rdataset->covers);
+ }
+
+ result = dns_rdataslab_fromrdataset(rdataset, mctx,
+ &r, sizeof(rdatasetheader_t));
+ if (result != ISC_R_SUCCESS)
+ goto unlock;
+
+ header = (rdatasetheader_t *)r.base;
+ header->type = rdataset->type;
+ header->ttl = rdataset->ttl;
+ header->trust = rdataset->trust;
+ header->covers = rdataset->covers;
+ header->attributes = 0;
+ if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
+ header->attributes |= RDATASET_ATTR_NXDOMAIN;
+ ISC_LINK_INIT(header, link);
+ ISC_LIST_APPEND(ecdbnode->rdatasets, header, link);
+
+ if (addedrdataset == NULL)
+ goto unlock;
+
+ bind_rdataset(ecdb, ecdbnode, header, addedrdataset);
+
+ unlock:
+ UNLOCK(&ecdbnode->lock);
+
+ return (result);
+}
+
+static isc_result_t
+deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
+ dns_rdatatype_t type, dns_rdatatype_t covers)
+{
+ UNUSED(db);
+ UNUSED(node);
+ UNUSED(version);
+ UNUSED(type);
+ UNUSED(covers);
+
+ return (ISC_R_NOTIMPLEMENTED);
+}
+
+static isc_result_t
+createiterator(dns_db_t *db, unsigned int options,
+ dns_dbiterator_t **iteratorp)
+{
+ UNUSED(db);
+ UNUSED(options);
+ UNUSED(iteratorp);
+
+ return (ISC_R_NOTIMPLEMENTED);
+}
+
+static isc_result_t
+allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
+ isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
+{
+ dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
+ dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)node;
+ isc_mem_t *mctx;
+ ecdb_rdatasetiter_t *iterator;
+
+ REQUIRE(VALID_ECDB(ecdb));
+ REQUIRE(VALID_ECDBNODE(ecdbnode));
+
+ mctx = ecdb->common.mctx;
+
+ iterator = isc_mem_get(mctx, sizeof(ecdb_rdatasetiter_t));
+ if (iterator == NULL)
+ return (ISC_R_NOMEMORY);
+
+ iterator->common.magic = DNS_RDATASETITER_MAGIC;
+ iterator->common.methods = &rdatasetiter_methods;
+ iterator->common.db = db;
+ iterator->common.node = NULL;
+ attachnode(db, node, &iterator->common.node);
+ iterator->common.version = version;
+ iterator->common.now = now;
+
+ *iteratorp = (dns_rdatasetiter_t *)iterator;
+
+ return (ISC_R_SUCCESS);
+}
+
+static dns_dbmethods_t ecdb_methods = {
+ attach,
+ detach,
+ NULL, /* beginload */
+ NULL, /* endload */
+ NULL, /* dump */
+ NULL, /* currentversion */
+ NULL, /* newversion */
+ NULL, /* attachversion */
+ NULL, /* closeversion */
+ findnode,
+ find,
+ findzonecut,
+ attachnode,
+ detachnode,
+ NULL, /* expirenode */
+ NULL, /* printnode */
+ createiterator, /* createiterator */
+ NULL, /* findrdataset */
+ allrdatasets,
+ addrdataset,
+ NULL, /* subtractrdataset */
+ deleterdataset,
+ NULL, /* issecure */
+ NULL, /* nodecount */
+ NULL, /* ispersistent */
+ NULL, /* overmem */
+ NULL, /* settask */
+ NULL, /* getoriginnode */
+ NULL, /* transfernode */
+ NULL, /* getnsec3parameters */
+ NULL, /* findnsec3node */
+ NULL, /* setsigningtime */
+ NULL, /* getsigningtime */
+ NULL, /* resigned */
+ NULL, /* isdnssec */
+ NULL, /* getrrsetstats */
+ NULL, /* rpz_enabled */
+ NULL /* rpz_findips */
+};
+
+static isc_result_t
+dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type,
+ dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
+ void *driverarg, dns_db_t **dbp)
+{
+ dns_ecdb_t *ecdb;
+ isc_result_t result;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(origin == dns_rootname);
+ REQUIRE(type == dns_dbtype_cache);
+ REQUIRE(dbp != NULL && *dbp == NULL);
+
+ UNUSED(argc);
+ UNUSED(argv);
+ UNUSED(driverarg);
+
+ ecdb = isc_mem_get(mctx, sizeof(*ecdb));
+ if (ecdb == NULL)
+ return (ISC_R_NOMEMORY);
+
+ ecdb->common.attributes = DNS_DBATTR_CACHE;
+ ecdb->common.rdclass = rdclass;
+ ecdb->common.methods = &ecdb_methods;
+ dns_name_init(&ecdb->common.origin, NULL);
+ result = dns_name_dupwithoffsets(origin, mctx, &ecdb->common.origin);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, ecdb, sizeof(*ecdb));
+ return (result);
+ }
+
+ result = isc_mutex_init(&ecdb->lock);
+ if (result != ISC_R_SUCCESS) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_mutex_init() failed: %s",
+ isc_result_totext(result));
+ if (dns_name_dynamic(&ecdb->common.origin))
+ dns_name_free(&ecdb->common.origin, mctx);
+ isc_mem_put(mctx, ecdb, sizeof(*ecdb));
+ return (ISC_R_UNEXPECTED);
+ }
+
+ ecdb->references = 1;
+ ISC_LIST_INIT(ecdb->nodes);
+
+ ecdb->common.mctx = NULL;
+ isc_mem_attach(mctx, &ecdb->common.mctx);
+ ecdb->common.impmagic = ECDB_MAGIC;
+ ecdb->common.magic = DNS_DB_MAGIC;
+
+ *dbp = (dns_db_t *)ecdb;
+
+ return (ISC_R_SUCCESS);
+}
+
+/*%
+ * Rdataset Methods
+ */
+
+static void
+rdataset_disassociate(dns_rdataset_t *rdataset) {
+ dns_db_t *db = rdataset->private1;
+ dns_dbnode_t *node = rdataset->private2;
+
+ dns_db_detachnode(db, &node);
+}
+
+static isc_result_t
+rdataset_first(dns_rdataset_t *rdataset) {
+ unsigned char *raw = rdataset->private3;
+ unsigned int count;
+
+ count = raw[0] * 256 + raw[1];
+ if (count == 0) {
+ rdataset->private5 = NULL;
+ return (ISC_R_NOMORE);
+ }
+ raw += 2;
+ /*
+ * The privateuint4 field is the number of rdata beyond the cursor
+ * position, so we decrement the total count by one before storing
+ * it.
+ */
+ count--;
+ rdataset->privateuint4 = count;
+ rdataset->private5 = raw;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+rdataset_next(dns_rdataset_t *rdataset) {
+ unsigned int count;
+ unsigned int length;
+ unsigned char *raw;
+
+ count = rdataset->privateuint4;
+ if (count == 0)
+ return (ISC_R_NOMORE);
+ count--;
+ rdataset->privateuint4 = count;
+ raw = rdataset->private5;
+ length = raw[0] * 256 + raw[1];
+ raw += length + 2;
+ rdataset->private5 = raw;
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
+ unsigned char *raw = rdataset->private5;
+ isc_region_t r;
+ unsigned int length;
+ unsigned int flags = 0;
+
+ REQUIRE(raw != NULL);
+
+ length = raw[0] * 256 + raw[1];
+ raw += 2;
+ if (rdataset->type == dns_rdatatype_rrsig) {
+ if (*raw & DNS_RDATASLAB_OFFLINE)
+ flags |= DNS_RDATA_OFFLINE;
+ length--;
+ raw++;
+ }
+ r.length = length;
+ r.base = raw;
+ dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
+ rdata->flags |= flags;
+}
+
+static void
+rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
+ dns_db_t *db = source->private1;
+ dns_dbnode_t *node = source->private2;
+ dns_dbnode_t *cloned_node = NULL;
+
+ attachnode(db, node, &cloned_node);
+ *target = *source;
+
+ /*
+ * Reset iterator state.
+ */
+ target->privateuint4 = 0;
+ target->private5 = NULL;
+}
+
+static unsigned int
+rdataset_count(dns_rdataset_t *rdataset) {
+ unsigned char *raw = rdataset->private3;
+ unsigned int count;
+
+ count = raw[0] * 256 + raw[1];
+
+ return (count);
+}
+
+static void
+rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
+ rdatasetheader_t *header = rdataset->private3;
+
+ header--;
+ header->trust = rdataset->trust = trust;
+}
+
+/*
+ * Rdataset Iterator Methods
+ */
+
+static void
+rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
+ ecdb_rdatasetiter_t *ecdbiterator;
+ isc_mem_t *mctx;
+
+ REQUIRE(iteratorp != NULL);
+ ecdbiterator = (ecdb_rdatasetiter_t *)*iteratorp;
+ REQUIRE(DNS_RDATASETITER_VALID(&ecdbiterator->common));
+
+ mctx = ecdbiterator->common.db->mctx;
+
+ ecdbiterator->common.magic = 0;
+
+ dns_db_detachnode(ecdbiterator->common.db, &ecdbiterator->common.node);
+ isc_mem_put(mctx, ecdbiterator, sizeof(ecdb_rdatasetiter_t));
+
+ *iteratorp = NULL;
+}
+
+static isc_result_t
+rdatasetiter_first(dns_rdatasetiter_t *iterator) {
+ ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
+ dns_ecdbnode_t *ecdbnode = (dns_ecdbnode_t *)iterator->node;
+
+ REQUIRE(DNS_RDATASETITER_VALID(iterator));
+
+ if (ISC_LIST_EMPTY(ecdbnode->rdatasets))
+ return (ISC_R_NOMORE);
+ ecdbiterator->current = ISC_LIST_HEAD(ecdbnode->rdatasets);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+rdatasetiter_next(dns_rdatasetiter_t *iterator) {
+ ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
+
+ REQUIRE(DNS_RDATASETITER_VALID(iterator));
+
+ ecdbiterator->current = ISC_LIST_NEXT(ecdbiterator->current, link);
+ if (ecdbiterator->current == NULL)
+ return (ISC_R_NOMORE);
+ else
+ return (ISC_R_SUCCESS);
+}
+
+static void
+rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
+ ecdb_rdatasetiter_t *ecdbiterator = (ecdb_rdatasetiter_t *)iterator;
+ dns_ecdb_t *ecdb;
+
+ ecdb = (dns_ecdb_t *)iterator->db;
+ REQUIRE(VALID_ECDB(ecdb));
+
+ bind_rdataset(ecdb, iterator->node, ecdbiterator->current, rdataset);
+}
diff --git a/lib/dns/forward.c b/lib/dns/forward.c
index 1406b46f5727..1f9c41a8c7e5 100644
--- a/lib/dns/forward.c
+++ b/lib/dns/forward.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: forward.c,v 1.12 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: forward.c,v 1.14 2009-09-02 23:48:02 tbox Exp $ */
/*! \file */
@@ -133,11 +133,27 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
}
isc_result_t
+dns_fwdtable_delete(dns_fwdtable_t *fwdtable, dns_name_t *name) {
+ isc_result_t result;
+
+ REQUIRE(VALID_FWDTABLE(fwdtable));
+
+ RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
+ result = dns_rbt_deletename(fwdtable->table, name, ISC_FALSE);
+ RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
+
+ if (result == DNS_R_PARTIALMATCH)
+ result = ISC_R_NOTFOUND;
+
+ return (result);
+}
+
+isc_result_t
dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name,
dns_forwarders_t **forwardersp)
{
return (dns_fwdtable_find2(fwdtable, name, NULL, forwardersp));
-}
+}
isc_result_t
dns_fwdtable_find2(dns_fwdtable_t *fwdtable, dns_name_t *name,
diff --git a/lib/dns/gen-unix.h b/lib/dns/gen-unix.h
index 91cd4d597253..47a343d04476 100644
--- a/lib/dns/gen-unix.h
+++ b/lib/dns/gen-unix.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: gen-unix.h,v 1.19.332.2 2009-01-18 23:47:35 tbox Exp $ */
+/* $Id: gen-unix.h,v 1.21 2009-01-17 23:47:42 tbox Exp $ */
/*! \file
* \brief
diff --git a/lib/dns/gen.c b/lib/dns/gen.c
index 6f8ce7d4c28a..f1d46ea4cc32 100644
--- a/lib/dns/gen.c
+++ b/lib/dns/gen.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: gen.c,v 1.83 2008-09-25 04:02:38 tbox Exp $ */
+/* $Id: gen.c,v 1.85 2009-12-04 22:06:37 tbox Exp $ */
/*! \file */
@@ -631,6 +631,8 @@ main(int argc, char **argv) {
TOWIRETYPE, TOWIRECLASS, TOWIREDEF);
doswitch("COMPARESWITCH", "compare", COMPAREARGS,
COMPARETYPE, COMPARECLASS, COMPAREDEF);
+ doswitch("CASECOMPARESWITCH", "casecompare", COMPAREARGS,
+ COMPARETYPE, COMPARECLASS, COMPAREDEF);
doswitch("FROMSTRUCTSWITCH", "fromstruct", FROMSTRUCTARGS,
FROMSTRUCTTYPE, FROMSTRUCTCLASS, FROMSTRUCTDEF);
doswitch("TOSTRUCTSWITCH", "tostruct", TOSTRUCTARGS,
diff --git a/lib/dns/gssapi_link.c b/lib/dns/gssapi_link.c
index a7af67f62688..e14d0eb97162 100644
--- a/lib/dns/gssapi_link.c
+++ b/lib/dns/gssapi_link.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,13 +16,14 @@
*/
/*
- * $Id: gssapi_link.c,v 1.12 2008-11-11 03:55:01 marka Exp $
+ * $Id: gssapi_link.c,v 1.16 2011-01-11 23:47:13 tbox Exp $
*/
#include <config.h>
#ifdef GSSAPI
+#include <isc/base64.h>
#include <isc/buffer.h>
#include <isc/mem.h>
#include <isc/string.h>
@@ -44,6 +45,12 @@
(gb).value = (r).base; \
} while (0)
+#define GBUFFER_TO_REGION(gb, r) \
+ do { \
+ (r).length = (gb).length; \
+ (r).base = (gb).value; \
+ } while (0)
+
struct dst_gssapi_signverifyctx {
isc_buffer_t *buffer;
@@ -254,9 +261,10 @@ gssapi_compare(const dst_key_t *key1, const dst_key_t *key2) {
}
static isc_result_t
-gssapi_generate(dst_key_t *key, int unused) {
+gssapi_generate(dst_key_t *key, int unused, void (*callback)(int)) {
UNUSED(key);
UNUSED(unused);
+ UNUSED(callback);
/* No idea */
return (ISC_R_FAILURE);
@@ -275,6 +283,79 @@ gssapi_destroy(dst_key_t *key) {
key->keydata.gssctx = NULL;
}
+static isc_result_t
+gssapi_restore(dst_key_t *key, const char *keystr) {
+ OM_uint32 major, minor;
+ size_t len;
+ isc_buffer_t *b = NULL;
+ isc_region_t r;
+ gss_buffer_desc gssbuffer;
+ isc_result_t result;
+
+ len = strlen(keystr);
+ if ((len % 4) != 0)
+ return (ISC_R_BADBASE64);
+
+ len = (len / 4) * 3;
+
+ result = isc_buffer_allocate(key->mctx, &b, len);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = isc_base64_decodestring(keystr, b);
+ if (result != ISC_R_SUCCESS) {
+ isc_buffer_free(&b);
+ return (result);
+ }
+
+ isc_buffer_remainingregion(b, &r);
+ REGION_TO_GBUFFER(r, gssbuffer);
+ major = gss_import_sec_context(&minor, &gssbuffer,
+ &key->keydata.gssctx);
+ if (major != GSS_S_COMPLETE) {
+ isc_buffer_free(&b);
+ return (ISC_R_FAILURE);
+ }
+
+ isc_buffer_free(&b);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+gssapi_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) {
+ OM_uint32 major, minor;
+ gss_buffer_desc gssbuffer;
+ size_t len;
+ char *buf;
+ isc_buffer_t b;
+ isc_region_t r;
+ isc_result_t result;
+
+ major = gss_export_sec_context(&minor, &key->keydata.gssctx,
+ &gssbuffer);
+ if (major != GSS_S_COMPLETE) {
+ fprintf(stderr, "gss_export_sec_context -> %d, %d\n",
+ major, minor);
+ return (ISC_R_FAILURE);
+ }
+ if (gssbuffer.length == 0)
+ return (ISC_R_FAILURE);
+ len = ((gssbuffer.length + 2)/3) * 4;
+ buf = isc_mem_get(mctx, len);
+ if (buf == NULL) {
+ gss_release_buffer(&minor, &gssbuffer);
+ return (ISC_R_NOMEMORY);
+ }
+ isc_buffer_init(&b, buf, len);
+ GBUFFER_TO_REGION(gssbuffer, r);
+ result = isc_base64_totext(&r, 0, "", &b);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ gss_release_buffer(&minor, &gssbuffer);
+ *buffer = buf;
+ *length = len;
+ return (ISC_R_SUCCESS);
+}
+
static dst_func_t gssapi_functions = {
gssapi_create_signverify_ctx,
gssapi_destroy_signverify_ctx,
@@ -292,7 +373,9 @@ static dst_func_t gssapi_functions = {
NULL, /*%< tofile */
NULL, /*%< parse */
NULL, /*%< cleanup */
- NULL /*%< fromlabel */
+ NULL, /*%< fromlabel */
+ gssapi_dump,
+ gssapi_restore,
};
isc_result_t
diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c
index f365a64a44c6..707745cc3139 100644
--- a/lib/dns/gssapictx.c
+++ b/lib/dns/gssapictx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,16 +15,18 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: gssapictx.c,v 1.12.118.5 2010-12-22 02:37:55 marka Exp $ */
+/* $Id: gssapictx.c,v 1.26 2011-01-10 03:49:49 marka Exp $ */
#include <config.h>
+#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <isc/buffer.h>
#include <isc/dir.h>
#include <isc/entropy.h>
+#include <isc/file.h>
#include <isc/lex.h>
#include <isc/mem.h>
#include <isc/once.h>
@@ -201,9 +203,12 @@ log_cred(const gss_cred_id_t cred) {
* - tkey-gssapi-credential doesn't start with DNS/
* - the default realm in /etc/krb5.conf and the
* tkey-gssapi-credential bind config option don't match
+ *
+ * Note that if tkey-gssapi-keytab is set then these configure checks
+ * are not performed, and runtime errors from gssapi are used instead
*/
static void
-dst_gssapi_check_config(const char *gss_name) {
+check_config(const char *gss_name) {
const char *p;
krb5_context krb5_ctx;
char *krb5_realm = NULL;
@@ -263,7 +268,7 @@ dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate,
* here when we're in the acceptor role, which would let us
* default the hostname and use a compiled in default service
* name of "DNS", giving one less thing to configure in
- * named.conf. Unfortunately, this creates a circular
+ * named.conf. Unfortunately, this creates a circular
* dependency due to DNS-based realm lookup in at least one
* GSSAPI implementation (Heimdal). Oh well.
*/
@@ -273,7 +278,7 @@ dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate,
gret = gss_import_name(&minor, &gnamebuf,
GSS_C_NO_OID, &gname);
if (gret != GSS_S_COMPLETE) {
- dst_gssapi_check_config((char *)array);
+ check_config((char *)array);
gss_log(3, "failed gss_import_name: %s",
gss_error_tostring(gret, minor, buf,
@@ -306,7 +311,7 @@ dst_gssapi_acquirecred(dns_name_t *name, isc_boolean_t initiate,
initiate ? "initiate" : "accept",
(char *)gnamebuf.value,
gss_error_tostring(gret, minor, buf, sizeof(buf)));
- dst_gssapi_check_config((char *)array);
+ check_config((char *)array);
return (ISC_R_FAILURE);
}
@@ -361,7 +366,7 @@ dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
rname++;
/*
- * Find the host portion of the signer's name. We do this by
+ * Find the host portion of the signer's name. We do this by
* searching for the first / character. We then check to make
* certain the instance name is "host"
*
@@ -440,7 +445,7 @@ dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name,
return (isc_boolean_false);
/*
- * Find the host portion of the signer's name. Zero out the $ so
+ * Find the host portion of the signer's name. Zero out the $ so
* it terminates the signer's name, and skip past the @ for
* the realm.
*
@@ -454,7 +459,7 @@ dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name,
/*
* Find the first . in the target name, and make it the end of
- * the string. The rest of the name has to match the realm.
+ * the string. The rest of the name has to match the realm.
*/
if (name != NULL) {
nname = strchr(nbuf, '.');
@@ -510,9 +515,34 @@ dst_gssapi_releasecred(gss_cred_id_t *cred) {
#endif
}
+#ifdef GSSAPI
+/*
+ * Format a gssapi error message info into a char ** on the given memory
+ * context. This is used to return gssapi error messages back up the
+ * call chain for reporting to the user.
+ */
+static void
+gss_err_message(isc_mem_t *mctx, isc_uint32_t major, isc_uint32_t minor,
+ char **err_message)
+{
+ char buf[1024];
+ char *estr;
+
+ if (err_message == NULL || mctx == NULL) {
+ /* the caller doesn't want any error messages */
+ return;
+ }
+
+ estr = gss_error_tostring(major, minor, buf, sizeof(buf));
+ if (estr)
+ (*err_message) = isc_mem_strdup(mctx, estr);
+}
+#endif
+
isc_result_t
dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
- isc_buffer_t *outtoken, gss_ctx_id_t *gssctx)
+ isc_buffer_t *outtoken, gss_ctx_id_t *gssctx,
+ isc_mem_t *mctx, char **err_message)
{
#ifdef GSSAPI
isc_region_t r;
@@ -523,10 +553,10 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
isc_result_t result;
gss_buffer_desc gnamebuf;
unsigned char array[DNS_NAME_MAXTEXT + 1];
- char buf[1024];
/* Client must pass us a valid gss_ctx_id_t here */
REQUIRE(gssctx != NULL);
+ REQUIRE(mctx != NULL);
isc_buffer_init(&namebuf, array, sizeof(array));
name_to_gbuffer(name, &namebuf, &gnamebuf);
@@ -534,6 +564,7 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
/* Get the name as a GSS name */
gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname);
if (gret != GSS_S_COMPLETE) {
+ gss_err_message(mctx, gret, minor, err_message);
result = ISC_R_FAILURE;
goto out;
}
@@ -550,8 +581,7 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
* Note that we don't set GSS_C_SEQUENCE_FLAG as Windows DNS
* servers don't like it.
*/
- flags = GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG |
- GSS_C_INTEG_FLAG;
+ flags = GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG;
gret = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, gssctx,
gname, GSS_SPNEGO_MECHANISM, flags,
@@ -559,9 +589,9 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
NULL, &gouttoken, &ret_flags, NULL);
if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) {
- gss_log(3, "Failure initiating security context");
- gss_log(3, "%s", gss_error_tostring(gret, minor,
- buf, sizeof(buf)));
+ gss_err_message(mctx, gret, minor, err_message);
+ gss_log(3, "Failure initiating security context: %s",
+ *err_message);
result = ISC_R_FAILURE;
goto out;
}
@@ -593,6 +623,8 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
UNUSED(intoken);
UNUSED(outtoken);
UNUSED(gssctx);
+ UNUSED(mctx);
+ UNUSED(err_message);
return (ISC_R_NOTIMPLEMENTED);
#endif
@@ -600,6 +632,7 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
isc_result_t
dst_gssapi_acceptctx(gss_cred_id_t cred,
+ const char *gssapi_keytab,
isc_region_t *intoken, isc_buffer_t **outtoken,
gss_ctx_id_t *ctxout, dns_name_t *principal,
isc_mem_t *mctx)
@@ -626,6 +659,34 @@ dst_gssapi_acceptctx(gss_cred_id_t cred,
else
context = *ctxout;
+ if (gssapi_keytab != NULL) {
+#ifdef ISC_PLATFORM_GSSAPI_KRB5_HEADER
+ gret = gsskrb5_register_acceptor_identity(gssapi_keytab);
+ if (gret != GSS_S_COMPLETE) {
+ gss_log(3, "failed "
+ "gsskrb5_register_acceptor_identity(%s): %s",
+ gssapi_keytab,
+ gss_error_tostring(gret, minor,
+ buf, sizeof(buf)));
+ return (DNS_R_INVALIDTKEY);
+ }
+#else
+ /*
+ * Minimize memory leakage by only setting KRB5_KTNAME
+ * if it needs to change.
+ */
+ const char *old = getenv("KRB5_KTNAME");
+ if (old == NULL || strcmp(old, gssapi_keytab) != 0) {
+ char *kt = malloc(strlen(gssapi_keytab) + 13);
+ if (kt == NULL)
+ return (ISC_R_NOMEMORY);
+ sprintf(kt, "KRB5_KTNAME=%s", gssapi_keytab);
+ if (putenv(kt) != 0)
+ return (ISC_R_NOMEMORY);
+ }
+#endif
+ }
+
gret = gss_accept_sec_context(&minor, &context, cred, &gintoken,
GSS_C_NO_CHANNEL_BINDINGS, &gname,
NULL, &gouttoken, NULL, NULL, NULL);
@@ -692,7 +753,7 @@ dst_gssapi_acceptctx(gss_cred_id_t cred,
isc_buffer_add(&namebuf, r.length);
RETERR(dns_name_fromtext(principal, &namebuf, dns_rootname,
- ISC_FALSE, NULL));
+ 0, NULL));
if (gnamebuf.length != 0) {
gret = gss_release_buffer(&minor, &gnamebuf);
@@ -717,6 +778,7 @@ dst_gssapi_acceptctx(gss_cred_id_t cred,
return (result);
#else
UNUSED(cred);
+ UNUSED(gssapi_keytab);
UNUSED(intoken);
UNUSED(outtoken);
UNUSED(ctxout);
diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c
index 5d6dce78c2bc..ecc4089888da 100644
--- a/lib/dns/hmac_link.c
+++ b/lib/dns/hmac_link.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: hmac_link.c,v 1.11 2008-04-01 23:47:10 tbox Exp $
+ * $Id: hmac_link.c,v 1.19 2011-01-11 23:47:13 tbox Exp $
*/
#include <config.h>
@@ -50,14 +50,10 @@
#include "dst_internal.h"
#include "dst_parse.h"
-#define HMAC_LEN 64
-#define HMAC_IPAD 0x36
-#define HMAC_OPAD 0x5c
-
static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data);
struct dst_hmacmd5_key {
- unsigned char key[HMAC_LEN];
+ unsigned char key[ISC_MD5_BLOCK_LENGTH];
};
static isc_result_t
@@ -79,7 +75,7 @@ hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) {
hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t));
if (hmacmd5ctx == NULL)
return (ISC_R_NOMEMORY);
- isc_hmacmd5_init(hmacmd5ctx, hkey->key, HMAC_LEN);
+ isc_hmacmd5_init(hmacmd5ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
dctx->ctxdata.hmacmd5ctx = hmacmd5ctx;
return (ISC_R_SUCCESS);
}
@@ -142,26 +138,28 @@ hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) {
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, HMAC_LEN) == 0)
+ if (memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH) == 0)
return (ISC_TRUE);
else
return (ISC_FALSE);
}
static isc_result_t
-hmacmd5_generate(dst_key_t *key, int pseudorandom_ok) {
+hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) {
isc_buffer_t b;
isc_result_t ret;
- int bytes;
- unsigned char data[HMAC_LEN];
+ unsigned int bytes;
+ unsigned char data[ISC_SHA1_BLOCK_LENGTH];
+
+ UNUSED(callback);
bytes = (key->key_size + 7) / 8;
- if (bytes > HMAC_LEN) {
- bytes = HMAC_LEN;
- key->key_size = HMAC_LEN * 8;
+ if (bytes > ISC_SHA1_BLOCK_LENGTH) {
+ bytes = ISC_SHA1_BLOCK_LENGTH;
+ key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
}
- memset(data, 0, HMAC_LEN);
+ memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
if (ret != ISC_R_SUCCESS)
@@ -170,7 +168,7 @@ hmacmd5_generate(dst_key_t *key, int pseudorandom_ok) {
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
ret = hmacmd5_fromdns(key, &b);
- memset(data, 0, HMAC_LEN);
+ memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
return (ret);
}
@@ -184,6 +182,7 @@ hmacmd5_isprivate(const dst_key_t *key) {
static void
hmacmd5_destroy(dst_key_t *key) {
dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
+
memset(hkey, 0, sizeof(dst_hmacmd5_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacmd5_key_t));
key->keydata.hmacmd5 = NULL;
@@ -223,7 +222,7 @@ hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
memset(hkey->key, 0, sizeof(hkey->key));
- if (r.length > HMAC_LEN) {
+ if (r.length > ISC_SHA1_BLOCK_LENGTH) {
isc_md5_init(&md5ctx);
isc_md5_update(&md5ctx, r.base, r.length);
isc_md5_final(&md5ctx, hkey->key);
@@ -268,15 +267,17 @@ hmacmd5_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
- result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx, &priv);
+ result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx,
+ &priv);
if (result != ISC_R_SUCCESS)
return (result);
@@ -324,6 +325,8 @@ static dst_func_t hmacmd5_functions = {
hmacmd5_parse,
NULL, /*%< cleanup */
NULL, /*%< fromlabel */
+ NULL, /*%< dump */
+ NULL, /*%< restore */
};
isc_result_t
@@ -337,7 +340,7 @@ dst__hmacmd5_init(dst_func_t **funcp) {
static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data);
struct dst_hmacsha1_key {
- unsigned char key[ISC_SHA1_DIGESTLENGTH];
+ unsigned char key[ISC_SHA1_BLOCK_LENGTH];
};
static isc_result_t
@@ -348,7 +351,7 @@ hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) {
hmacsha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha1_t));
if (hmacsha1ctx == NULL)
return (ISC_R_NOMEMORY);
- isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_DIGESTLENGTH);
+ isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
dctx->ctxdata.hmacsha1ctx = hmacsha1ctx;
return (ISC_R_SUCCESS);
}
@@ -411,26 +414,28 @@ hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) {
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, ISC_SHA1_DIGESTLENGTH) == 0)
+ if (memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH) == 0)
return (ISC_TRUE);
else
return (ISC_FALSE);
}
static isc_result_t
-hmacsha1_generate(dst_key_t *key, int pseudorandom_ok) {
+hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) {
isc_buffer_t b;
isc_result_t ret;
- int bytes;
- unsigned char data[HMAC_LEN];
+ unsigned int bytes;
+ unsigned char data[ISC_SHA1_BLOCK_LENGTH];
+
+ UNUSED(callback);
bytes = (key->key_size + 7) / 8;
- if (bytes > HMAC_LEN) {
- bytes = HMAC_LEN;
- key->key_size = HMAC_LEN * 8;
+ if (bytes > ISC_SHA1_BLOCK_LENGTH) {
+ bytes = ISC_SHA1_BLOCK_LENGTH;
+ key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
}
- memset(data, 0, HMAC_LEN);
+ memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
if (ret != ISC_R_SUCCESS)
@@ -439,7 +444,7 @@ hmacsha1_generate(dst_key_t *key, int pseudorandom_ok) {
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
ret = hmacsha1_fromdns(key, &b);
- memset(data, 0, ISC_SHA1_DIGESTLENGTH);
+ memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
return (ret);
}
@@ -453,6 +458,7 @@ hmacsha1_isprivate(const dst_key_t *key) {
static void
hmacsha1_destroy(dst_key_t *key) {
dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
+
memset(hkey, 0, sizeof(dst_hmacsha1_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha1_key_t));
key->keydata.hmacsha1 = NULL;
@@ -492,7 +498,7 @@ hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
memset(hkey->key, 0, sizeof(hkey->key));
- if (r.length > ISC_SHA1_DIGESTLENGTH) {
+ if (r.length > ISC_SHA1_BLOCK_LENGTH) {
isc_sha1_init(&sha1ctx);
isc_sha1_update(&sha1ctx, r.base, r.length);
isc_sha1_final(&sha1ctx, hkey->key);
@@ -537,13 +543,14 @@ hmacsha1_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx,
&priv);
@@ -594,6 +601,8 @@ static dst_func_t hmacsha1_functions = {
hmacsha1_parse,
NULL, /* cleanup */
NULL, /* fromlabel */
+ NULL, /* dump */
+ NULL, /* restore */
};
isc_result_t
@@ -607,7 +616,7 @@ dst__hmacsha1_init(dst_func_t **funcp) {
static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data);
struct dst_hmacsha224_key {
- unsigned char key[ISC_SHA224_DIGESTLENGTH];
+ unsigned char key[ISC_SHA224_BLOCK_LENGTH];
};
static isc_result_t
@@ -618,7 +627,7 @@ hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) {
hmacsha224ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha224_t));
if (hmacsha224ctx == NULL)
return (ISC_R_NOMEMORY);
- isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_DIGESTLENGTH);
+ isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_BLOCK_LENGTH);
dctx->ctxdata.hmacsha224ctx = hmacsha224ctx;
return (ISC_R_SUCCESS);
}
@@ -681,26 +690,30 @@ hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) {
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, ISC_SHA224_DIGESTLENGTH) == 0)
+ if (memcmp(hkey1->key, hkey2->key, ISC_SHA224_BLOCK_LENGTH) == 0)
return (ISC_TRUE);
else
return (ISC_FALSE);
}
static isc_result_t
-hmacsha224_generate(dst_key_t *key, int pseudorandom_ok) {
+hmacsha224_generate(dst_key_t *key, int pseudorandom_ok,
+ void (*callback)(int))
+{
isc_buffer_t b;
isc_result_t ret;
- int bytes;
- unsigned char data[HMAC_LEN];
+ unsigned int bytes;
+ unsigned char data[ISC_SHA224_BLOCK_LENGTH];
+
+ UNUSED(callback);
bytes = (key->key_size + 7) / 8;
- if (bytes > HMAC_LEN) {
- bytes = HMAC_LEN;
- key->key_size = HMAC_LEN * 8;
+ if (bytes > ISC_SHA224_BLOCK_LENGTH) {
+ bytes = ISC_SHA224_BLOCK_LENGTH;
+ key->key_size = ISC_SHA224_BLOCK_LENGTH * 8;
}
- memset(data, 0, HMAC_LEN);
+ memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
if (ret != ISC_R_SUCCESS)
@@ -709,7 +722,7 @@ hmacsha224_generate(dst_key_t *key, int pseudorandom_ok) {
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
ret = hmacsha224_fromdns(key, &b);
- memset(data, 0, ISC_SHA224_DIGESTLENGTH);
+ memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
return (ret);
}
@@ -723,6 +736,7 @@ hmacsha224_isprivate(const dst_key_t *key) {
static void
hmacsha224_destroy(dst_key_t *key) {
dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
+
memset(hkey, 0, sizeof(dst_hmacsha224_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha224_key_t));
key->keydata.hmacsha224 = NULL;
@@ -762,7 +776,7 @@ hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
memset(hkey->key, 0, sizeof(hkey->key));
- if (r.length > ISC_SHA224_DIGESTLENGTH) {
+ if (r.length > ISC_SHA224_BLOCK_LENGTH) {
isc_sha224_init(&sha224ctx);
isc_sha224_update(&sha224ctx, r.base, r.length);
isc_sha224_final(hkey->key, &sha224ctx);
@@ -807,13 +821,14 @@ hmacsha224_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx,
&priv);
@@ -864,6 +879,8 @@ static dst_func_t hmacsha224_functions = {
hmacsha224_parse,
NULL, /* cleanup */
NULL, /* fromlabel */
+ NULL, /* dump */
+ NULL, /* restore */
};
isc_result_t
@@ -877,7 +894,7 @@ dst__hmacsha224_init(dst_func_t **funcp) {
static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data);
struct dst_hmacsha256_key {
- unsigned char key[ISC_SHA256_DIGESTLENGTH];
+ unsigned char key[ISC_SHA256_BLOCK_LENGTH];
};
static isc_result_t
@@ -888,7 +905,7 @@ hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) {
hmacsha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha256_t));
if (hmacsha256ctx == NULL)
return (ISC_R_NOMEMORY);
- isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_DIGESTLENGTH);
+ isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_BLOCK_LENGTH);
dctx->ctxdata.hmacsha256ctx = hmacsha256ctx;
return (ISC_R_SUCCESS);
}
@@ -951,26 +968,30 @@ hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) {
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, ISC_SHA256_DIGESTLENGTH) == 0)
+ if (memcmp(hkey1->key, hkey2->key, ISC_SHA256_BLOCK_LENGTH) == 0)
return (ISC_TRUE);
else
return (ISC_FALSE);
}
static isc_result_t
-hmacsha256_generate(dst_key_t *key, int pseudorandom_ok) {
+hmacsha256_generate(dst_key_t *key, int pseudorandom_ok,
+ void (*callback)(int))
+{
isc_buffer_t b;
isc_result_t ret;
- int bytes;
- unsigned char data[HMAC_LEN];
+ unsigned int bytes;
+ unsigned char data[ISC_SHA256_BLOCK_LENGTH];
+
+ UNUSED(callback);
bytes = (key->key_size + 7) / 8;
- if (bytes > HMAC_LEN) {
- bytes = HMAC_LEN;
- key->key_size = HMAC_LEN * 8;
+ if (bytes > ISC_SHA256_BLOCK_LENGTH) {
+ bytes = ISC_SHA256_BLOCK_LENGTH;
+ key->key_size = ISC_SHA256_BLOCK_LENGTH * 8;
}
- memset(data, 0, HMAC_LEN);
+ memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
if (ret != ISC_R_SUCCESS)
@@ -979,7 +1000,7 @@ hmacsha256_generate(dst_key_t *key, int pseudorandom_ok) {
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
ret = hmacsha256_fromdns(key, &b);
- memset(data, 0, ISC_SHA256_DIGESTLENGTH);
+ memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
return (ret);
}
@@ -993,6 +1014,7 @@ hmacsha256_isprivate(const dst_key_t *key) {
static void
hmacsha256_destroy(dst_key_t *key) {
dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
+
memset(hkey, 0, sizeof(dst_hmacsha256_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha256_key_t));
key->keydata.hmacsha256 = NULL;
@@ -1032,7 +1054,7 @@ hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
memset(hkey->key, 0, sizeof(hkey->key));
- if (r.length > ISC_SHA256_DIGESTLENGTH) {
+ if (r.length > ISC_SHA256_BLOCK_LENGTH) {
isc_sha256_init(&sha256ctx);
isc_sha256_update(&sha256ctx, r.base, r.length);
isc_sha256_final(hkey->key, &sha256ctx);
@@ -1077,13 +1099,14 @@ hmacsha256_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx,
&priv);
@@ -1134,6 +1157,8 @@ static dst_func_t hmacsha256_functions = {
hmacsha256_parse,
NULL, /* cleanup */
NULL, /* fromlabel */
+ NULL, /* dump */
+ NULL, /* restore */
};
isc_result_t
@@ -1147,7 +1172,7 @@ dst__hmacsha256_init(dst_func_t **funcp) {
static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data);
struct dst_hmacsha384_key {
- unsigned char key[ISC_SHA384_DIGESTLENGTH];
+ unsigned char key[ISC_SHA384_BLOCK_LENGTH];
};
static isc_result_t
@@ -1158,7 +1183,7 @@ hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) {
hmacsha384ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha384_t));
if (hmacsha384ctx == NULL)
return (ISC_R_NOMEMORY);
- isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_DIGESTLENGTH);
+ isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_BLOCK_LENGTH);
dctx->ctxdata.hmacsha384ctx = hmacsha384ctx;
return (ISC_R_SUCCESS);
}
@@ -1221,26 +1246,30 @@ hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) {
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, ISC_SHA384_DIGESTLENGTH) == 0)
+ if (memcmp(hkey1->key, hkey2->key, ISC_SHA384_BLOCK_LENGTH) == 0)
return (ISC_TRUE);
else
return (ISC_FALSE);
}
static isc_result_t
-hmacsha384_generate(dst_key_t *key, int pseudorandom_ok) {
+hmacsha384_generate(dst_key_t *key, int pseudorandom_ok,
+ void (*callback)(int))
+{
isc_buffer_t b;
isc_result_t ret;
- int bytes;
- unsigned char data[HMAC_LEN];
+ unsigned int bytes;
+ unsigned char data[ISC_SHA384_BLOCK_LENGTH];
+
+ UNUSED(callback);
bytes = (key->key_size + 7) / 8;
- if (bytes > HMAC_LEN) {
- bytes = HMAC_LEN;
- key->key_size = HMAC_LEN * 8;
+ if (bytes > ISC_SHA384_BLOCK_LENGTH) {
+ bytes = ISC_SHA384_BLOCK_LENGTH;
+ key->key_size = ISC_SHA384_BLOCK_LENGTH * 8;
}
- memset(data, 0, HMAC_LEN);
+ memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
if (ret != ISC_R_SUCCESS)
@@ -1249,7 +1278,7 @@ hmacsha384_generate(dst_key_t *key, int pseudorandom_ok) {
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
ret = hmacsha384_fromdns(key, &b);
- memset(data, 0, ISC_SHA384_DIGESTLENGTH);
+ memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
return (ret);
}
@@ -1263,6 +1292,7 @@ hmacsha384_isprivate(const dst_key_t *key) {
static void
hmacsha384_destroy(dst_key_t *key) {
dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
+
memset(hkey, 0, sizeof(dst_hmacsha384_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha384_key_t));
key->keydata.hmacsha384 = NULL;
@@ -1302,7 +1332,7 @@ hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
memset(hkey->key, 0, sizeof(hkey->key));
- if (r.length > ISC_SHA384_DIGESTLENGTH) {
+ if (r.length > ISC_SHA384_BLOCK_LENGTH) {
isc_sha384_init(&sha384ctx);
isc_sha384_update(&sha384ctx, r.base, r.length);
isc_sha384_final(hkey->key, &sha384ctx);
@@ -1347,13 +1377,14 @@ hmacsha384_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx,
&priv);
@@ -1404,6 +1435,8 @@ static dst_func_t hmacsha384_functions = {
hmacsha384_parse,
NULL, /* cleanup */
NULL, /* fromlabel */
+ NULL, /* dump */
+ NULL, /* restore */
};
isc_result_t
@@ -1417,7 +1450,7 @@ dst__hmacsha384_init(dst_func_t **funcp) {
static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data);
struct dst_hmacsha512_key {
- unsigned char key[ISC_SHA512_DIGESTLENGTH];
+ unsigned char key[ISC_SHA512_BLOCK_LENGTH];
};
static isc_result_t
@@ -1428,7 +1461,7 @@ hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) {
hmacsha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha512_t));
if (hmacsha512ctx == NULL)
return (ISC_R_NOMEMORY);
- isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_DIGESTLENGTH);
+ isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_BLOCK_LENGTH);
dctx->ctxdata.hmacsha512ctx = hmacsha512ctx;
return (ISC_R_SUCCESS);
}
@@ -1491,26 +1524,30 @@ hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) {
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, ISC_SHA512_DIGESTLENGTH) == 0)
+ if (memcmp(hkey1->key, hkey2->key, ISC_SHA512_BLOCK_LENGTH) == 0)
return (ISC_TRUE);
else
return (ISC_FALSE);
}
static isc_result_t
-hmacsha512_generate(dst_key_t *key, int pseudorandom_ok) {
+hmacsha512_generate(dst_key_t *key, int pseudorandom_ok,
+ void (*callback)(int))
+{
isc_buffer_t b;
isc_result_t ret;
- int bytes;
- unsigned char data[HMAC_LEN];
+ unsigned int bytes;
+ unsigned char data[ISC_SHA512_BLOCK_LENGTH];
+
+ UNUSED(callback);
bytes = (key->key_size + 7) / 8;
- if (bytes > HMAC_LEN) {
- bytes = HMAC_LEN;
- key->key_size = HMAC_LEN * 8;
+ if (bytes > ISC_SHA512_BLOCK_LENGTH) {
+ bytes = ISC_SHA512_BLOCK_LENGTH;
+ key->key_size = ISC_SHA512_BLOCK_LENGTH * 8;
}
- memset(data, 0, HMAC_LEN);
+ memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
if (ret != ISC_R_SUCCESS)
@@ -1519,7 +1556,7 @@ hmacsha512_generate(dst_key_t *key, int pseudorandom_ok) {
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
ret = hmacsha512_fromdns(key, &b);
- memset(data, 0, ISC_SHA512_DIGESTLENGTH);
+ memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
return (ret);
}
@@ -1533,6 +1570,7 @@ hmacsha512_isprivate(const dst_key_t *key) {
static void
hmacsha512_destroy(dst_key_t *key) {
dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
+
memset(hkey, 0, sizeof(dst_hmacsha512_key_t));
isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha512_key_t));
key->keydata.hmacsha512 = NULL;
@@ -1572,7 +1610,7 @@ hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
memset(hkey->key, 0, sizeof(hkey->key));
- if (r.length > ISC_SHA512_DIGESTLENGTH) {
+ if (r.length > ISC_SHA512_BLOCK_LENGTH) {
isc_sha512_init(&sha512ctx);
isc_sha512_update(&sha512ctx, r.base, r.length);
isc_sha512_final(hkey->key, &sha512ctx);
@@ -1617,13 +1655,14 @@ hmacsha512_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer) {
+hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
+ UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx,
&priv);
@@ -1674,6 +1713,8 @@ static dst_func_t hmacsha512_functions = {
hmacsha512_parse,
NULL, /* cleanup */
NULL, /* fromlabel */
+ NULL, /* dump */
+ NULL, /* restore */
};
isc_result_t
diff --git a/lib/dns/include/dns/Makefile.in b/lib/dns/include/dns/Makefile.in
index a4cd810fd9f3..e13d0848bdd9 100644
--- a/lib/dns/include/dns/Makefile.in
+++ b/lib/dns/include/dns/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.55 2008-11-14 23:47:33 tbox Exp $
+# $Id: Makefile.in,v 1.57 2009-10-08 23:48:10 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -21,19 +21,17 @@ top_srcdir = @top_srcdir@
@BIND9_VERSION@
-HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h \
- cert.h compress.h \
+HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h cert.h compress.h \
db.h dbiterator.h dbtable.h diff.h dispatch.h dlz.h \
- dnssec.h ds.h events.h fixedname.h iptable.h journal.h keyflags.h \
- keytable.h keyvalues.h lib.h log.h master.h masterdump.h \
- message.h name.h ncache.h \
- nsec.h peer.h portlist.h rbt.h rcode.h \
+ dnssec.h ds.h events.h fixedname.h iptable.h journal.h \
+ keyflags.h keytable.h keyvalues.h lib.h log.h \
+ master.h masterdump.h message.h name.h ncache.h nsec.h \
+ peer.h portlist.h private.h rbt.h rcode.h \
rdata.h rdataclass.h rdatalist.h rdataset.h rdatasetiter.h \
rdataslab.h rdatatype.h request.h resolver.h result.h \
rootns.h sdb.h sdlz.h secalg.h secproto.h soa.h ssu.h \
- tcpmsg.h time.h tkey.h \
- tsig.h ttl.h types.h validator.h version.h view.h xfrin.h \
- zone.h zonekey.h zt.h
+ tcpmsg.h time.h tkey.h tsig.h ttl.h types.h \
+ validator.h version.h view.h xfrin.h zone.h zonekey.h zt.h
GENHEADERS = enumclass.h enumtype.h rdatastruct.h
diff --git a/lib/dns/include/dns/acl.h b/lib/dns/include/dns/acl.h
index 1045cd2e88dc..04f55773d896 100644
--- a/lib/dns/include/dns/acl.h
+++ b/lib/dns/include/dns/acl.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: acl.h,v 1.31.206.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: acl.h,v 1.33 2009-01-17 23:47:43 tbox Exp $ */
#ifndef DNS_ACL_H
#define DNS_ACL_H 1
diff --git a/lib/dns/include/dns/cache.h b/lib/dns/include/dns/cache.h
index 94077d6b0695..e4ea5f489577 100644
--- a/lib/dns/include/dns/cache.h
+++ b/lib/dns/include/dns/cache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: cache.h,v 1.26 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: cache.h,v 1.28 2009-01-09 23:47:46 tbox Exp $ */
#ifndef DNS_CACHE_H
#define DNS_CACHE_H 1
@@ -65,8 +65,15 @@ dns_cache_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
isc_timermgr_t *timermgr, dns_rdataclass_t rdclass,
const char *db_type, unsigned int db_argc, char **db_argv,
dns_cache_t **cachep);
+isc_result_t
+dns_cache_create2(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
+ isc_timermgr_t *timermgr, dns_rdataclass_t rdclass,
+ const char *cachename, const char *db_type,
+ unsigned int db_argc, char **db_argv, dns_cache_t **cachep);
/*%<
- * Create a new DNS cache.
+ * Create a new DNS cache. dns_cache_create2() will create a named cache.
+ * dns_cache_create() is a backward compatible version that internally specifies
+ * an empty name.
*
* Requires:
*
@@ -76,6 +83,8 @@ dns_cache_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
* manager, or both are NULL. If NULL, no periodic cleaning of the
* cache will take place.
*
+ *\li 'cachename' is a valid string. This must not be NULL.
+ *
*\li 'cachep' is a valid pointer, and *cachep == NULL
*
* Ensures:
@@ -217,12 +226,36 @@ dns_cache_setcleaninginterval(dns_cache_t *cache, unsigned int interval);
* Set the periodic cache cleaning interval to 'interval' seconds.
*/
+unsigned int
+dns_cache_getcleaninginterval(dns_cache_t *cache);
+/*%<
+ * Get the periodic cache cleaning interval to 'interval' seconds.
+ */
+
+isc_uint32_t
+dns_cache_getcachesize(dns_cache_t *cache);
+/*%<
+ * Get the maximum cache size.
+ */
+
+const char *
+dns_cache_getname(dns_cache_t *cache);
+/*%<
+ * Get the cache name.
+ */
+
void
dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size);
/*%<
* Set the maximum cache size. 0 means unlimited.
*/
+isc_uint32_t
+dns_cache_getcachesize(dns_cache_t *cache);
+/*%<
+ * Get the maximum cache size.
+ */
+
isc_result_t
dns_cache_flush(dns_cache_t *cache);
/*%<
diff --git a/lib/dns/include/dns/client.h b/lib/dns/include/dns/client.h
new file mode 100644
index 000000000000..13cdf8f71365
--- /dev/null
+++ b/lib/dns/include/dns/client.h
@@ -0,0 +1,621 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.3 2009-09-02 23:48:02 tbox Exp $ */
+
+#ifndef DNS_CLIENT_H
+#define DNS_CLIENT_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ *
+ * \brief
+ * The DNS client module provides convenient programming interfaces to various
+ * DNS services, such as name resolution with or without DNSSEC validation or
+ * dynamic DNS update. This module is primarily expected to be used by other
+ * applications than BIND9-related ones that need such advanced DNS features.
+ *
+ * MP:
+ *\li In the typical usage of this module, application threads will not share
+ * the same data structures created and manipulated in this module.
+ * However, the module still ensures appropriate synchronization of such
+ * data structures.
+ *
+ * Resources:
+ *\li TBS
+ *
+ * Security:
+ *\li This module does not handle any low-level data directly, and so no
+ * security issue specific to this module is anticipated.
+ */
+
+#include <isc/event.h>
+#include <isc/sockaddr.h>
+
+#include <dns/tsig.h>
+#include <dns/types.h>
+
+#include <dst/dst.h>
+
+typedef enum {
+ updateop_none = 0,
+ updateop_add = 1,
+ updateop_delete = 2,
+ updateop_exist = 3,
+ updateop_notexist = 4,
+ updateop_max = 5
+} dns_client_updateop_t;
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+/*%
+ * Optional flags for dns_client_create(x).
+ */
+/*%< Enable caching resolution results (experimental). */
+#define DNS_CLIENTCREATEOPT_USECACHE 0x8000
+
+/*%
+ * Optional flags for dns_client_(start)resolve.
+ */
+/*%< Disable DNSSEC validation. */
+#define DNS_CLIENTRESOPT_NODNSSEC 0x01
+/*%< Allow running external context. */
+#define DNS_CLIENTRESOPT_ALLOWRUN 0x02
+
+/*%
+ * Optional flags for dns_client_(start)request.
+ */
+/*%< Allow running external context. */
+#define DNS_CLIENTREQOPT_ALLOWRUN 0x01
+
+/*%
+ * A dns_clientresevent_t is sent when name resolution performed by a client
+ * completes. 'result' stores the result code of the entire resolution
+ * procedure. 'vresult' specifically stores the result code of DNSSEC
+ * validation if it is performed. When name resolution successfully completes,
+ * 'answerlist' is typically non empty, containing answer names along with
+ * RRsets. It is the receiver's responsibility to free this list by calling
+ * dns_client_freeresanswer() before freeing the event structure.
+ */
+typedef struct dns_clientresevent {
+ ISC_EVENT_COMMON(struct dns_clientresevent);
+ isc_result_t result;
+ isc_result_t vresult;
+ dns_namelist_t answerlist;
+} dns_clientresevent_t; /* too long? */
+
+/*%
+ * Status of a dynamic update procedure.
+ */
+typedef enum {
+ dns_clientupdatestate_prepare, /*%< no updates have been sent */
+ dns_clientupdatestate_sent, /*%< updates were sent, no response */
+ dns_clientupdatestate_done /*%< update was sent and succeeded */
+} dns_clientupdatestate_t;
+
+/*%
+ * A dns_clientreqevent_t is sent when a DNS request is completed by a client.
+ * 'result' stores the result code of the entire transaction.
+ * If the transaction is successfully completed but the response packet cannot
+ * be parsed, 'result' will store the result code of dns_message_parse().
+ * If the response packet is received, 'rmessage' will contain the response
+ * message, whether it is successfully parsed or not.
+ */
+typedef struct dns_clientreqevent {
+ ISC_EVENT_COMMON(struct dns_clientreqevent);
+ isc_result_t result;
+ dns_message_t *rmessage;
+} dns_clientreqevent_t; /* too long? */
+
+/*%
+ * A dns_clientupdateevent_t is sent when dynamic update performed by a client
+ * completes. 'result' stores the result code of the entire update procedure.
+ * 'state' specifies the status of the update procedure when this event is
+ * sent. This can be used as a hint by the receiver to determine whether
+ * the update attempt was ever made. In particular, if the state is
+ * dns_clientupdatestate_prepare, the receiver can be sure that the requested
+ * update was not applied.
+ */
+typedef struct dns_clientupdateevent {
+ ISC_EVENT_COMMON(struct dns_clientupdateevent);
+ isc_result_t result;
+ dns_clientupdatestate_t state;
+} dns_clientupdateevent_t; /* too long? */
+
+isc_result_t
+dns_client_create(dns_client_t **clientp, unsigned int options);
+
+isc_result_t
+dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
+ isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
+ unsigned int options, dns_client_t **clientp);
+/*%<
+ * Create a DNS client. These functions create a new client object with
+ * minimal internal resources such as the default 'view' for the IN class and
+ * IPv4/IPv6 dispatches for the view.
+ *
+ * dns_client_createx() takes 'manager' arguments so that the caller can
+ * control the behavior of the client through the underlying event framework.
+ * On the other hand, dns_client_create() simplifies the interface and creates
+ * the managers internally. A DNS client object created via
+ * dns_client_create() is expected to be used by an application that only needs
+ * simple synchronous services or by a thread-based application.
+ *
+ * If the DNS_CLIENTCREATEOPT_USECACHE flag is set in 'options',
+ * dns_client_create(x) will create a cache database with the view.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'actx' is a valid application context.
+ *
+ *\li 'taskmgr' is a valid task manager.
+ *
+ *\li 'socketmgr' is a valid socket manager.
+ *
+ *\li 'timermgr' is a valid timer manager.
+ *
+ *\li clientp != NULL && *clientp == NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+void
+dns_client_destroy(dns_client_t **clientp);
+/*%<
+ * Destroy 'client'.
+ *
+ * Requires:
+ *
+ *\li '*clientp' is a valid client.
+ *
+ * Ensures:
+ *
+ *\li *clientp == NULL.
+ */
+
+isc_result_t
+dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *namespace, isc_sockaddrlist_t *addrs);
+/*%<
+ * Specify a list of addresses of recursive name servers that the client will
+ * use for name resolution. A view for the 'rdclass' class must be created
+ * beforehand. If 'namespace' is non NULL, the specified server will be used
+ * if and only if the query name is a subdomain of 'namespace'. When servers
+ * for multiple 'namespace's are provided, and a query name is covered by
+ * more than one 'namespace', the servers for the best (longest) matching
+ * namespace will be used. If 'namespace' is NULL, it works as if
+ * dns_rootname (.) were specified.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'namespace' is NULL or a valid name.
+ *
+ *\li 'addrs' != NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+isc_result_t
+dns_client_clearservers(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *namespace);
+/*%<
+ * Remove configured recursive name servers for the 'rdclass' and 'namespace'
+ * from the client. See the description of dns_client_setservers() for
+ * the requirements about 'rdclass' and 'namespace'.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'namespace' is NULL or a valid name.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+isc_result_t
+dns_client_resolve(dns_client_t *client, dns_name_t *name,
+ dns_rdataclass_t rdclass, dns_rdatatype_t type,
+ unsigned int options, dns_namelist_t *namelist);
+
+isc_result_t
+dns_client_startresolve(dns_client_t *client, dns_name_t *name,
+ dns_rdataclass_t rdclass, dns_rdatatype_t type,
+ unsigned int options, isc_task_t *task,
+ isc_taskaction_t action, void *arg,
+ dns_clientrestrans_t **transp);
+/*%<
+ * Perform name resolution for 'name', 'rdclass', and 'type'.
+ *
+ * If any trusted keys are configured and the query name is considered to
+ * belong to a secure zone, these functions also validate the responses
+ * using DNSSEC by default. If the DNS_CLIENTRESOPT_NODNSSEC flag is set
+ * in 'options', DNSSEC validation is disabled regardless of the configured
+ * trusted keys or the query name.
+ *
+ * dns_client_resolve() provides a synchronous service. This function starts
+ * name resolution internally and blocks until it completes. On success,
+ * 'namelist' will contain a list of answer names, each of which has
+ * corresponding RRsets. The caller must provide a valid empty list, and
+ * is responsible for freeing the list content via dns_client_freeresanswer().
+ * If the name resolution fails due to an error in DNSSEC validation,
+ * dns_client_resolve() returns the result code indicating the validation
+ * error. Otherwise, it returns the result code of the entire resolution
+ * process, either success or failure.
+ *
+ * It is typically expected that the client object passed to
+ * dns_client_resolve() was created via dns_client_create() and has its own
+ * managers and contexts. However, if the DNS_CLIENTRESOPT_ALLOWRUN flag is
+ * set in 'options', this function performs the synchronous service even if
+ * it does not have its own manager and context structures.
+ *
+ * dns_client_startresolve() is an asynchronous version of dns_client_resolve()
+ * and does not block. When name resolution is completed, 'action' will be
+ * called with the argument of a 'dns_clientresevent_t' object, which contains
+ * the resulting list of answer names (on success). On return, '*transp' is
+ * set to an opaque transaction ID so that the caller can cancel this
+ * resolution process.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'addrs' != NULL.
+ *
+ *\li 'name' is a valid name.
+ *
+ *\li 'namelist' != NULL and is not empty.
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li 'transp' != NULL && *transp == NULL;
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+void
+dns_client_cancelresolve(dns_clientrestrans_t *trans);
+/*%<
+ * Cancel an ongoing resolution procedure started via
+ * dns_client_startresolve().
+ *
+ * Notes:
+ *
+ *\li If the resolution procedure has not completed, post its CLIENTRESDONE
+ * event with a result code of #ISC_R_CANCELED.
+ *
+ * Requires:
+ *
+ *\li 'trans' is a valid transaction ID.
+ */
+
+void
+dns_client_destroyrestrans(dns_clientrestrans_t **transp);
+/*%<
+ * Destroy name resolution transaction state identified by '*transp'.
+ *
+ * Requires:
+ *
+ *\li '*transp' is a valid transaction ID.
+ *
+ *\li The caller has received the CLIENTRESDONE event (either because the
+ * resolution completed or because dns_client_cancelresolve() was called).
+ *
+ * Ensures:
+ *
+ *\li *transp == NULL.
+ */
+
+void
+dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist);
+/*%<
+ * Free resources allocated for the content of 'namelist'.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'namelist' != NULL.
+ */
+
+isc_result_t
+dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *keyname, isc_buffer_t *keydatabuf);
+/*%<
+ * Add a DNSSEC trusted key for the 'rdclass' class. A view for the 'rdclass'
+ * class must be created beforehand. 'keyname' is the DNS name of the key,
+ * and 'keydatabuf' stores the resource data of the key.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'keyname' is a valid name.
+ *
+ *\li 'keydatabuf' is a valid buffer.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+isc_result_t
+dns_client_request(dns_client_t *client, dns_message_t *qmessage,
+ dns_message_t *rmessage, isc_sockaddr_t *server,
+ unsigned int options, unsigned int parseoptions,
+ dns_tsec_t *tsec, unsigned int timeout,
+ unsigned int udptimeout, unsigned int udpretries);
+
+isc_result_t
+dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage,
+ dns_message_t *rmessage, isc_sockaddr_t *server,
+ unsigned int options, unsigned int parseoptions,
+ dns_tsec_t *tsec, unsigned int timeout,
+ unsigned int udptimeout, unsigned int udpretries,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
+ dns_clientreqtrans_t **transp);
+
+/*%<
+ * Send a DNS request containig a query message 'query' to 'server'.
+ *
+ * 'parseoptions' will be used when the response packet is parsed, and will be
+ * passed to dns_message_parse() via dns_request_getresponse(). See
+ * dns_message_parse() for more details.
+ *
+ * 'tsec' is a transaction security object containing, e.g. a TSIG key for
+ * authenticating the request/response transaction. This is optional and can
+ * be NULL, in which case this library performs the transaction without any
+ * transaction authentication.
+ *
+ * 'timeout', 'udptimeout', and 'udpretries' are passed to
+ * dns_request_createvia3(). See dns_request_createvia3() for more details.
+ *
+ * dns_client_request() provides a synchronous service. This function sends
+ * the request and blocks until a response is received. On success,
+ * 'rmessage' will contain the response message. The caller must provide a
+ * valid initialized message.
+ *
+ * It is usually expected that the client object passed to
+ * dns_client_request() was created via dns_client_create() and has its own
+ * managers and contexts. However, if the DNS_CLIENTREQOPT_ALLOWRUN flag is
+ * set in 'options', this function performs the synchronous service even if
+ * it does not have its own manager and context structures.
+ *
+ * dns_client_startrequest() is an asynchronous version of dns_client_request()
+ * and does not block. When the transaction is completed, 'action' will be
+ * called with the argument of a 'dns_clientreqevent_t' object, which contains
+ * the response message (on success). On return, '*transp' is set to an opaque
+ * transaction ID so that the caller can cancel this request.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'qmessage' and 'rmessage' are valid initialized message.
+ *
+ *\li 'server' is a valid socket address structure.
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li 'transp' != NULL && *transp == NULL;
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ *
+ *\li Any result that dns_message_parse() can return.
+ */
+
+void
+dns_client_cancelrequest(dns_clientreqtrans_t *transp);
+/*%<
+ * Cancel an ongoing DNS request procedure started via
+ * dns_client_startrequest().
+ *
+ * Notes:
+ *
+ *\li If the request procedure has not completed, post its CLIENTREQDONE
+ * event with a result code of #ISC_R_CANCELED.
+ *
+ * Requires:
+ *
+ *\li 'trans' is a valid transaction ID.
+ */
+
+void
+dns_client_destroyreqtrans(dns_clientreqtrans_t **transp);
+/*%
+ * Destroy DNS request transaction state identified by '*transp'.
+ *
+ * Requires:
+ *
+ *\li '*transp' is a valid transaction ID.
+ *
+ *\li The caller has received the CLIENTREQDONE event (either because the
+ * request completed or because dns_client_cancelrequest() was called).
+ *
+ * Ensures:
+ *
+ *\li *transp == NULL.
+ */
+
+isc_result_t
+dns_client_update(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *zonename, dns_namelist_t *prerequisites,
+ dns_namelist_t *updates, isc_sockaddrlist_t *servers,
+ dns_tsec_t *tsec, unsigned int options);
+
+isc_result_t
+dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass,
+ dns_name_t *zonename, dns_namelist_t *prerequisites,
+ dns_namelist_t *updates, isc_sockaddrlist_t *servers,
+ dns_tsec_t *tsec, unsigned int options,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
+ dns_clientupdatetrans_t **transp);
+/*%<
+ * Perform DNS dynamic update for 'updates' of the 'rdclass' class with
+ * optional 'prerequisites'.
+ *
+ * 'updates' are a list of names with associated RRsets to be updated.
+ *
+ * 'prerequisites' are a list of names with associated RRsets corresponding to
+ * the prerequisites of the updates. This is optional and can be NULL, in
+ * which case the prerequisite section of the update message will be empty.
+ *
+ * Both 'updates' and 'prerequisites' must be constructed as specified in
+ * RFC2136.
+ *
+ * 'zonename' is the name of the zone in which the updated names exist.
+ * This is optional and can be NULL. In this case, these functions internally
+ * identify the appropriate zone through some queries for the SOA RR starting
+ * with the first name in prerequisites or updates.
+ *
+ * 'servers' is a list of authoritative servers to which the update message
+ * should be sent. This is optional and can be NULL. In this case, these
+ * functions internally identify the appropriate primary server name and its
+ * addresses through some queries for the SOA RR (like the case of zonename)
+ * and supplemental A/AAAA queries for the server name.
+ * Note: The client module generally assumes the given addresses are of the
+ * primary server of the corresponding zone. It will work even if a secondary
+ * server address is specified as long as the server allows update forwarding,
+ * it is generally discouraged to include secondary server addresses unless
+ * there's strong reason to do so.
+ *
+ * 'tsec' is a transaction security object containing, e.g. a TSIG key for
+ * authenticating the update transaction (and the supplemental query/response
+ * transactions if the server is specified). This is optional and can be
+ * NULL, in which case the library tries the update without any transaction
+ * authentication.
+ *
+ * dns_client_update() provides a synchronous service. This function blocks
+ * until the entire update procedure completes, including the additional
+ * queries when necessary.
+ *
+ * dns_client_startupdate() is an asynchronous version of dns_client_update().
+ * It immediately returns (typically with *transp being set to a non-NULL
+ * pointer), and performs the update procedure through a set of internal
+ * events. All transactions including the additional query exchanges are
+ * performed as a separate event, so none of these events cause blocking
+ * operation. When the update procedure completes, the specified function
+ * 'action' will be called with the argument of a 'dns_clientupdateevent_t'
+ * structure. On return, '*transp' is set to an opaque transaction ID so that
+ * the caller can cancel this update process.
+ *
+ * Notes:
+ *\li No options are currently defined.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+ *
+ *\li 'updates' != NULL.
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li 'transp' != NULL && *transp == NULL;
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+void
+dns_client_cancelupdate(dns_clientupdatetrans_t *trans);
+/*%<
+ * Cancel an ongoing dynamic update procedure started via
+ * dns_client_startupdate().
+ *
+ * Notes:
+ *
+ *\li If the update procedure has not completed, post its UPDATEDONE
+ * event with a result code of #ISC_R_CANCELED.
+ *
+ * Requires:
+ *
+ *\li 'trans' is a valid transaction ID.
+ */
+
+void
+dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp);
+/*%<
+ * Destroy dynamic update transaction identified by '*transp'.
+ *
+ * Requires:
+ *
+ *\li '*transp' is a valid transaction ID.
+ *
+ *\li The caller has received the UPDATEDONE event (either because the
+ * update completed or because dns_client_cancelupdate() was called).
+ *
+ * Ensures:
+ *
+ *\li *transp == NULL.
+ */
+
+isc_result_t
+dns_client_updaterec(dns_client_updateop_t op, dns_name_t *owner,
+ dns_rdatatype_t type, dns_rdata_t *source,
+ dns_ttl_t ttl, dns_name_t *target,
+ dns_rdataset_t *rdataset, dns_rdatalist_t *rdatalist,
+ dns_rdata_t *rdata, isc_mem_t *mctx);
+/*%<
+ * TBD
+ */
+
+void
+dns_client_freeupdate(dns_name_t **namep);
+/*%<
+ * TBD
+ */
+
+isc_mem_t *
+dns_client_mctx(dns_client_t *client);
+
+ISC_LANG_ENDDECLS
+
+#endif /* DNS_CLIENT_H */
diff --git a/lib/dns/include/dns/compress.h b/lib/dns/include/dns/compress.h
index 4181c7777fdd..ebe543b64837 100644
--- a/lib/dns/include/dns/compress.h
+++ b/lib/dns/include/dns/compress.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: compress.h,v 1.40.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: compress.h,v 1.42 2009-01-17 23:47:43 tbox Exp $ */
#ifndef DNS_COMPRESS_H
#define DNS_COMPRESS_H 1
diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h
index f6228347938c..edb1263ab80f 100644
--- a/lib/dns/include/dns/db.h
+++ b/lib/dns/include/dns/db.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.h,v 1.93.50.5 2009-11-25 23:48:42 tbox Exp $ */
+/* $Id: db.h,v 1.104 2011-01-13 04:59:25 tbox Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@@ -59,7 +59,11 @@
#include <isc/ondestroy.h>
#include <isc/stdtime.h>
+#include <dns/fixedname.h>
#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rpz.h>
#include <dns/types.h>
ISC_LANG_BEGINDECLS
@@ -167,6 +171,13 @@ typedef struct dns_dbmethods {
dns_dbversion_t *version);
isc_boolean_t (*isdnssec)(dns_db_t *db);
dns_stats_t *(*getrrsetstats)(dns_db_t *db);
+ void (*rpz_enabled)(dns_db_t *db, dns_rpz_st_t *st);
+ isc_result_t (*rpz_findips)(dns_rpz_zone_t *rpz,
+ dns_rpz_type_t rpz_type,
+ dns_zone_t *zone, dns_db_t *db,
+ dns_dbversion_t *version,
+ dns_rdataset_t *ardataset,
+ dns_rpz_st_t *st);
} dns_dbmethods_t;
typedef isc_result_t
@@ -491,6 +502,10 @@ dns_db_load(dns_db_t *db, const char *filename);
isc_result_t
dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format);
+
+isc_result_t
+dns_db_load3(dns_db_t *db, const char *filename, dns_masterformat_t format,
+ unsigned int options);
/*%<
* Load master file 'filename' into 'db'.
*
@@ -614,7 +629,7 @@ dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp,
*
* Note: if '*versionp' is a read-write version and 'commit' is ISC_TRUE,
* then all changes made in the version will take effect, otherwise they
- * will be rolled back. The value if 'commit' is ignored for read-only
+ * will be rolled back. The value of 'commit' is ignored for read-only
* versions.
*
* Requires:
@@ -841,6 +856,9 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* \li #DNS_R_COVERINGNSEC The returned data is a NSEC
* that potentially covers 'name'.
*
+ * \li #DNS_R_EMPTYWILD The name is a wildcard without
+ * resource records.
+ *
* Error results:
*
* \li #ISC_R_NOMEMORY
@@ -1477,6 +1495,31 @@ dns_db_getrrsetstats(dns_db_t *db);
* dns_rdatasetstats_create(); otherwise NULL.
*/
+void
+dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st);
+/*%<
+ * See if a policy database has DNS_RPZ_TYPE_IP, DNS_RPZ_TYPE_NSIP, or
+ * DNS_RPZ_TYPE_NSDNAME records.
+ */
+
+isc_result_t
+dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
+ dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
+ dns_rdataset_t *ardataset, dns_rpz_st_t *st);
+/*%<
+ * Search the CDIR block tree of a response policy tree of trees for the best
+ * match to any of the IP addresses in an A or AAAA rdataset.
+ *
+ * Requires:
+ * \li search in policy zone 'rpz' for a match of 'rpz_type' either
+ * DNS_RPZ_TYPE_IP or DNS_RPZ_TYPE_NSIP
+ * \li 'zone' and 'db' are the database corresponding to 'rpz'
+ * \li 'version' is the required version of the database
+ * \li 'ardataset' is an A or AAAA rdataset of addresses to check
+ * \li 'found' specifies the previous best match if any or
+ * or NULL, an empty name, 0, DNS_RPZ_POLICY_MISS, and 0
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_DB_H */
diff --git a/lib/dns/include/dns/diff.h b/lib/dns/include/dns/diff.h
index f5e25ee67c2e..b6c929f04d47 100644
--- a/lib/dns/include/dns/diff.h
+++ b/lib/dns/include/dns/diff.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: diff.h,v 1.15.120.4 2010-06-04 23:48:25 tbox Exp $ */
+/* $Id: diff.h,v 1.19 2010-06-04 23:51:14 tbox Exp $ */
#ifndef DNS_DIFF_H
#define DNS_DIFF_H 1
diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h
index 6e2f3e15db3a..3d252a138366 100644
--- a/lib/dns/include/dns/dispatch.h
+++ b/lib/dns/include/dns/dispatch.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.h,v 1.60.82.2 2009-01-29 23:47:44 tbox Exp $ */
+/* $Id: dispatch.h,v 1.62 2009-01-27 23:47:54 tbox Exp $ */
#ifndef DNS_DISPATCH_H
#define DNS_DISPATCH_H 1
diff --git a/lib/dns/include/dns/dlz.h b/lib/dns/include/dns/dlz.h
index 28a24a944b20..e04b1b1adc62 100644
--- a/lib/dns/include/dns/dlz.h
+++ b/lib/dns/include/dns/dlz.h
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2005-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dlz.h,v 1.7.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: dlz.h,v 1.12 2010-12-20 23:47:21 tbox Exp $ */
/*! \file dns/dlz.h */
@@ -87,6 +87,7 @@
#include <dns/name.h>
#include <dns/types.h>
#include <dns/view.h>
+#include <dst/dst.h>
#include <isc/lang.h>
@@ -166,12 +167,37 @@ typedef isc_result_t
* return a result code indicating the type of error.
*/
+
+typedef isc_result_t
+(*dns_dlzconfigure_t)(void *driverarg, void *dbdata, dns_view_t *view);
+/*%<
+ * Method prototype. Drivers implementing the DLZ interface may
+ * optionally supply a configure method. If supplied, this will be
+ * called immediately after the create method is called. The driver
+ * may call configuration functions during the configure call
+ */
+
+
+typedef isc_boolean_t (*dns_dlzssumatch_t)(dns_name_t *signer,
+ dns_name_t *name,
+ isc_netaddr_t *tcpaddr,
+ dns_rdatatype_t type,
+ const dst_key_t *key,
+ void *driverarg, void *dbdata);
+/*%<
+ * Method prototype. Drivers implementing the DLZ interface may
+ * optionally supply a ssumatch method. If supplied, this will be
+ * called to authorize update requests
+ */
+
/*% the methods supplied by a DLZ driver */
typedef struct dns_dlzmethods {
dns_dlzcreate_t create;
dns_dlzdestroy_t destroy;
dns_dlzfindzone_t findzone;
dns_dlzallowzonexfr_t allowzonexfr;
+ dns_dlzconfigure_t configure;
+ dns_dlzssumatch_t ssumatch;
} dns_dlzmethods_t;
/*% information about a DLZ driver */
@@ -183,12 +209,18 @@ struct dns_dlzimplementation {
ISC_LINK(dns_dlzimplementation_t) link;
};
-/*% an instance of a DLZ driver */
+typedef isc_result_t (*dlzconfigure_callback_t)(dns_view_t *, dns_zone_t *);
+
+/*% An instance of a DLZ driver */
struct dns_dlzdb {
unsigned int magic;
isc_mem_t *mctx;
dns_dlzimplementation_t *implementation;
void *dbdata;
+ dlzconfigure_callback_t configure_callback;
+#ifdef BIND9
+ dns_ssutable_t *ssutable;
+#endif
};
@@ -285,6 +317,30 @@ dns_dlzunregister(dns_dlzimplementation_t **dlzimp);
* is called.
*/
+
+isc_result_t
+dns_dlz_writeablezone(dns_view_t *view, const char *zone_name);
+
+/*%<
+ * creates a writeable DLZ zone. Must be called from within the
+ * configure() method of a DLZ driver.
+ */
+
+
+isc_result_t
+dns_dlzconfigure(dns_view_t *view, dlzconfigure_callback_t callback);
+/*%<
+ * call a DLZ drivers configure method, if supplied
+ */
+
+isc_boolean_t
+dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase,
+ dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr,
+ dns_rdatatype_t type, const dst_key_t *key);
+/*%<
+ * call a DLZ drivers ssumatch method, if supplied. Otherwise return ISC_FALSE
+ */
+
ISC_LANG_ENDDECLS
#endif /* DLZ_H */
diff --git a/lib/dns/include/dns/dns64.h b/lib/dns/include/dns/dns64.h
new file mode 100644
index 000000000000..5fd32e850e96
--- /dev/null
+++ b/lib/dns/include/dns/dns64.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: dns64.h,v 1.3 2010-12-08 23:51:56 tbox Exp $ */
+
+#ifndef DNS_DNS64_H
+#define DNS_DNS64_H 1
+
+#include <isc/lang.h>
+
+#include <dns/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*
+ * dns_dns64_create() flags.
+ */
+#define DNS_DNS64_RECURSIVE_ONLY 0x01 /* If set then this record
+ * only applies to recursive
+ * queries.
+ */
+#define DNS_DNS64_BREAK_DNSSEC 0x02 /* If set then still perform
+ * DNSSEC synthesis even
+ * though the result would
+ * fail validation.
+ */
+
+/*
+ * dns_dns64_aaaaok() and dns_dns64_aaaafroma() flags.
+ */
+#define DNS_DNS64_RECURSIVE 0x01 /* Recursive query. */
+#define DNS_DNS64_DNSSEC 0x02 /* DNSSEC sensitive query. */
+
+isc_result_t
+dns_dns64_create(isc_mem_t *mctx, isc_netaddr_t *prefix,
+ unsigned int prefixlen, isc_netaddr_t *suffix,
+ dns_acl_t *client, dns_acl_t *mapped, dns_acl_t *excluded,
+ unsigned int flags, dns_dns64_t **dns64);
+/*
+ * Create a dns64 record which is used to identify the set of clients
+ * it applies to and how to perform the DNS64 synthesis.
+ *
+ * 'prefix' and 'prefixlen' defined the leading bits of the AAAA records
+ * to be synthesised. 'suffix' defines the bits after the A records bits.
+ * If suffix is NULL zeros will be used for these bits. 'client' defines
+ * for which clients this record applies. If 'client' is NULL then all
+ * clients apply. 'mapped' defines which A records are candidated for
+ * mapping. If 'mapped' is NULL then all A records will be mapped.
+ * 'excluded' defines which AAAA are to be treated as non-existent for the
+ * purposed of determining whether to perform syntesis. If 'excluded' is
+ * NULL then no AAAA records prevent synthesis.
+ *
+ * If DNS_DNS64_RECURSIVE_ONLY is set then the record will only match if
+ * DNS_DNS64_RECURSIVE is set when calling dns_dns64_aaaaok() and
+ * dns_dns64_aaaafroma().
+ *
+ * If DNS_DNS64_BREAK_DNSSEC is set then the record will still apply if
+ * DNS_DNS64_DNSSEC is set when calling dns_dns64_aaaaok() and
+ * dns_dns64_aaaafroma() otherwise the record will be ignored.
+ *
+ * Requires:
+ * 'mctx' to be valid.
+ * 'prefix' to be valid and the address family to AF_INET6.
+ * 'prefixlen' to be one of 32, 40, 48, 56, 72 and 96.
+ * the bits not covered by prefixlen in prefix to
+ * be zero.
+ * 'suffix' to be NULL or the address family be set to AF_INET6
+ * and the leading 'prefixlen' + 32 bits of the 'suffix'
+ * to be zero. If 'prefixlen' is 40, 48 or 56 then the
+ * the leading 'prefixlen' + 40 bits of 'suffix' must be
+ * zero.
+ * 'client' to be NULL or a valid acl.
+ * 'mapped' to be NULL or a valid acl.
+ * 'exculded' to be NULL or a valid acl.
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * ISC_R_NOMEMORY
+ */
+
+void
+dns_dns64_destroy(dns_dns64_t **dns64p);
+/*
+ * Destroys a dns64 record.
+ *
+ * Requires the record to not be linked.
+ */
+
+isc_result_t
+dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
+ const dns_name_t *reqsigner, const dns_aclenv_t *env,
+ unsigned int flags, unsigned char *a, unsigned char *aaaa);
+/*
+ * dns_dns64_aaaafroma() determines whether to perform a DNS64 address
+ * synthesis from 'a' based on 'dns64', 'reqaddr', 'reqsigner', 'env',
+ * 'flags' and 'aaaa'. If synthesis is performed then the result is
+ * written to '*aaaa'.
+ *
+ * The synthesised address will be of the form:
+ *
+ * <prefix bits><a bits><suffix bits>
+ *
+ * If <a bits> straddle bits 64-71 of the AAAA record, then 8 zero bits will
+ * be inserted at bits 64-71.
+ *
+ * Requires:
+ * 'dns64' to be valid.
+ * 'reqaddr' to be valid.
+ * 'reqsigner' to be NULL or valid.
+ * 'env' to be valid.
+ * 'a' to point to a IPv4 address in network order.
+ * 'aaaa' to point to a IPv6 address buffer in network order.
+ *
+ * Returns:
+ * ISC_R_SUCCESS if synthesis was performed.
+ * DNS_R_DISALLOWED if there is no match.
+ */
+
+dns_dns64_t *
+dns_dns64_next(dns_dns64_t *dns64);
+/*
+ * Return the next dns64 record in the list.
+ */
+
+void
+dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64);
+/*
+ * Append the dns64 record to the list.
+ */
+
+void
+dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64);
+/*
+ * Unlink the dns64 record from the list.
+ */
+
+isc_boolean_t
+dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
+ const dns_name_t *reqsigner, const dns_aclenv_t *env,
+ unsigned int flags, dns_rdataset_t *rdataset,
+ isc_boolean_t *aaaaok, size_t aaaaoklen);
+/*
+ * Determine if there are any non-excluded AAAA records in from the
+ * matching dns64 records in the list starting at 'dns64'. If there
+ * is a non-exluded address return ISC_TRUE. If all addresses are
+ * excluded in the matched records return ISC_FALSE. If no records
+ * match then return ISC_TRUE.
+ *
+ * If aaaaok is defined then dns_dns64_aaaaok() return a array of which
+ * addresses in 'rdataset' were deemed to not be exclude by any matching
+ * record. If there are no matching records then all entries are set
+ * to ISC_TRUE.
+ *
+ * Requires
+ * 'rdataset' to be valid and to be for type AAAA and class IN.
+ * 'aaaaoklen' must match the number of records in 'rdataset'
+ * if 'aaaaok' in non NULL.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* DNS_DNS64_H */
diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h
index 5a1468a9c0f3..c6d910b3954e 100644
--- a/lib/dns/include/dns/dnssec.h
+++ b/lib/dns/include/dns/dnssec.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec.h,v 1.32.332.6 2009-06-22 23:47:18 tbox Exp $ */
+/* $Id: dnssec.h,v 1.42 2010-01-09 23:48:45 tbox Exp $ */
#ifndef DNS_DNSSEC_H
#define DNS_DNSSEC_H 1
@@ -25,12 +25,48 @@
#include <isc/lang.h>
#include <isc/stdtime.h>
+#include <dns/diff.h>
#include <dns/types.h>
#include <dst/dst.h>
ISC_LANG_BEGINDECLS
+/*
+ * Indicates how the signer found this key: in the key repository, at the
+ * zone apex, or specified by the user.
+ */
+typedef enum {
+ dns_keysource_unknown,
+ dns_keysource_repository,
+ dns_keysource_zoneapex,
+ dns_keysource_user
+} dns_keysource_t;
+
+/*
+ * A DNSSEC key and hints about its intended use gleaned from metadata
+ */
+struct dns_dnsseckey {
+ dst_key_t *key;
+ isc_boolean_t hint_publish; /*% metadata says to publish */
+ isc_boolean_t force_publish; /*% publish regardless of metadata */
+ isc_boolean_t hint_sign; /*% metadata says to sign with this key */
+ isc_boolean_t force_sign; /*% sign with key regardless of metadata */
+ isc_boolean_t hint_remove; /*% metadata says *don't* publish */
+ isc_boolean_t is_active; /*% key is already active */
+ isc_boolean_t first_sign; /*% key is newly becoming active */
+ unsigned int prepublish; /*% how long until active? */
+ dns_keysource_t source; /*% how the key was found */
+ isc_boolean_t ksk; /*% this is a key-signing key */
+ isc_boolean_t legacy; /*% this is old-style key with no
+ metadata (possibly generated by
+ an older version of BIND9) and
+ should be ignored when searching
+ for keys to import into the zone */
+ unsigned int index; /*% position in list */
+ ISC_LINK(dns_dnsseckey_t) link;
+};
+
isc_result_t
dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx,
dst_key_t **key);
@@ -184,6 +220,103 @@ dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
isc_boolean_t ignoretime, isc_mem_t *mctx);
+isc_result_t
+dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey,
+ dns_dnsseckey_t **dkp);
+/*%<
+ * Create and initialize a dns_dnsseckey_t structure.
+ *
+ * Requires:
+ *\li 'dkp' is not NULL and '*dkp' is NULL.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ */
+
+void
+dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp);
+/*%<
+ * Reclaim a dns_dnsseckey_t structure.
+ *
+ * Requires:
+ *\li 'dkp' is not NULL and '*dkp' is not NULL.
+ *
+ * Ensures:
+ *\li '*dkp' is NULL.
+ */
+
+isc_result_t
+dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory,
+ isc_mem_t *mctx, dns_dnsseckeylist_t *keylist);
+/*%<
+ * Search 'directory' for K* key files matching the name in 'origin'.
+ * Append all such keys, along with use hints gleaned from their
+ * metadata, onto 'keylist'.
+ *
+ * Requires:
+ *\li 'keylist' is not NULL
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOTFOUND
+ *\li #ISC_R_NOMEMORY
+ *\li any error returned by dns_name_totext(), isc_dir_open(), or
+ * dst_key_fromnamedfile()
+ *
+ * Ensures:
+ *\li On error, keylist is unchanged
+ */
+
+isc_result_t
+dns_dnssec_keylistfromrdataset(dns_name_t *origin,
+ const char *directory, isc_mem_t *mctx,
+ dns_rdataset_t *keyset, dns_rdataset_t *keysigs,
+ dns_rdataset_t *soasigs, isc_boolean_t savekeys,
+ isc_boolean_t public,
+ dns_dnsseckeylist_t *keylist);
+/*%<
+ * Append the contents of a DNSKEY rdataset 'keyset' to 'keylist'.
+ * Omit duplicates. If 'public' is ISC_FALSE, search 'directory' for
+ * matching key files, and load the private keys that go with
+ * the public ones. If 'savekeys' is ISC_TRUE, mark the keys so
+ * they will not be deleted or inactivated regardless of metadata.
+ *
+ * 'keysigs' and 'soasigs', if not NULL and associated, contain the
+ * RRSIGS for the DNSKEY and SOA records respectively and are used to mark
+ * whether a key is already active in the zone.
+ */
+
+isc_result_t
+dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
+ dns_dnsseckeylist_t *removed, dns_name_t *origin,
+ dns_ttl_t ttl, dns_diff_t *diff, isc_boolean_t allzsk,
+ isc_mem_t *mctx, void (*report)(const char *, ...));
+/*%<
+ * Update the list of keys in 'keys' with new key information in 'newkeys'.
+ *
+ * For each key in 'newkeys', see if it has a match in 'keys'.
+ * - If not, and if the metadata says the key should be published:
+ * add it to 'keys', and place a dns_difftuple into 'diff' so
+ * the key can be added to the DNSKEY set. If the metadata says it
+ * should be active, set the first_sign flag.
+ * - If so, and if the metadata says it should be removed:
+ * remove it from 'keys', and place a dns_difftuple into 'diff' so
+ * the key can be removed from the DNSKEY set. if 'removed' is non-NULL,
+ * copy the key into that list; otherwise destroy it.
+ * - Otherwise, make sure keys has current metadata.
+ *
+ * If 'allzsk' is true, we are allowing KSK-flagged keys to be used as
+ * ZSKs.
+ *
+ * 'ttl' is the TTL of the DNSKEY RRset; if it is longer than the
+ * time until a new key will be activated, then we have to delay the
+ * key's activation.
+ *
+ * 'report' points to a function for reporting status.
+ *
+ * On completion, any remaining keys in 'newkeys' are freed.
+ */
ISC_LANG_ENDDECLS
#endif /* DNS_DNSSEC_H */
diff --git a/lib/dns/include/dns/ds.h b/lib/dns/include/dns/ds.h
index 77a2cb8da147..04e4bab99525 100644
--- a/lib/dns/include/dns/ds.h
+++ b/lib/dns/include/dns/ds.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ds.h,v 1.10 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: ds.h,v 1.12 2010-12-23 23:47:08 tbox Exp $ */
#ifndef DNS_DS_H
#define DNS_DS_H 1
@@ -26,6 +26,11 @@
#define DNS_DSDIGEST_SHA1 (1)
#define DNS_DSDIGEST_SHA256 (2)
+#define DNS_DSDIGEST_GOST (3)
+
+/* should not be here... */
+
+#define ISC_GOST_DIGESTLENGTH 32U
/*
* Assuming SHA-256 digest type.
diff --git a/lib/dns/include/dns/ecdb.h b/lib/dns/include/dns/ecdb.h
new file mode 100644
index 000000000000..be71a52fd29e
--- /dev/null
+++ b/lib/dns/include/dns/ecdb.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ecdb.h,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+#ifndef DNS_ECDB_H
+#define DNS_ECDB_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/* TBD */
+
+/***
+ *** Imports
+ ***/
+
+#include <dns/types.h>
+
+/***
+ *** Types
+ ***/
+
+/***
+ *** Functions
+ ***/
+
+/* TBD: describe those */
+
+isc_result_t
+dns_ecdb_register(isc_mem_t *mctx, dns_dbimplementation_t **dbimp);
+
+void
+dns_ecdb_unregister(dns_dbimplementation_t **dbimp);
+
+ISC_LANG_ENDDECLS
+
+#endif /* DNS_ECDB_H */
diff --git a/lib/dns/include/dns/events.h b/lib/dns/include/dns/events.h
index 689566bbc3d7..d9858336f778 100644
--- a/lib/dns/include/dns/events.h
+++ b/lib/dns/include/dns/events.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: events.h,v 1.49.332.4 2010-05-10 23:48:14 tbox Exp $ */
+/* $Id: events.h,v 1.56 2010-12-21 03:11:42 marka Exp $ */
#ifndef DNS_EVENTS_H
#define DNS_EVENTS_H 1
@@ -69,6 +69,11 @@
#define DNS_EVENT_ACACHECLEAN (ISC_EVENTCLASS_DNS + 39)
#define DNS_EVENT_ACACHEOVERMEM (ISC_EVENTCLASS_DNS + 40)
#define DNS_EVENT_RBTPRUNE (ISC_EVENTCLASS_DNS + 41)
+#define DNS_EVENT_MANAGEKEYS (ISC_EVENTCLASS_DNS + 42)
+#define DNS_EVENT_CLIENTRESDONE (ISC_EVENTCLASS_DNS + 43)
+#define DNS_EVENT_CLIENTREQDONE (ISC_EVENTCLASS_DNS + 44)
+#define DNS_EVENT_ADBGROWENTRIES (ISC_EVENTCLASS_DNS + 45)
+#define DNS_EVENT_ADBGROWNAMES (ISC_EVENTCLASS_DNS + 46)
#define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0)
#define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535)
diff --git a/lib/dns/include/dns/forward.h b/lib/dns/include/dns/forward.h
index 5fbe898e4e67..683969d594d1 100644
--- a/lib/dns/include/dns/forward.h
+++ b/lib/dns/include/dns/forward.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: forward.h,v 1.11 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: forward.h,v 1.13 2009-09-02 23:48:02 tbox Exp $ */
#ifndef DNS_FORWARD_H
#define DNS_FORWARD_H 1
@@ -67,6 +67,21 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
*/
isc_result_t
+dns_fwdtable_delete(dns_fwdtable_t *fwdtable, dns_name_t *name);
+/*%<
+ * Removes an entry for 'name' from the forwarding table. If an entry
+ * that exactly matches 'name' does not exist, ISC_R_NOTFOUND will be returned.
+ *
+ * Requires:
+ * \li fwdtable is a valid forwarding table.
+ * \li name is a valid name
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_NOTFOUND
+ */
+
+isc_result_t
dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name,
dns_forwarders_t **forwardersp);
/*%<
diff --git a/lib/dns/include/dns/journal.h b/lib/dns/include/dns/journal.h
index 9e56c19c2400..28a7dbe31b98 100644
--- a/lib/dns/include/dns/journal.h
+++ b/lib/dns/include/dns/journal.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: journal.h,v 1.33.120.4 2009-11-04 23:47:25 tbox Exp $ */
+/* $Id: journal.h,v 1.37 2009-11-04 23:48:18 tbox Exp $ */
#ifndef DNS_JOURNAL_H
#define DNS_JOURNAL_H 1
diff --git a/lib/dns/include/dns/keydata.h b/lib/dns/include/dns/keydata.h
new file mode 100644
index 000000000000..36bf590f6446
--- /dev/null
+++ b/lib/dns/include/dns/keydata.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: keydata.h,v 1.2 2009-06-30 02:52:32 each Exp $ */
+
+#ifndef DNS_KEYDATA_H
+#define DNS_KEYDATA_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file dns/keydata.h
+ * \brief
+ * KEYDATA utilities.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#include <dns/types.h>
+#include <dns/rdatastruct.h>
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+dns_keydata_todnskey(dns_rdata_keydata_t *keydata,
+ dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx);
+
+isc_result_t
+dns_keydata_fromdnskey(dns_rdata_keydata_t *keydata,
+ dns_rdata_dnskey_t *dnskey,
+ isc_uint32_t refresh, isc_uint32_t addhd,
+ isc_uint32_t removehd, isc_mem_t *mctx);
+
+ISC_LANG_ENDDECLS
+
+#endif /* DNS_KEYDATA_H */
diff --git a/lib/dns/include/dns/keytable.h b/lib/dns/include/dns/keytable.h
index 40c4b16e14c8..a53ec08b9095 100644
--- a/lib/dns/include/dns/keytable.h
+++ b/lib/dns/include/dns/keytable.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: keytable.h,v 1.16 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: keytable.h,v 1.23 2010-06-25 03:24:05 marka Exp $ */
#ifndef DNS_KEYTABLE_H
#define DNS_KEYTABLE_H 1
@@ -42,6 +42,10 @@
*/
#include <isc/lang.h>
+#include <isc/magic.h>
+#include <isc/refcount.h>
+#include <isc/rwlock.h>
+#include <isc/stdtime.h>
#include <dns/types.h>
@@ -49,6 +53,33 @@
ISC_LANG_BEGINDECLS
+struct dns_keytable {
+ /* Unlocked. */
+ unsigned int magic;
+ isc_mem_t *mctx;
+ isc_mutex_t lock;
+ isc_rwlock_t rwlock;
+ /* Locked by lock. */
+ isc_uint32_t active_nodes;
+ /* Locked by rwlock. */
+ isc_uint32_t references;
+ dns_rbt_t *table;
+};
+
+#define KEYTABLE_MAGIC ISC_MAGIC('K', 'T', 'b', 'l')
+#define VALID_KEYTABLE(kt) ISC_MAGIC_VALID(kt, KEYTABLE_MAGIC)
+
+struct dns_keynode {
+ unsigned int magic;
+ isc_refcount_t refcount;
+ dst_key_t * key;
+ isc_boolean_t managed;
+ struct dns_keynode * next;
+};
+
+#define KEYNODE_MAGIC ISC_MAGIC('K', 'N', 'o', 'd')
+#define VALID_KEYNODE(kn) ISC_MAGIC_VALID(kn, KEYNODE_MAGIC)
+
isc_result_t
dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep);
/*%<
@@ -106,16 +137,22 @@ dns_keytable_detach(dns_keytable_t **keytablep);
*/
isc_result_t
-dns_keytable_add(dns_keytable_t *keytable, dst_key_t **keyp);
+dns_keytable_add(dns_keytable_t *keytable, isc_boolean_t managed,
+ dst_key_t **keyp);
/*%<
- * Add '*keyp' to 'keytable'.
+ * Add '*keyp' to 'keytable' (using the name in '*keyp').
+ * The value of keynode->managed is set to 'managed'
*
* Notes:
*
*\li Ownership of *keyp is transferred to the keytable.
+ *\li If the key already exists in the table, ISC_R_EXISTS is
+ * returned and the new key is freed.
*
* Requires:
*
+ *\li 'keytable' points to a valid keytable.
+ *
*\li keyp != NULL && *keyp is a valid dst_key_t *.
*
* Ensures:
@@ -125,11 +162,124 @@ dns_keytable_add(dns_keytable_t *keytable, dst_key_t **keyp);
* Returns:
*
*\li ISC_R_SUCCESS
+ *\li ISC_R_EXISTS
+ *
+ *\li Any other result indicates failure.
+ */
+
+isc_result_t
+dns_keytable_marksecure(dns_keytable_t *keytable, dns_name_t *name);
+/*%<
+ * Add a null key to 'keytable' for name 'name'. This marks the
+ * name as a secure domain, but doesn't supply any key data to allow the
+ * domain to be validated. (Used when automated trust anchor management
+ * has gotten broken by a zone misconfiguration; for example, when the
+ * active key has been revoked but the stand-by key was still in its 30-day
+ * waiting period for validity.)
+ *
+ * Notes:
+ *
+ *\li If a key already exists in the table, ISC_R_EXISTS is
+ * returned and nothing is done.
+ *
+ * Requires:
+ *
+ *\li 'keytable' points to a valid keytable.
+ *
+ *\li keyp != NULL && *keyp is a valid dst_key_t *.
+ *
+ * Returns:
+ *
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_EXISTS
+ *
+ *\li Any other result indicates failure.
+ */
+
+isc_result_t
+dns_keytable_delete(dns_keytable_t *keytable, dns_name_t *keyname);
+/*%<
+ * Delete node(s) from 'keytable' matching name 'keyname'
+ *
+ * Requires:
+ *
+ *\li 'keytable' points to a valid keytable.
+ *
+ *\li 'name' is not NULL
+ *
+ * Returns:
+ *
+ *\li ISC_R_SUCCESS
+ *
+ *\li Any other result indicates failure.
+ */
+
+isc_result_t
+dns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey);
+/*%<
+ * Delete node(s) from 'keytable' containing copies of the key pointed
+ * to by 'dstkey'
+ *
+ * Requires:
+ *
+ *\li 'keytable' points to a valid keytable.
+ *\li 'dstkey' is not NULL
+ *
+ * Returns:
+ *
+ *\li ISC_R_SUCCESS
*
*\li Any other result indicates failure.
*/
isc_result_t
+dns_keytable_find(dns_keytable_t *keytable, dns_name_t *keyname,
+ dns_keynode_t **keynodep);
+/*%<
+ * Search for the first instance of a key named 'name' in 'keytable',
+ * without regard to keyid and algorithm. Use dns_keytable_nextkeynode()
+ * to find subsequent instances.
+ *
+ * Requires:
+ *
+ *\li 'keytable' is a valid keytable.
+ *
+ *\li 'name' is a valid absolute name.
+ *
+ *\li keynodep != NULL && *keynodep == NULL
+ *
+ * Returns:
+ *
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_NOTFOUND
+ *
+ *\li Any other result indicates an error.
+ */
+
+isc_result_t
+dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
+ dns_keynode_t **nextnodep);
+/*%<
+ * Return for the next key after 'keynode' in 'keytable', without regard to
+ * keyid and algorithm.
+ *
+ * Requires:
+ *
+ *\li 'keytable' is a valid keytable.
+ *
+ *\li 'keynode' is a valid keynode.
+ *
+ *\li nextnodep != NULL && *nextnodep == NULL
+ *
+ * Returns:
+ *
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_NOTFOUND
+ *
+ *\li Any other result indicates an error.
+ */
+
+isc_result_t
dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name,
dns_secalg_t algorithm, dns_keytag_t tag,
dns_keynode_t **keynodep);
@@ -157,7 +307,7 @@ dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name,
isc_result_t
dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
- dns_keynode_t **nextnodep);
+ dns_keynode_t **nextnodep);
/*%<
* Search for the next key with the same properties as 'keynode' in
* 'keytable' as found by dns_keytable_findkeynode().
@@ -201,6 +351,22 @@ dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name,
*/
void
+dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source,
+ dns_keynode_t **target);
+/*%<
+ * Attach a keynode and and increment the active_nodes counter in a
+ * corresponding keytable.
+ *
+ * Requires:
+ *
+ *\li 'keytable' is a valid keytable.
+ *
+ *\li 'source' is a valid keynode.
+ *
+ *\li 'target' is not null and '*target' is null.
+ */
+
+void
dns_keytable_detachkeynode(dns_keytable_t *keytable,
dns_keynode_t **keynodep);
/*%<
@@ -244,12 +410,48 @@ dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name,
*\li Any other result is an error.
*/
+isc_result_t
+dns_keytable_dump(dns_keytable_t *keytable, FILE *fp);
+/*%<
+ * Dump the keytable on fp.
+ */
+
dst_key_t *
dns_keynode_key(dns_keynode_t *keynode);
/*%<
* Get the DST key associated with keynode.
*/
+isc_boolean_t
+dns_keynode_managed(dns_keynode_t *keynode);
+/*%<
+ * Is this flagged as a managed key?
+ */
+
+isc_result_t
+dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target);
+/*%<
+ * Allocate space for a keynode
+ */
+
+void
+dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target);
+/*%<
+ * Attach keynode 'source' to '*target'
+ */
+
+void
+dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **target);
+/*%<
+ * Detach a single keynode, without touching any keynodes that
+ * may be pointed to by its 'next' pointer
+ */
+
+void
+dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **target);
+/*%<
+ * Detach a keynode and all its succesors.
+ */
ISC_LANG_ENDDECLS
#endif /* DNS_KEYTABLE_H */
diff --git a/lib/dns/include/dns/keyvalues.h b/lib/dns/include/dns/keyvalues.h
index 70ca3fa2cf67..210765708bc6 100644
--- a/lib/dns/include/dns/keyvalues.h
+++ b/lib/dns/include/dns/keyvalues.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: keyvalues.h,v 1.23.48.4 2010-01-15 23:47:33 tbox Exp $ */
+/* $Id: keyvalues.h,v 1.29 2010-12-23 23:47:08 tbox Exp $ */
#ifndef DNS_KEYVALUES_H
#define DNS_KEYVALUES_H 1
@@ -42,7 +42,7 @@
#define DNS_KEYOWNER_ENTITY 0x0200 /*%< key is assoc. with entity eg host */
#define DNS_KEYOWNER_ZONE 0x0100 /*%< key is zone key */
#define DNS_KEYOWNER_RESERVED 0x0300 /*%< reserved meaning */
-#define DNS_KEYFLAG_REVOKE 0x0080 /*%< key revoked (per rfc5001) */
+#define DNS_KEYFLAG_REVOKE 0x0080 /*%< key revoked (per rfc5011) */
#define DNS_KEYFLAG_RESERVED9 0x0040 /*%< reserved - must be zero */
#define DNS_KEYFLAG_RESERVED10 0x0020 /*%< reserved - must be zero */
#define DNS_KEYFLAG_RESERVED11 0x0010 /*%< reserved - must be zero */
@@ -51,7 +51,6 @@
#define DNS_KEYFLAG_RESERVEDMASK (DNS_KEYFLAG_RESERVED2 | \
DNS_KEYFLAG_RESERVED4 | \
DNS_KEYFLAG_RESERVED5 | \
- DNS_KEYFLAG_RESERVED8 | \
DNS_KEYFLAG_RESERVED9 | \
DNS_KEYFLAG_RESERVED10 | \
DNS_KEYFLAG_RESERVED11 )
@@ -71,6 +70,7 @@
#define DNS_KEYALG_NSEC3RSASHA1 7
#define DNS_KEYALG_RSASHA256 8
#define DNS_KEYALG_RSASHA512 10
+#define DNS_KEYALG_ECCGOST 12
#define DNS_KEYALG_INDIRECT 252
#define DNS_KEYALG_PRIVATEDNS 253
#define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */
@@ -99,4 +99,6 @@
#define DNS_SIG_DSAMINBYTES 213
#define DNS_SIG_DSAMAXBYTES 405
+#define DNS_SIG_GOSTSIGSIZE 64
+
#endif /* DNS_KEYVALUES_H */
diff --git a/lib/dns/include/dns/lib.h b/lib/dns/include/dns/lib.h
index 361ef8fc7d5e..70874b7568df 100644
--- a/lib/dns/include/dns/lib.h
+++ b/lib/dns/include/dns/lib.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lib.h,v 1.16 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: lib.h,v 1.18 2009-09-02 23:48:02 tbox Exp $ */
#ifndef DNS_LIB_H
#define DNS_LIB_H 1
@@ -40,6 +40,20 @@ dns_lib_initmsgcat(void);
* has not already been initialized.
*/
+isc_result_t
+dns_lib_init(void);
+/*%<
+ * A set of initialization procedure used in the DNS library. This function
+ * is provided for an application that is not aware of the underlying ISC or
+ * DNS libraries much.
+ */
+
+void
+dns_lib_shutdown(void);
+/*%<
+ * Free temporary resources allocated in dns_lib_init().
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_LIB_H */
diff --git a/lib/dns/include/dns/log.h b/lib/dns/include/dns/log.h
index 4b648ff66227..a5650edfbdc4 100644
--- a/lib/dns/include/dns/log.h
+++ b/lib/dns/include/dns/log.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: log.h,v 1.42.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: log.h,v 1.45 2009-12-18 22:16:49 each Exp $ */
/*! \file dns/log.h
* \author Principal Authors: DCL */
@@ -73,6 +73,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[];
#define DNS_LOGMODULE_HINTS (&dns_modules[24])
#define DNS_LOGMODULE_ACACHE (&dns_modules[25])
#define DNS_LOGMODULE_DLZ (&dns_modules[26])
+#define DNS_LOGMODULE_DNSSEC (&dns_modules[27])
ISC_LANG_BEGINDECLS
diff --git a/lib/dns/include/dns/lookup.h b/lib/dns/include/dns/lookup.h
index 81bb9b99afbf..7e6a566ae34b 100644
--- a/lib/dns/include/dns/lookup.h
+++ b/lib/dns/include/dns/lookup.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lookup.h,v 1.12.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: lookup.h,v 1.14 2009-01-17 23:47:43 tbox Exp $ */
#ifndef DNS_LOOKUP_H
#define DNS_LOOKUP_H 1
diff --git a/lib/dns/include/dns/master.h b/lib/dns/include/dns/master.h
index 3f3a4de650ca..2ee637488bdd 100644
--- a/lib/dns/include/dns/master.h
+++ b/lib/dns/include/dns/master.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: master.h,v 1.51 2008-04-02 02:37:42 marka Exp $ */
+/* $Id: master.h,v 1.53 2009-07-01 23:47:36 tbox Exp $ */
#ifndef DNS_MASTER_H
#define DNS_MASTER_H 1
@@ -56,6 +56,7 @@
#define DNS_MASTER_CHECKMXFAIL 0x00001000
#define DNS_MASTER_RESIGN 0x00002000
+#define DNS_MASTER_KEY 0x00004000 /*%< Loading a key zone master file. */
ISC_LANG_BEGINDECLS
diff --git a/lib/dns/include/dns/masterdump.h b/lib/dns/include/dns/masterdump.h
index 96a198df8982..684dd82d53b6 100644
--- a/lib/dns/include/dns/masterdump.h
+++ b/lib/dns/include/dns/masterdump.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.h,v 1.42.602.2 2011-06-02 23:46:22 tbox Exp $ */
+/* $Id: masterdump.h,v 1.42.596.2 2011-06-02 23:47:35 tbox Exp $ */
#ifndef DNS_MASTERDUMP_H
#define DNS_MASTERDUMP_H 1
diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h
index 98fb321f8512..438de1ecf7e5 100644
--- a/lib/dns/include/dns/message.h
+++ b/lib/dns/include/dns/message.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: message.h,v 1.125.118.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: message.h,v 1.132 2010-03-04 23:50:34 tbox Exp $ */
#ifndef DNS_MESSAGE_H
#define DNS_MESSAGE_H 1
@@ -81,8 +81,7 @@
* name = NULL;
* name = dns_message_gettempname(message, &name);
* dns_name_init(name, NULL);
- * result = dns_name_fromtext(name, &source, dns_rootname, ISC_FALSE,
- * buffer);
+ * result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer);
* dns_message_takebuffer(message, &buffer);
* \endcode
*
@@ -137,6 +136,8 @@ typedef int dns_pseudosection_t;
typedef int dns_messagetextflag_t;
#define DNS_MESSAGETEXTFLAG_NOCOMMENTS 0x0001
#define DNS_MESSAGETEXTFLAG_NOHEADERS 0x0002
+#define DNS_MESSAGETEXTFLAG_ONESOA 0x0004
+#define DNS_MESSAGETEXTFLAG_OMITSOA 0x0008
/*
* Dynamic update names for these sections.
@@ -174,6 +175,9 @@ typedef int dns_messagetextflag_t;
additional section. */
#define DNS_MESSAGERENDER_PREFER_AAAA 0x0010 /*%< prefer AAAA records in
additional section. */
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+#define DNS_MESSAGERENDER_FILTER_AAAA 0x0020 /*%< filter AAAA records */
+#endif
typedef struct dns_msgblock dns_msgblock_t;
@@ -369,6 +373,14 @@ dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
* #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will
* be emitted.
*
+ * If #DNS_MESSAGETEXTFLAG_ONESOA is set then only print the
+ * first SOA record in the answer section. If
+ * #DNS_MESSAGETEXTFLAG_OMITSOA is set don't print any SOA records
+ * in the answer section. These are useful for suppressing the
+ * display of the second SOA record in a AXFR by setting
+ * #DNS_MESSAGETEXTFLAG_ONESOA on the first message in a AXFR stream
+ * and #DNS_MESSAGETEXTFLAG_OMITSOA on subsequent messages.
+ *
* Requires:
*
*\li 'msg' is a valid message.
diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h
index 801c9ac164cf..c13a85d52c43 100644
--- a/lib/dns/include/dns/name.h
+++ b/lib/dns/include/dns/name.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: name.h,v 1.126.332.5 2010-07-09 23:45:55 tbox Exp $ */
+/* $Id: name.h,v 1.137 2011-01-13 04:59:26 tbox Exp $ */
#ifndef DNS_NAME_H
#define DNS_NAME_H 1
@@ -121,21 +121,27 @@ struct dns_name {
#define DNS_NAME_MAGIC ISC_MAGIC('D','N','S','n')
-#define DNS_NAMEATTR_ABSOLUTE 0x0001
-#define DNS_NAMEATTR_READONLY 0x0002
-#define DNS_NAMEATTR_DYNAMIC 0x0004
-#define DNS_NAMEATTR_DYNOFFSETS 0x0008
-#define DNS_NAMEATTR_NOCOMPRESS 0x0010
+#define DNS_NAMEATTR_ABSOLUTE 0x00000001
+#define DNS_NAMEATTR_READONLY 0x00000002
+#define DNS_NAMEATTR_DYNAMIC 0x00000004
+#define DNS_NAMEATTR_DYNOFFSETS 0x00000008
+#define DNS_NAMEATTR_NOCOMPRESS 0x00000010
/*
* Attributes below 0x0100 reserved for name.c usage.
*/
-#define DNS_NAMEATTR_CACHE 0x0100 /*%< Used by resolver. */
-#define DNS_NAMEATTR_ANSWER 0x0200 /*%< Used by resolver. */
-#define DNS_NAMEATTR_NCACHE 0x0400 /*%< Used by resolver. */
-#define DNS_NAMEATTR_CHAINING 0x0800 /*%< Used by resolver. */
-#define DNS_NAMEATTR_CHASE 0x1000 /*%< Used by resolver. */
-#define DNS_NAMEATTR_WILDCARD 0x2000 /*%< Used by server. */
+#define DNS_NAMEATTR_CACHE 0x00000100 /*%< Used by resolver. */
+#define DNS_NAMEATTR_ANSWER 0x00000200 /*%< Used by resolver. */
+#define DNS_NAMEATTR_NCACHE 0x00000400 /*%< Used by resolver. */
+#define DNS_NAMEATTR_CHAINING 0x00000800 /*%< Used by resolver. */
+#define DNS_NAMEATTR_CHASE 0x00001000 /*%< Used by resolver. */
+#define DNS_NAMEATTR_WILDCARD 0x00002000 /*%< Used by server. */
+#define DNS_NAMEATTR_PREREQUISITE 0x00004000 /*%< Used by client. */
+#define DNS_NAMEATTR_UPDATE 0x00008000 /*%< Used by client. */
+#define DNS_NAMEATTR_HASUPDATEREC 0x00010000 /*%< Used by client. */
+/*
+ * Various flags.
+ */
#define DNS_NAME_DOWNCASE 0x0001
#define DNS_NAME_CHECKNAMES 0x0002 /*%< Used by rdata. */
#define DNS_NAME_CHECKNAMESFAIL 0x0004 /*%< Used by rdata. */
@@ -750,7 +756,7 @@ dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
isc_result_t
dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
- dns_name_t *origin, unsigned int options,
+ const dns_name_t *origin, unsigned int options,
isc_buffer_t *target);
/*%<
* Convert the textual representation of a DNS name at source
@@ -1139,6 +1145,56 @@ dns_name_format(dns_name_t *name, char *cp, unsigned int size);
*/
isc_result_t
+dns_name_tostring(dns_name_t *source, char **target, isc_mem_t *mctx);
+/*%<
+ * Convert 'name' to string format, allocating sufficient memory to
+ * hold it (free with isc_mem_free()).
+ *
+ * Differs from dns_name_format in that it allocates its own memory.
+ *
+ * Requires:
+ *
+ *\li 'name' is a valid name.
+ *\li 'target' is not NULL.
+ *\li '*target' is NULL.
+ *
+ * Returns:
+ *
+ *\li ISC_R_SUCCESS
+ *
+ *\li Any error that dns_name_totext() can return.
+ */
+
+isc_result_t
+dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options,
+ isc_mem_t *mctx);
+isc_result_t
+dns_name_fromstring2(dns_name_t *target, const char *src,
+ const dns_name_t *origin, unsigned int options,
+ isc_mem_t *mctx);
+/*%<
+ * Convert a string to a name and place it in target, allocating memory
+ * as necessary. 'options' has the same semantics as that of
+ * dns_name_fromtext().
+ *
+ * If 'target' has a buffer then the name will be copied into it rather than
+ * memory being allocated.
+ *
+ * Requires:
+ *
+ * \li 'target' is a valid name that is not read-only.
+ * \li 'src' is not NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *
+ *\li Any error that dns_name_fromtext() can return.
+ *
+ *\li Any error that dns_name_dup() can return.
+ */
+
+isc_result_t
dns_name_settotextfilter(dns_name_totextfilter_t proc);
/*%<
* Set / clear a thread specific function 'proc' to be called at the
diff --git a/lib/dns/include/dns/ncache.h b/lib/dns/include/dns/ncache.h
index 0c1d950fd7cc..32345cf20691 100644
--- a/lib/dns/include/dns/ncache.h
+++ b/lib/dns/include/dns/ncache.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ncache.h,v 1.25.48.4 2010-05-14 23:47:50 tbox Exp $ */
+/* $Id: ncache.h,v 1.29 2010-05-14 23:50:40 tbox Exp $ */
#ifndef DNS_NCACHE_H
#define DNS_NCACHE_H 1
diff --git a/lib/dns/include/dns/nsec3.h b/lib/dns/include/dns/nsec3.h
index ba808e498217..ac0c8f2c00ed 100644
--- a/lib/dns/include/dns/nsec3.h
+++ b/lib/dns/include/dns/nsec3.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2008-2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3.h,v 1.5.48.3 2009-10-06 21:20:18 each Exp $ */
+/* $Id: nsec3.h,v 1.12 2010-05-18 02:38:10 tbox Exp $ */
#ifndef DNS_NSEC3_H
#define DNS_NSEC3_H 1
@@ -110,6 +110,12 @@ isc_result_t
dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
dns_name_t *name, dns_ttl_t nsecttl,
isc_boolean_t unsecure, dns_diff_t *diff);
+
+isc_result_t
+dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
+ dns_name_t *name, dns_ttl_t nsecttl,
+ isc_boolean_t unsecure, dns_rdatatype_t private,
+ dns_diff_t *diff);
/*%<
* Add NSEC3 records for 'name', recording the change in 'diff'.
* Adjust previous NSEC3 records, if any, to reflect the addition.
@@ -130,6 +136,10 @@ dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
* NSEC3PARAM record otherwise OPTOUT will be inherited from the previous
* record in the chain.
*
+ * dns_nsec3_addnsec3sx() is similar to dns_nsec3_addnsec3s() but 'private'
+ * specifies the type of the private rdataset to be checked in addition to
+ * the nsec3param rdataset at the zone apex.
+ *
* Requires:
* 'db' to be valid.
* 'version' to be valid or NULL.
@@ -145,6 +155,10 @@ dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
isc_result_t
dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
dns_diff_t *diff);
+
+isc_result_t
+dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
+ dns_rdatatype_t private, dns_diff_t *diff);
/*%<
* Remove NSEC3 records for 'name', recording the change in 'diff'.
* Adjust previous NSEC3 records, if any, to reflect the removal.
@@ -156,6 +170,10 @@ dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
* to dns_nsec3_addnsec3s(). Unlike dns_nsec3_addnsec3s() updated NSEC3
* records have the OPTOUT flag preserved.
*
+ * dns_nsec3_delnsec3sx() is similar to dns_nsec3_delnsec3s() but 'private'
+ * specifies the type of the private rdataset to be checked in addition to
+ * the nsec3param rdataset at the zone apex.
+ *
* Requires:
* 'db' to be valid.
* 'version' to be valid or NULL.
@@ -167,10 +185,19 @@ dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
isc_result_t
dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
isc_boolean_t complete, isc_boolean_t *answer);
+
+isc_result_t
+dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
+ isc_boolean_t complete, dns_rdatatype_t private,
+ isc_boolean_t *answer);
/*%<
* Check if there are any complete/to be built NSEC3 chains.
* If 'complete' is ISC_TRUE only complete chains will be recognized.
*
+ * dns_nsec3_activex() is similar to dns_nsec3_active() but 'private'
+ * specifies the type of the private rdataset to be checked in addition to
+ * the nsec3param rdataset at the zone apex.
+ *
* Requires:
* 'db' to be valid.
* 'version' to be valid or NULL.
@@ -191,6 +218,36 @@ dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
* 'iterationsp' to be non NULL.
*/
+isc_boolean_t
+dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
+ unsigned char *buf, size_t buflen);
+/*%<
+ * Convert a private rdata to a nsec3param rdata.
+ *
+ * Return ISC_TRUE if 'src' could be successfully converted.
+ *
+ * 'buf' should be at least DNS_NSEC3PARAM_BUFFERSIZE in size.
+ */
+
+void
+dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
+ dns_rdatatype_t privatetype,
+ unsigned char *buf, size_t buflen);
+/*%<
+ * Convert a nsec3param rdata to a private rdata.
+ *
+ * 'buf' should be at least src->length + 1 in size.
+ */
+
+isc_result_t
+dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
+ dns_zone_t *zone, dns_diff_t *diff);
+
+/*%<
+ * Mark NSEC3PARAM for deletion.
+ */
+
+
ISC_LANG_ENDDECLS
#endif /* DNS_NSEC3_H */
diff --git a/lib/dns/include/dns/peer.h b/lib/dns/include/dns/peer.h
index 1f8a42e3fc83..a1a3e34ec38e 100644
--- a/lib/dns/include/dns/peer.h
+++ b/lib/dns/include/dns/peer.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: peer.h,v 1.33.118.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: peer.h,v 1.35 2009-01-17 23:47:43 tbox Exp $ */
#ifndef DNS_PEER_H
#define DNS_PEER_H 1
diff --git a/lib/dns/include/dns/private.h b/lib/dns/include/dns/private.h
new file mode 100644
index 000000000000..ffedb5ff4c22
--- /dev/null
+++ b/lib/dns/include/dns/private.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: private.h,v 1.3 2009-10-09 23:48:09 tbox Exp $ */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#include <dns/types.h>
+#include <dns/db.h>
+
+#ifndef DNS_PRIVATE_H
+#define DNS_PRIVATE_H
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+dns_private_chains(dns_db_t *db, dns_dbversion_t *ver,
+ dns_rdatatype_t privatetype,
+ isc_boolean_t *build_nsec, isc_boolean_t *build_nsec3);
+/*%<
+ * Examine the NSEC, NSEC3PARAM and privatetype RRsets at the apex of the
+ * database to determine which of NSEC or NSEC3 chains we are currently
+ * maintaining. In normal operations only one of NSEC or NSEC3 is being
+ * maintained but when we are transitiong between NSEC and NSEC3 we need
+ * to update both sets of chains. If 'privatetype' is zero then the
+ * privatetype RRset will not be examined.
+ *
+ * Requires:
+ * \li 'db' is valid.
+ * \li 'version' is valid or NULL.
+ * \li 'build_nsec' is a pointer to a isc_boolean_t or NULL.
+ * \li 'build_nsec3' is a pointer to a isc_boolean_t or NULL.
+ *
+ * Returns:
+ * \li ISC_R_SUCCESS, 'build_nsec' and 'build_nsec3' will be valid.
+ * \li other on error
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif
diff --git a/lib/dns/include/dns/rbt.h b/lib/dns/include/dns/rbt.h
index 72ef2f1febb4..6149e8d66749 100644
--- a/lib/dns/include/dns/rbt.h
+++ b/lib/dns/include/dns/rbt.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbt.h,v 1.71.48.3 2009-10-20 05:06:04 marka Exp $ */
+/* $Id: rbt.h,v 1.77 2009-11-04 01:18:19 marka Exp $ */
#ifndef DNS_RBT_H
#define DNS_RBT_H 1
@@ -70,6 +70,12 @@ ISC_LANG_BEGINDECLS
* multiple dns_rbtnode structures will not work.
*/
typedef struct dns_rbtnode dns_rbtnode_t;
+enum {
+ DNS_RBT_NSEC_NORMAL=0, /* in main tree */
+ DNS_RBT_NSEC_HAS_NSEC=1, /* also has node in nsec tree */
+ DNS_RBT_NSEC_NSEC=2, /* in nsec tree */
+ DNS_RBT_NSEC_NSEC3=3 /* in nsec3 tree */
+};
struct dns_rbtnode {
#if DNS_RBT_USEMAGIC
unsigned int magic;
@@ -94,10 +100,7 @@ struct dns_rbtnode {
* The following bitfields add up to a total bitwidth of 32.
* The range of values necessary for each item is indicated,
* but in the case of "attributes" the field is wider to accommodate
- * possible future expansion. "offsetlen" could be one bit
- * narrower by always adjusting its value by 1 to find the real
- * offsetlen, but doing so does not gain anything (except perhaps
- * another bit for "attributes", which doesn't yet need any more).
+ * possible future expansion.
*
* In each case below the "range" indicated is what's _necessary_ for
* the bitfield to hold, not what it actually _can_ hold.
@@ -105,8 +108,8 @@ struct dns_rbtnode {
unsigned int is_root : 1; /*%< range is 0..1 */
unsigned int color : 1; /*%< range is 0..1 */
unsigned int find_callback : 1; /*%< range is 0..1 */
- unsigned int attributes : 4; /*%< range is 0..2 */
- unsigned int nsec3 : 1; /*%< range is 0..1 */
+ unsigned int attributes : 3; /*%< range is 0..2 */
+ unsigned int nsec : 2; /*%< range is 0..3 */
unsigned int namelen : 8; /*%< range is 1..255 */
unsigned int offsetlen : 8; /*%< range is 1..128 */
unsigned int oldnamelen : 8; /*%< range is 1..255 */
@@ -909,7 +912,7 @@ dns_rbtnodechain_nextflat(dns_rbtnodechain_t *chain, dns_name_t *name);
} while (0)
#else /* DNS_RBT_USEISCREFCOUNT */
#define dns_rbtnode_refinit(node, n) ((node)->references = (n))
-#define dns_rbtnode_refdestroy(node) (REQUIRE((node)->references == 0))
+#define dns_rbtnode_refdestroy(node) REQUIRE((node)->references == 0)
#define dns_rbtnode_refcurrent(node) ((node)->references)
#define dns_rbtnode_refincrement0(node, refs) \
do { \
diff --git a/lib/dns/include/dns/rdata.h b/lib/dns/include/dns/rdata.h
index 1674b0cd2036..b70a353dde1a 100644
--- a/lib/dns/include/dns/rdata.h
+++ b/lib/dns/include/dns/rdata.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdata.h,v 1.70.120.3 2009-02-16 00:29:27 marka Exp $ */
+/* $Id: rdata.h,v 1.77 2009-12-04 21:09:33 marka Exp $ */
#ifndef DNS_RDATA_H
#define DNS_RDATA_H 1
@@ -95,6 +95,7 @@
#include <dns/types.h>
#include <dns/name.h>
+#include <dns/message.h>
ISC_LANG_BEGINDECLS
@@ -124,9 +125,27 @@ struct dns_rdata {
#define DNS_RDATA_INIT { NULL, 0, 0, 0, 0, {(void*)(-1), (void *)(-1)}}
+#define DNS_RDATA_CHECKINITIALIZED
+#ifdef DNS_RDATA_CHECKINITIALIZED
+#define DNS_RDATA_INITIALIZED(rdata) \
+ ((rdata)->data == NULL && (rdata)->length == 0 && \
+ (rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 0 && \
+ !ISC_LINK_LINKED((rdata), link))
+#else
+#ifdef ISC_LIST_CHECKINIT
+#define DNS_RDATA_INITIALIZED(rdata) \
+ (!ISC_LINK_LINKED((rdata), link))
+#else
+#define DNS_RDATA_INITIALIZED(rdata) ISC_TRUE
+#endif
+#endif
+
#define DNS_RDATA_UPDATE 0x0001 /*%< update pseudo record. */
#define DNS_RDATA_OFFLINE 0x0002 /*%< RRSIG has a offline key. */
+#define DNS_RDATA_VALIDFLAGS(rdata) \
+ (((rdata)->flags & ~(DNS_RDATA_UPDATE|DNS_RDATA_OFFLINE)) == 0)
+
/*
* Flags affecting rdata formatting style. Flags 0xFFFF0000
* are used by masterfile-level formatting and defined elsewhere.
@@ -201,6 +220,25 @@ dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2);
*\li > 0 'rdata1' is greater than 'rdata2'
*/
+int
+dns_rdata_casecompare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2);
+/*%<
+ * dns_rdata_casecompare() is similar to dns_rdata_compare() but also
+ * compares domain names case insensitively in known rdata types that
+ * are treated as opaque data by dns_rdata_compare().
+ *
+ * Requires:
+ *
+ *\li 'rdata1' is a valid, non-empty rdata
+ *
+ *\li 'rdata2' is a valid, non-empty rdata
+ *
+ * Returns:
+ *\li < 0 'rdata1' is less than 'rdata2'
+ *\li 0 'rdata1' is equal to 'rdata2'
+ *\li > 0 'rdata1' is greater than 'rdata2'
+ */
+
/***
*** Conversions
***/
@@ -698,6 +736,21 @@ dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad);
* 'bad' to be NULL or valid.
*/
+void
+dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type);
+
+void
+dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type);
+
+void
+dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type);
+
+void
+dns_rdata_makedelete(dns_rdata_t *rdata);
+
+const char *
+dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section);
+
ISC_LANG_ENDDECLS
#endif /* DNS_RDATA_H */
diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h
index a8c3e9c7cd9b..7f50c12db212 100644
--- a/lib/dns/include/dns/rdataset.h
+++ b/lib/dns/include/dns/rdataset.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataset.h,v 1.65.50.4.6.3 2011-06-21 20:13:23 each Exp $ */
+/* $Id: rdataset.h,v 1.69.270.3 2011-06-21 20:15:54 each Exp $ */
#ifndef DNS_RDATASET_H
#define DNS_RDATASET_H 1
diff --git a/lib/dns/include/dns/request.h b/lib/dns/include/dns/request.h
index 8808c0a57825..f2db1031be4c 100644
--- a/lib/dns/include/dns/request.h
+++ b/lib/dns/include/dns/request.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: request.h,v 1.27.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: request.h,v 1.31 2010-03-04 23:50:34 tbox Exp $ */
#ifndef DNS_REQUEST_H
#define DNS_REQUEST_H 1
@@ -47,6 +47,7 @@
#include <dns/types.h>
#define DNS_REQUESTOPT_TCP 0x00000001U
+#define DNS_REQUESTOPT_CASE 0x00000002U
typedef struct dns_requestevent {
ISC_EVENT_COMMON(struct dns_requestevent);
@@ -175,6 +176,9 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
* #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request
* will timeout after 'timeout' seconds.
*
+ *\li If the #DNS_REQUESTOPT_CASE option is set, use case sensitive
+ * compression.
+ *
*\li When the request completes, successfully, due to a timeout, or
* because it was canceled, a completion event will be sent to 'task'.
*
@@ -227,6 +231,9 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
* will timeout after 'timeout' seconds. UDP requests will be resent
* at 'udptimeout' intervals if non-zero or 'udpretries' is non-zero.
*
+ *\li If the #DNS_REQUESTOPT_CASE option is set, use case sensitive
+ * compression.
+ *
*\li When the request completes, successfully, due to a timeout, or
* because it was canceled, a completion event will be sent to 'task'.
*
diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h
index c9034bfaf83e..2db1770a6ded 100644
--- a/lib/dns/include/dns/resolver.h
+++ b/lib/dns/include/dns/resolver.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.h,v 1.60.56.5 2010-02-25 10:56:41 tbox Exp $ */
+/* $Id: resolver.h,v 1.67.86.1.2.1 2011-06-02 23:47:36 tbox Exp $ */
#ifndef DNS_RESOLVER_H
#define DNS_RESOLVER_H 1
@@ -81,6 +81,7 @@ typedef struct dns_fetchevent {
dns_fixedname_t foundname;
isc_sockaddr_t * client;
dns_messageid_t id;
+ isc_result_t vresult;
} dns_fetchevent_t;
/*
@@ -179,7 +180,7 @@ dns_resolver_freeze(dns_resolver_t *res);
*
* Requires:
*
- *\li 'res' is a valid, unfrozen resolver.
+ *\li 'res' is a valid resolver.
*
* Ensures:
*
@@ -491,6 +492,27 @@ dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name,
isc_boolean_t
dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name);
+
+void
+dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int seconds);
+/*%<
+ * Set the length of time the resolver will work on a query, in seconds.
+ *
+ * If timeout is 0, the default timeout will be applied.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ */
+
+unsigned int
+dns_resolver_gettimeout(dns_resolver_t *resolver);
+/*%<
+ * Get the current length of time the resolver will work on a query, in seconds.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ */
+
void
dns_resolver_setclientsperquery(dns_resolver_t *resolver,
isc_uint32_t min, isc_uint32_t max);
diff --git a/lib/dns/include/dns/result.h b/lib/dns/include/dns/result.h
index 74b84d665bd3..adc1215a61f9 100644
--- a/lib/dns/include/dns/result.h
+++ b/lib/dns/include/dns/result.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.h,v 1.116.48.2 2010-02-25 10:56:41 tbox Exp $ */
+/* $Id: result.h,v 1.122 2011-01-11 23:47:13 tbox Exp $ */
#ifndef DNS_RESULT_H
#define DNS_RESULT_H 1
@@ -148,10 +148,11 @@
#define DNS_R_MXISADDRESS (ISC_RESULTCLASS_DNS + 102)
#define DNS_R_DUPLICATE (ISC_RESULTCLASS_DNS + 103)
#define DNS_R_INVALIDNSEC3 (ISC_RESULTCLASS_DNS + 104)
-#define DNS_R_NOTMASTER (ISC_RESULTCLASS_DNS + 105)
+#define DNS_R_NOTMASTER (ISC_RESULTCLASS_DNS + 105)
#define DNS_R_BROKENCHAIN (ISC_RESULTCLASS_DNS + 106)
+#define DNS_R_EXPIRED (ISC_RESULTCLASS_DNS + 107)
-#define DNS_R_NRESULTS 107 /*%< Number of results */
+#define DNS_R_NRESULTS 108 /*%< Number of results */
/*
* DNS wire format rcodes.
diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h
new file mode 100644
index 000000000000..404f5176ec98
--- /dev/null
+++ b/lib/dns/include/dns/rpz.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: rpz.h,v 1.3 2011-01-13 04:59:26 tbox Exp $ */
+
+#ifndef DNS_RPZ_H
+#define DNS_RPZ_H 1
+
+#include <isc/lang.h>
+
+#include <dns/fixedname.h>
+#include <dns/rdata.h>
+#include <dns/types.h>
+
+ISC_LANG_BEGINDECLS
+
+#define DNS_RPZ_IP_ZONE "rpz-ip"
+#define DNS_RPZ_NSIP_ZONE "rpz-nsip"
+#define DNS_RPZ_NSDNAME_ZONE "rpz-nsdname"
+
+typedef isc_uint8_t dns_rpz_cidr_bits_t;
+
+typedef enum {
+ DNS_RPZ_TYPE_BAD,
+ DNS_RPZ_TYPE_QNAME,
+ DNS_RPZ_TYPE_IP,
+ DNS_RPZ_TYPE_NSIP,
+ DNS_RPZ_TYPE_NSDNAME
+} dns_rpz_type_t;
+
+/*
+ * Require DNS_RPZ_POLICY_NO_OP < DNS_RPZ_POLICY_NXDOMAIN <
+ * DNS_RPZ_POLICY_NODATA < DNS_RPZ_POLICY_CNAME.
+ */
+typedef enum {
+ DNS_RPZ_POLICY_GIVEN = 0, /* 'given': what something else says */
+ DNS_RPZ_POLICY_NO_OP = 1, /* 'no-op': do not rewrite */
+ DNS_RPZ_POLICY_NXDOMAIN = 2, /* 'nxdomain': answer with NXDOMAIN */
+ DNS_RPZ_POLICY_NODATA = 3, /* 'nodata': answer with ANCOUNT=0 */
+ DNS_RPZ_POLICY_CNAME = 4, /* 'cname x': answer with x's rrsets */
+ DNS_RPZ_POLICY_RECORD = 5,
+ DNS_RPZ_POLICY_MISS,
+ DNS_RPZ_POLICY_ERROR
+} dns_rpz_policy_t;
+
+/*
+ * Specify a response policy zone.
+ */
+typedef struct dns_rpz_zone dns_rpz_zone_t;
+
+struct dns_rpz_zone {
+ ISC_LINK(dns_rpz_zone_t) link;
+ int num;
+ dns_name_t origin; /* Policy zone name */
+ dns_name_t nsdname; /* RPZ_NSDNAME_ZONE.origin */
+ dns_rpz_policy_t policy; /* RPZ_POLICY_GIVEN or override */
+ dns_name_t cname; /* override name for
+ RPZ_POLICY_CNAME */
+};
+
+/*
+ * Radix trees for response policy IP addresses.
+ */
+typedef struct dns_rpz_cidr dns_rpz_cidr_t;
+
+/*
+ * context for finding the best policy
+ */
+typedef struct {
+ unsigned int state;
+# define DNS_RPZ_REWRITTEN 0x0001
+# define DNS_RPZ_DONE_QNAME 0x0002
+# define DNS_RPZ_DONE_A 0x0004
+# define DNS_RPZ_RECURSING 0x0008
+# define DNS_RPZ_HAVE_IP 0x0010
+# define DNS_RPZ_HAVE_NSIPv4 0x0020
+# define DNS_RPZ_HAVE_NSIPv6 0x0040
+# define DNS_RPZ_HAD_NSDNAME 0x0080
+ /*
+ * Best match so far.
+ */
+ struct {
+ dns_rpz_type_t type;
+ dns_rpz_zone_t *rpz;
+ dns_rpz_cidr_bits_t prefix;
+ dns_rpz_policy_t policy;
+ dns_ttl_t ttl;
+ isc_result_t result;
+ dns_zone_t *zone;
+ dns_db_t *db;
+ dns_dbnode_t *node;
+ dns_rdataset_t *rdataset;
+ } m;
+ /*
+ * State for chasing NS names and addresses including recursion.
+ */
+ struct {
+ unsigned int label;
+ dns_db_t *db;
+ dns_rdataset_t *ns_rdataset;
+ dns_rdatatype_t r_type;
+ isc_result_t r_result;
+ dns_rdataset_t *r_rdataset;
+ } ns;
+ /*
+ * State of real query while recursing for NSIP or NSDNAME.
+ */
+ struct {
+ isc_result_t result;
+ isc_boolean_t is_zone;
+ isc_boolean_t authoritative;
+ dns_zone_t *zone;
+ dns_db_t *db;
+ dns_dbnode_t *node;
+ dns_rdataset_t *rdataset;
+ dns_rdataset_t *sigrdataset;
+ dns_rdatatype_t qtype;
+ } q;
+ dns_name_t *qname;
+ dns_name_t *r_name;
+ dns_name_t *fname;
+ dns_fixedname_t _qnamef;
+ dns_fixedname_t _r_namef;
+ dns_fixedname_t _fnamef;
+} dns_rpz_st_t;
+
+#define DNS_RPZ_TTL_DEFAULT 5
+
+/*
+ * So various response policy zone messages can be turned up or down.
+ */
+#define DNS_RPZ_ERROR_LEVEL ISC_LOG_WARNING
+#define DNS_RPZ_INFO_LEVEL ISC_LOG_INFO
+#define DNS_RPZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1)
+#define DNS_RPZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2)
+
+const char *
+dns_rpz_type2str(dns_rpz_type_t type);
+
+dns_rpz_policy_t
+dns_rpz_str2policy(const char *str);
+
+void
+dns_rpz_set_need(isc_boolean_t need);
+
+isc_boolean_t
+dns_rpz_needed(void);
+
+void
+dns_rpz_cidr_free(dns_rpz_cidr_t **cidr);
+
+void
+dns_rpz_view_destroy(dns_view_t *view);
+
+isc_result_t
+dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin,
+ dns_rpz_cidr_t **rbtdb_cidr);
+void
+dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st);
+
+void
+dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name);
+
+void
+dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name);
+
+isc_result_t
+dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr,
+ dns_rpz_type_t type, dns_name_t *canon_name,
+ dns_name_t *search_name, dns_rpz_cidr_bits_t *prefix);
+
+dns_rpz_policy_t
+dns_rpz_decode_cname(dns_rdataset_t *, dns_name_t *selfname);
+
+#endif /* DNS_RPZ_H */
+
diff --git a/lib/dns/include/dns/rriterator.h b/lib/dns/include/dns/rriterator.h
new file mode 100644
index 000000000000..00873492c722
--- /dev/null
+++ b/lib/dns/include/dns/rriterator.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: rriterator.h,v 1.2 2009-06-30 02:52:32 each Exp $ */
+
+#ifndef DNS_RRITERATOR_H
+#define DNS_RRITERATOR_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file dns/rriterator.h
+ * \brief
+ * Functions for "walking" a zone database, visiting each RR or RRset in turn.
+ */
+
+/*****
+ ***** Imports
+ *****/
+
+#include <isc/lang.h>
+#include <isc/magic.h>
+#include <isc/ondestroy.h>
+#include <isc/stdtime.h>
+
+#include <dns/db.h>
+#include <dns/dbiterator.h>
+#include <dns/fixedname.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatasetiter.h>
+#include <dns/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*****
+ ***** Types
+ *****/
+
+/*%
+ * A dns_rriterator_t is an iterator that iterates over an entire database,
+ * returning one RR at a time, in some arbitrary order.
+ */
+
+typedef struct dns_rriterator {
+ unsigned int magic;
+ isc_result_t result;
+ dns_db_t *db;
+ dns_dbiterator_t *dbit;
+ dns_dbversion_t *ver;
+ isc_stdtime_t now;
+ dns_dbnode_t *node;
+ dns_fixedname_t fixedname;
+ dns_rdatasetiter_t *rdatasetit;
+ dns_rdataset_t rdataset;
+ dns_rdata_t rdata;
+} dns_rriterator_t;
+
+#define RRITERATOR_MAGIC ISC_MAGIC('R', 'R', 'I', 't')
+#define VALID_RRITERATOR(m) ISC_MAGIC_VALID(m, RRITERATOR_MAGIC)
+
+isc_result_t
+dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db,
+ dns_dbversion_t *ver, isc_stdtime_t now);
+
+isc_result_t
+dns_rriterator_first(dns_rriterator_t *it);
+
+isc_result_t
+dns_rriterator_nextrrset(dns_rriterator_t *it);
+
+isc_result_t
+dns_rriterator_next(dns_rriterator_t *it);
+
+void
+dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name,
+ isc_uint32_t *ttl, dns_rdataset_t **rdataset,
+ dns_rdata_t **rdata);
+
+void
+dns_rriterator_pause(dns_rriterator_t *it);
+
+void
+dns_rriterator_destroy(dns_rriterator_t *it);
+
+ISC_LANG_ENDDECLS
+
+#endif /* DNS_RRITERATOR_H */
diff --git a/lib/dns/include/dns/sdb.h b/lib/dns/include/dns/sdb.h
index 18995ed92e30..5744837cdec4 100644
--- a/lib/dns/include/dns/sdb.h
+++ b/lib/dns/include/dns/sdb.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdb.h,v 1.21.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: sdb.h,v 1.23 2009-01-17 23:47:43 tbox Exp $ */
#ifndef DNS_SDB_H
#define DNS_SDB_H 1
diff --git a/lib/dns/include/dns/sdlz.h b/lib/dns/include/dns/sdlz.h
index 9d2a0ed6b916..b917cc078b62 100644
--- a/lib/dns/include/dns/sdlz.h
+++ b/lib/dns/include/dns/sdlz.h
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2005-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdlz.h,v 1.7.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: sdlz.h,v 1.14 2011-01-13 08:50:29 tbox Exp $ */
/*! \file dns/sdlz.h */
@@ -74,11 +74,10 @@ typedef struct dns_sdlzlookup dns_sdlzlookup_t;
/* A simple DLZ database traversal in progress. */
typedef struct dns_sdlzallnodes dns_sdlzallnodes_t;
-
-typedef isc_result_t
-(*dns_sdlzallnodesfunc_t)(const char *zone, void *driverarg, void *dbdata,
- dns_sdlzallnodes_t *allnodes);
-
+typedef isc_result_t (*dns_sdlzallnodesfunc_t)(const char *zone,
+ void *driverarg,
+ void *dbdata,
+ dns_sdlzallnodes_t *allnodes);
/*%<
* Method prototype. Drivers implementing the SDLZ interface may
* supply an all nodes method. This method is called when the DNS
@@ -92,9 +91,9 @@ typedef isc_result_t
* does not have to implement an all nodes method.
*/
-typedef isc_result_t
-(*dns_sdlzallowzonexfr_t)(void *driverarg, void *dbdata, const char *name,
- const char *client);
+typedef isc_result_t (*dns_sdlzallowzonexfr_t)(void *driverarg,
+ void *dbdata, const char *name,
+ const char *client);
/*%<
* Method prototype. Drivers implementing the SDLZ interface may
@@ -117,9 +116,9 @@ typedef isc_result_t
* error.
*/
-typedef isc_result_t
-(*dns_sdlzauthorityfunc_t)(const char *zone, void *driverarg, void *dbdata,
- dns_sdlzlookup_t *lookup);
+typedef isc_result_t (*dns_sdlzauthorityfunc_t)(const char *zone,
+ void *driverarg, void *dbdata,
+ dns_sdlzlookup_t *lookup);
/*%<
* Method prototype. Drivers implementing the SDLZ interface may
@@ -131,9 +130,9 @@ typedef isc_result_t
* method.
*/
-typedef isc_result_t
-(*dns_sdlzcreate_t)(const char *dlzname, unsigned int argc, char *argv[],
- void *driverarg, void **dbdata);
+typedef isc_result_t (*dns_sdlzcreate_t)(const char *dlzname,
+ unsigned int argc, char *argv[],
+ void *driverarg, void **dbdata);
/*%<
* Method prototype. Drivers implementing the SDLZ interface may
@@ -142,8 +141,7 @@ typedef isc_result_t
* does not have to implement a create method.
*/
-typedef void
-(*dns_sdlzdestroy_t)(void *driverarg, void *dbdata);
+typedef void (*dns_sdlzdestroy_t)(void *driverarg, void *dbdata);
/*%<
* Method prototype. Drivers implementing the SDLZ interface may
@@ -198,6 +196,87 @@ typedef isc_result_t
* lookup method.
*/
+typedef isc_result_t (*dns_sdlznewversion_t)(const char *zone,
+ void *driverarg, void *dbdata,
+ void **versionp);
+/*%<
+ * Method prototype. Drivers implementing the SDLZ interface may
+ * supply a newversion method. This method is called to start a
+ * write transaction on a zone and should only be implemented by
+ * writeable backends.
+ * When implemented, the driver should create a new transaction, and
+ * fill *versionp with a pointer to the transaction state. The
+ * closeversion function will be called to close the transaction.
+ */
+
+typedef void (*dns_sdlzcloseversion_t)(const char *zone, isc_boolean_t commit,
+ void *driverarg, void *dbdata,
+ void **versionp);
+/*%<
+ * Method prototype. Drivers implementing the SDLZ interface must
+ * supply a closeversion method if they supply a newversion method.
+ * When implemented, the driver should close the given transaction,
+ * committing changes if 'commit' is ISC_TRUE. If 'commit' is not true
+ * then all changes should be discarded and the database rolled back.
+ * If the call is successful then *versionp should be set to NULL
+ */
+
+typedef isc_result_t (*dns_sdlzconfigure_t)(dns_view_t *view, void *driverarg,
+ void *dbdata);
+/*%<
+ * Method prototype. Drivers implementing the SDLZ interface may
+ * supply a configure method. When supplied, it will be called
+ * immediately after the create method to give the driver a chance
+ * to configure writeable zones
+ */
+
+
+typedef isc_boolean_t (*dns_sdlzssumatch_t)(const char *signer,
+ const char *name,
+ const char *tcpaddr,
+ const char *type,
+ const char *key,
+ isc_uint32_t keydatalen,
+ unsigned char *keydata,
+ void *driverarg,
+ void *dbdata);
+
+/*%<
+ * Method prototype. Drivers implementing the SDLZ interface may
+ * supply a ssumatch method. If supplied, then ssumatch will be
+ * called to authorize any zone updates. The driver should return
+ * ISC_TRUE to allow the update, and ISC_FALSE to deny it. For a DLZ
+ * controlled zone, this is the only access control on updates.
+ */
+
+
+typedef isc_result_t (*dns_sdlzmodrdataset_t)(const char *name,
+ const char *rdatastr,
+ void *driverarg, void *dbdata,
+ void *version);
+/*%<
+ * Method prototype. Drivers implementing the SDLZ interface may
+ * supply addrdataset and subtractrdataset methods. If supplied, then these
+ * will be called when rdatasets are added/subtracted during
+ * updates. The version parameter comes from a call to the sdlz
+ * newversion() method from the driver. The rdataset parameter is a
+ * linearise string representation of the rdataset change. The format
+ * is the same as used by dig when displaying records. The fields are
+ * tab delimited.
+ */
+
+typedef isc_result_t (*dns_sdlzdelrdataset_t)(const char *name,
+ const char *type,
+ void *driverarg, void *dbdata,
+ void *version);
+/*%<
+ * Method prototype. Drivers implementing the SDLZ interface may
+ * supply a delrdataset method. If supplied, then this
+ * function will be called when rdatasets are deleted during
+ * updates. The call should remove all rdatasets of the given type for
+ * the specified name.
+ */
+
typedef struct dns_sdlzmethods {
dns_sdlzcreate_t create;
dns_sdlzdestroy_t destroy;
@@ -206,6 +285,13 @@ typedef struct dns_sdlzmethods {
dns_sdlzauthorityfunc_t authority;
dns_sdlzallnodesfunc_t allnodes;
dns_sdlzallowzonexfr_t allowzonexfr;
+ dns_sdlznewversion_t newversion;
+ dns_sdlzcloseversion_t closeversion;
+ dns_sdlzconfigure_t configure;
+ dns_sdlzssumatch_t ssumatch;
+ dns_sdlzmodrdataset_t addrdataset;
+ dns_sdlzmodrdataset_t subtractrdataset;
+ dns_sdlzdelrdataset_t delrdataset;
} dns_sdlzmethods_t;
isc_result_t
@@ -261,6 +347,14 @@ dns_sdlz_putsoa(dns_sdlzlookup_t *lookup, const char *mname, const char *rname,
*/
+isc_result_t
+dns_sdlz_setdb(dns_dlzdb_t *dlzdatabase, dns_rdataclass_t rdclass,
+ dns_name_t *name, dns_db_t **dbp);
+/*%<
+ * Create the database pointers for a writeable SDLZ zone
+ */
+
+
ISC_LANG_ENDDECLS
#endif /* SDLZ_H */
diff --git a/lib/dns/include/dns/secalg.h b/lib/dns/include/dns/secalg.h
index 0eb033359112..49613d51737c 100644
--- a/lib/dns/include/dns/secalg.h
+++ b/lib/dns/include/dns/secalg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: secalg.h,v 1.19 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: secalg.h,v 1.21 2009-10-12 23:48:02 tbox Exp $ */
#ifndef DNS_SECALG_H
#define DNS_SECALG_H 1
@@ -66,6 +66,13 @@ dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target);
*\li ISC_R_NOSPACE target buffer is too small
*/
+#define DNS_SECALG_FORMATSIZE 20
+void
+dns_secalg_format(dns_secalg_t alg, char *cp, unsigned int size);
+/*%<
+ * Wrapper for dns_secalg_totext(), writing text into 'cp'
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_SECALG_H */
diff --git a/lib/dns/include/dns/soa.h b/lib/dns/include/dns/soa.h
index c1ad70612bdb..6ebf61d6ef83 100644
--- a/lib/dns/include/dns/soa.h
+++ b/lib/dns/include/dns/soa.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: soa.h,v 1.9 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: soa.h,v 1.12 2009-09-10 01:47:09 each Exp $ */
#ifndef DNS_SOA_H
#define DNS_SOA_H 1
@@ -40,6 +40,28 @@
ISC_LANG_BEGINDECLS
+#define DNS_SOA_BUFFERSIZE ((2 * DNS_NAME_MAXWIRE) + (4 * 5))
+
+isc_result_t
+dns_soa_buildrdata(dns_name_t *origin, dns_name_t *contact,
+ dns_rdataclass_t rdclass,
+ isc_uint32_t serial, isc_uint32_t refresh,
+ isc_uint32_t retry, isc_uint32_t expire,
+ isc_uint32_t minimum, unsigned char *buffer,
+ dns_rdata_t *rdata);
+/*%<
+ * Build the rdata of an SOA record.
+ *
+ * Requires:
+ *\li buffer Points to a temporary buffer of at least
+ * DNS_SOA_BUFFERSIZE bytes.
+ *\li rdata Points to an initialized dns_rdata_t.
+ *
+ * Ensures:
+ * \li *rdata Contains a valid SOA rdata. The 'data' member
+ * refers to 'buffer'.
+ */
+
isc_uint32_t
dns_soa_getserial(dns_rdata_t *rdata);
isc_uint32_t
diff --git a/lib/dns/include/dns/ssu.h b/lib/dns/include/dns/ssu.h
index 686928bd84ed..5d6c17818166 100644
--- a/lib/dns/include/dns/ssu.h
+++ b/lib/dns/include/dns/ssu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ssu.h,v 1.24 2008-01-18 23:46:58 tbox Exp $ */
+/* $Id: ssu.h,v 1.28 2011-01-06 23:47:00 tbox Exp $ */
#ifndef DNS_SSU_H
#define DNS_SSU_H 1
@@ -25,6 +25,7 @@
#include <isc/lang.h>
#include <dns/types.h>
+#include <dst/dst.h>
ISC_LANG_BEGINDECLS
@@ -40,7 +41,9 @@ ISC_LANG_BEGINDECLS
#define DNS_SSUMATCHTYPE_SUBDOMAINKRB5 9
#define DNS_SSUMATCHTYPE_TCPSELF 10
#define DNS_SSUMATCHTYPE_6TO4SELF 11
-#define DNS_SSUMATCHTYPE_MAX 11 /* max value */
+#define DNS_SSUMATCHTYPE_EXTERNAL 12
+#define DNS_SSUMATCHTYPE_DLZ 13
+#define DNS_SSUMATCHTYPE_MAX 12 /* max value */
isc_result_t
dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table);
@@ -57,6 +60,16 @@ dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table);
*\li ISC_R_NOMEMORY
*/
+isc_result_t
+dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep,
+ dns_dlzdb_t *dlzdatabase);
+/*%<
+ * Create an SSU table that contains a dlzdatabase pointer, and a
+ * single rule with matchtype DNS_SSUMATCHTYPE_DLZ. This type of SSU
+ * table is used by writeable DLZ drivers to offload authorization for
+ * updates to the driver.
+ */
+
void
dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp);
/*%<
@@ -120,7 +133,7 @@ dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant,
isc_boolean_t
dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
dns_name_t *name, isc_netaddr_t *tcpaddr,
- dns_rdatatype_t type);
+ dns_rdatatype_t type, const dst_key_t *key);
/*%<
* Checks that the attempted update of (name, type) is allowed according
* to the rules specified in the simple-secure-update rule table. If
@@ -184,6 +197,16 @@ isc_result_t dns_ssutable_nextrule(dns_ssurule_t *rule,
*\li #ISC_R_NOMORE
*/
+
+/*%<
+ * Check a policy rule via an external application
+ */
+isc_boolean_t
+dns_ssu_external_match(dns_name_t *identity, dns_name_t *signer,
+ dns_name_t *name, isc_netaddr_t *tcpaddr,
+ dns_rdatatype_t type, const dst_key_t *key,
+ isc_mem_t *mctx);
+
ISC_LANG_ENDDECLS
#endif /* DNS_SSU_H */
diff --git a/lib/dns/include/dns/stats.h b/lib/dns/include/dns/stats.h
index 853c1e9630c4..c19b0c767af9 100644
--- a/lib/dns/include/dns/stats.h
+++ b/lib/dns/include/dns/stats.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: stats.h,v 1.18.56.2 2009-01-29 23:47:44 tbox Exp $ */
+/* $Id: stats.h,v 1.20 2009-01-27 23:47:54 tbox Exp $ */
#ifndef DNS_STATS_H
#define DNS_STATS_H 1
diff --git a/lib/dns/include/dns/tkey.h b/lib/dns/include/dns/tkey.h
index cb1fe0edd605..f9e34f8fd747 100644
--- a/lib/dns/include/dns/tkey.h
+++ b/lib/dns/include/dns/tkey.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tkey.h,v 1.26.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: tkey.h,v 1.32 2011-01-08 23:47:01 tbox Exp $ */
#ifndef DNS_TKEY_H
#define DNS_TKEY_H 1
@@ -44,6 +44,7 @@ struct dns_tkeyctx {
gss_cred_id_t gsscred;
isc_mem_t *mctx;
isc_entropy_t *ectx;
+ char *gssapi_keytab;
};
isc_result_t
@@ -123,7 +124,8 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
isc_result_t
dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname,
isc_buffer_t *intoken, isc_uint32_t lifetime,
- gss_ctx_id_t *context, isc_boolean_t win2k);
+ gss_ctx_id_t *context, isc_boolean_t win2k,
+ isc_mem_t *mctx, char **err_message);
/*%<
* Builds a query containing a TKEY that will generate a GSSAPI context.
* The key is requested to have the specified lifetime (in seconds).
@@ -141,6 +143,7 @@ dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname,
*\li ISC_R_SUCCESS msg was successfully updated to include the
* query to be sent
*\li other an error occurred while building the message
+ *\li *err_message optional error message
*/
@@ -187,7 +190,7 @@ isc_result_t
dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
dns_name_t *gname, gss_ctx_id_t *context,
isc_buffer_t *outtoken, dns_tsigkey_t **outkey,
- dns_tsig_keyring_t *ring);
+ dns_tsig_keyring_t *ring, char **err_message);
/*%<
* XXX
*/
@@ -211,12 +214,11 @@ dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
* component of the query or response
*/
-
isc_result_t
dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
dns_name_t *server, gss_ctx_id_t *context,
dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
- isc_boolean_t win2k);
+ isc_boolean_t win2k, char **err_message);
/*
* Client side negotiation of GSS-TSIG. Process the response
diff --git a/lib/dns/include/dns/tsec.h b/lib/dns/include/dns/tsec.h
new file mode 100644
index 000000000000..698634efa933
--- /dev/null
+++ b/lib/dns/include/dns/tsec.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: tsec.h,v 1.6 2010-12-09 00:54:34 marka Exp $ */
+
+#ifndef DNS_TSEC_H
+#define DNS_TSEC_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ *
+ * \brief
+ * The TSEC (Transaction Security) module is an abstraction layer for managing
+ * DNS transaction mechanisms such as TSIG or SIG(0). A TSEC structure is a
+ * mechanism-independent object containing key information specific to the
+ * mechanism, and is expected to be used as an argument to other modules
+ * that use transaction security in a mechanism-independent manner.
+ *
+ * MP:
+ *\li A TSEC structure is expected to be thread-specific. No inter-thread
+ * synchronization is ensured in multiple access to a single TSEC
+ * structure.
+ *
+ * Resources:
+ *\li TBS
+ *
+ * Security:
+ *\li This module does not handle any low-level data directly, and so no
+ * security issue specific to this module is anticipated.
+ */
+
+#include <dns/types.h>
+
+#include <dst/dst.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+/*%
+ * Transaction security types.
+ */
+typedef enum {
+ dns_tsectype_none,
+ dns_tsectype_tsig,
+ dns_tsectype_sig0
+} dns_tsectype_t;
+
+isc_result_t
+dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key,
+ dns_tsec_t **tsecp);
+/*%<
+ * Create a TSEC structure and stores a type-dependent key structure in it.
+ * For a TSIG key (type is dns_tsectype_tsig), dns_tsec_create() creates a
+ * TSIG key structure from '*key' and keeps it in the structure. For other
+ * types, this function simply retains '*key' in the structure. In either
+ * case, the ownership of '*key' is transferred to the TSEC module; the caller
+ * must not modify or destroy it after the call to dns_tsec_create().
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'type' is a valid value of dns_tsectype_t (see above).
+ *
+ *\li 'key' is a valid key.
+ *
+ *\li tsecp != NULL && *tsecp == NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS On success.
+ *
+ *\li Anything else Failure.
+ */
+
+void
+dns_tsec_destroy(dns_tsec_t **tsecp);
+/*%<
+ * Destroy the TSEC structure. The stored key is also detached or destroyed.
+ *
+ * Requires
+ *
+ *\li '*tsecp' is a valid TSEC structure.
+ *
+ * Ensures
+ *
+ *\li *tsecp == NULL.
+ *
+ */
+
+dns_tsectype_t
+dns_tsec_gettype(dns_tsec_t *tsec);
+/*%<
+ * Return the TSEC type of '*tsec'.
+ *
+ * Requires
+ *
+ *\li 'tsec' is a valid TSEC structure.
+ *
+ */
+
+void
+dns_tsec_getkey(dns_tsec_t *tsec, void *keyp);
+/*%<
+ * Return the TSEC key of '*tsec' in '*keyp'.
+ *
+ * Requires
+ *
+ *\li keyp != NULL
+ *
+ * Ensures
+ *
+ *\li *tsecp points to a valid key structure depending on the TSEC type.
+ */
+
+#endif /* DNS_TSEC_H */
diff --git a/lib/dns/include/dns/tsig.h b/lib/dns/include/dns/tsig.h
index 5161fb315faa..ef9423b2c6a1 100644
--- a/lib/dns/include/dns/tsig.h
+++ b/lib/dns/include/dns/tsig.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tsig.h,v 1.51.332.4 2010-12-09 01:12:55 marka Exp $ */
+/* $Id: tsig.h,v 1.59 2011-01-11 23:47:13 tbox Exp $ */
#ifndef DNS_TSIG_H
#define DNS_TSIG_H 1
@@ -25,6 +25,7 @@
#include <isc/lang.h>
#include <isc/refcount.h>
#include <isc/rwlock.h>
+#include <isc/stdio.h>
#include <isc/stdtime.h>
#include <dns/types.h>
@@ -69,6 +70,7 @@ struct dns_tsig_keyring {
unsigned int generated;
unsigned int maxgenerated;
ISC_LIST(dns_tsigkey_t) lru;
+ unsigned int references;
};
struct dns_tsigkey {
@@ -253,9 +255,30 @@ dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp);
*\li #ISC_R_NOMEMORY
*/
+isc_result_t
+dns_tsigkeyring_add(dns_tsig_keyring_t *ring, dns_name_t *name,
+ dns_tsigkey_t *tkey);
+/*%<
+ * Place a TSIG key onto a key ring.
+ *
+ * Requires:
+ *\li 'ring', 'name' and 'tkey' are not NULL
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li Any other value indicates failure.
+ */
+
+
+void
+dns_tsigkeyring_attach(dns_tsig_keyring_t *source, dns_tsig_keyring_t **target);
void
-dns_tsigkeyring_destroy(dns_tsig_keyring_t **ringp);
+dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp);
+
+isc_result_t
+dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp);
+
/*%<
* Destroy a TSIG key ring.
*
@@ -263,6 +286,9 @@ dns_tsigkeyring_destroy(dns_tsig_keyring_t **ringp);
*\li 'ringp' is not NULL
*/
+void
+dns_keyring_restore(dns_tsig_keyring_t *ring, FILE *fp);
+
ISC_LANG_ENDDECLS
#endif /* DNS_TSIG_H */
diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h
index 4e4c1950026b..dc02c865024b 100644
--- a/lib/dns/include/dns/types.h
+++ b/lib/dns/include/dns/types.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.130.50.7 2010-05-14 23:47:50 tbox Exp $ */
+/* $Id: types.h,v 1.143 2010-12-08 02:46:16 marka Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
@@ -44,6 +44,10 @@ typedef struct dns_adbentry dns_adbentry_t;
typedef struct dns_adbfind dns_adbfind_t;
typedef ISC_LIST(dns_adbfind_t) dns_adbfindlist_t;
typedef struct dns_byaddr dns_byaddr_t;
+typedef struct dns_client dns_client_t;
+typedef void dns_clientrestrans_t;
+typedef void dns_clientreqtrans_t;
+typedef void dns_clientupdatetrans_t;
typedef struct dns_cache dns_cache_t;
typedef isc_uint16_t dns_cert_t;
typedef struct dns_compress dns_compress_t;
@@ -63,6 +67,10 @@ typedef struct dns_dispatchevent dns_dispatchevent_t;
typedef struct dns_dispatchlist dns_dispatchlist_t;
typedef struct dns_dispatchmgr dns_dispatchmgr_t;
typedef struct dns_dispentry dns_dispentry_t;
+typedef struct dns_dns64 dns_dns64_t;
+typedef ISC_LIST(dns_dns64_t) dns_dns64list_t;
+typedef struct dns_dnsseckey dns_dnsseckey_t;
+typedef ISC_LIST(dns_dnsseckey_t) dns_dnsseckeylist_t;
typedef struct dns_dumpctx dns_dumpctx_t;
typedef struct dns_fetch dns_fetch_t;
typedef struct dns_fixedname dns_fixedname_t;
@@ -72,6 +80,7 @@ typedef struct dns_iptable dns_iptable_t;
typedef isc_uint32_t dns_iterations_t;
typedef isc_uint16_t dns_keyflags_t;
typedef struct dns_keynode dns_keynode_t;
+typedef ISC_LIST(dns_keynode_t) dns_keynodelist_t;
typedef struct dns_keytable dns_keytable_t;
typedef isc_uint16_t dns_keytag_t;
typedef struct dns_loadctx dns_loadctx_t;
@@ -111,6 +120,7 @@ typedef struct dns_stats dns_stats_t;
typedef isc_uint32_t dns_rdatastatstype_t;
typedef struct dns_tkeyctx dns_tkeyctx_t;
typedef isc_uint16_t dns_trust_t;
+typedef struct dns_tsec dns_tsec_t;
typedef struct dns_tsig_keyring dns_tsig_keyring_t;
typedef struct dns_tsigkey dns_tsigkey_t;
typedef isc_uint32_t dns_ttl_t;
@@ -179,6 +189,12 @@ typedef enum {
dns_masterformat_raw = 2
} dns_masterformat_t;
+typedef enum {
+ dns_v4_aaaa_ok = 0,
+ dns_v4_aaaa_filter = 1,
+ dns_v4_aaaa_break_dnssec = 2
+} dns_v4_aaaa_t;
+
/*
* These are generated by gen.c.
*/
diff --git a/lib/dns/include/dns/validator.h b/lib/dns/include/dns/validator.h
index fb5b834b64e1..5fec1353dd2a 100644
--- a/lib/dns/include/dns/validator.h
+++ b/lib/dns/include/dns/validator.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.h,v 1.41.48.5 2010-02-25 10:56:41 tbox Exp $ */
+/* $Id: validator.h,v 1.46 2010-02-25 05:08:01 tbox Exp $ */
#ifndef DNS_VALIDATOR_H
#define DNS_VALIDATOR_H 1
diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h
index ec96d4c3d295..4b24023961f5 100644
--- a/lib/dns/include/dns/view.h
+++ b/lib/dns/include/dns/view.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.h,v 1.111.88.6 2010-09-24 08:30:28 tbox Exp $ */
+/* $Id: view.h,v 1.132 2011-01-13 01:59:28 marka Exp $ */
#ifndef DNS_VIEW_H
#define DNS_VIEW_H 1
@@ -73,6 +73,8 @@
#include <dns/acl.h>
#include <dns/fixedname.h>
+#include <dns/rdatastruct.h>
+#include <dns/rpz.h>
#include <dns/types.h>
ISC_LANG_BEGINDECLS
@@ -92,8 +94,13 @@ struct dns_view {
dns_cache_t * cache;
dns_db_t * cachedb;
dns_db_t * hints;
- dns_keytable_t * secroots;
- dns_keytable_t * trustedkeys;
+
+ /*
+ * security roots.
+ * internal use only; access via * dns_view_getsecroots()
+ */
+ dns_keytable_t * secroots_priv;
+
isc_mutex_t lock;
isc_boolean_t frozen;
isc_task_t * task;
@@ -102,6 +109,7 @@ struct dns_view {
isc_event_t reqevent;
isc_stats_t * resstats;
dns_stats_t * resquerystats;
+ isc_boolean_t cacheshared;
/* Configurable data. */
dns_tsig_keyring_t * statickeys;
@@ -129,6 +137,10 @@ struct dns_view {
dns_acl_t * transferacl;
dns_acl_t * updateacl;
dns_acl_t * upfwdacl;
+ dns_acl_t * denyansweracl;
+ dns_rbt_t * answeracl_exclude;
+ dns_rbt_t * denyanswernames;
+ dns_rbt_t * answernames_exclude;
isc_boolean_t requestixfr;
isc_boolean_t provideixfr;
isc_boolean_t requestnsid;
@@ -145,6 +157,11 @@ struct dns_view {
dns_name_t * dlv;
dns_fixedname_t dlv_fixed;
isc_uint16_t maxudp;
+ dns_v4_aaaa_t v4_aaaa;
+ dns_acl_t * v4_aaaa_acl;
+ dns_dns64list_t dns64;
+ unsigned int dns64cnt;
+ ISC_LIST(dns_rpz_zone_t) rpz_zones;
/*
* Configurable data for server use only,
@@ -162,6 +179,17 @@ struct dns_view {
unsigned int attributes;
/* Under owner's locking control. */
ISC_LINK(struct dns_view) link;
+ dns_viewlist_t * viewlist;
+
+ dns_zone_t * managed_keys;
+
+#ifdef BIND9
+ /* File in which to store configuration for newly added zones */
+ char * new_zone_file;
+
+ void * new_zone_config;
+ void (*cfg_destroy)(void **);
+#endif
};
#define DNS_VIEW_MAGIC ISC_MAGIC('V','i','e','w')
@@ -310,8 +338,12 @@ dns_view_createresolver(dns_view_t *view,
void
dns_view_setcache(dns_view_t *view, dns_cache_t *cache);
+void
+dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared);
/*%<
- * Set the view's cache database.
+ * Set the view's cache database. If 'shared' is true, this means the cache
+ * is created by another view and is shared with that view. dns_view_setcache()
+ * is a backward compatible version equivalent to setcache2(..., ISC_FALSE).
*
* Requires:
*
@@ -346,6 +378,8 @@ dns_view_sethints(dns_view_t *view, dns_db_t *hints);
void
dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring);
+void
+dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring);
/*%<
* Set the view's static TSIG keys
*
@@ -362,6 +396,15 @@ dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring);
*/
void
+dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp);
+/*%<
+ * Return the views dynamic keys.
+ *
+ * \li 'view' is a valid, unfrozen view.
+ * \li 'ringp' != NULL && ringp == NULL.
+ */
+
+void
dns_view_setdstport(dns_view_t *view, in_port_t dstport);
/*%<
* Set the view's destination port. This is the port to
@@ -398,7 +441,7 @@ dns_view_addzone(dns_view_t *view, dns_zone_t *zone);
void
dns_view_freeze(dns_view_t *view);
/*%<
- * Freeze view.
+ * Freeze view. No changes can be made to view configuration while frozen.
*
* Requires:
*
@@ -409,14 +452,44 @@ dns_view_freeze(dns_view_t *view);
*\li 'view' is frozen.
*/
+void
+dns_view_thaw(dns_view_t *view);
+/*%<
+ * Thaw view. This allows zones to be added or removed at runtime. This is
+ * NOT thread-safe; the caller MUST have run isc_task_exclusive() prior to
+ * thawing the view.
+ *
+ * Requires:
+ *
+ *\li 'view' is a valid, frozen view.
+ *
+ * Ensures:
+ *
+ *\li 'view' is no longer frozen.
+ */
isc_result_t
dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints,
dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
+isc_result_t
+dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
+ isc_stdtime_t now, unsigned int options,
+ isc_boolean_t use_hints, isc_boolean_t use_static_stub,
+ dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
/*%<
* Find an rdataset whose owner name is 'name', and whose type is
* 'type'.
+ * In general, this function first searches view's zone and cache DBs for the
+ * best match data against 'name'. If nothing found there, and if 'use_hints'
+ * is ISC_TRUE, the view's hint DB (if configured) is searched.
+ * If the view is configured with a static-stub zone which gives the longest
+ * match for 'name' among the zones, however, the cache DB is not consulted
+ * unless 'use_static_stub' is ISC_FALSE (see below about this argument).
+ *
+ * dns_view_find() is a backward compatible version equivalent to
+ * dns_view_find2() with use_static_stub argument being ISC_FALSE.
*
* Notes:
*
@@ -432,6 +505,23 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
* in the hints database but not the type, the result code will be
* #DNS_R_HINTNXRRSET.
*
+ *\li If 'use_static_stub' is ISC_FALSE and the longest match zone for 'name'
+ * is a static-stub zone, it's ignored and the cache and/or hints will be
+ * searched. In the majority of the cases this argument should be
+ * ISC_FALSE. The only known usage of this argument being ISC_TRUE is
+ * if this search is for a "bailiwick" glue A or AAAA RRset that may
+ * best match a static-stub zone. Consider the following example:
+ * this view is configured with a static-stub zone "example.com",
+ * and an attempt of recursive resolution needs to send a query for the
+ * zone. In this case it's quite likely that the resolver is trying to
+ * find A/AAAA RRs for the apex name "example.com". And, to honor the
+ * static-stub configuration it needs to return the glue RRs in the
+ * static-stub zone even if that exact RRs coming from the authoritative
+ * zone has been cached.
+ * In other general cases, the requested data is better to be
+ * authoritative, either locally configured or retrieved from an external
+ * server, and the data in the static-stub zone should better be ignored.
+ *
*\li 'foundname' must meet the requirements of dns_db_find().
*
*\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which
@@ -728,8 +818,14 @@ dns_view_dumpdbtostream(dns_view_t *view, FILE *fp);
isc_result_t
dns_view_flushcache(dns_view_t *view);
+isc_result_t
+dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly);
/*%<
- * Flush the view's cache (and ADB).
+ * Flush the view's cache (and ADB). If 'fixuponly' is true, it only updates
+ * the internal reference to the cache DB with omitting actual flush operation.
+ * 'fixuponly' is intended to be used for a view that shares a cache with
+ * a different view. dns_view_flushcache() is a backward compatible version
+ * that always sets fixuponly to false.
*
* Requires:
* 'view' is valid.
@@ -878,4 +974,105 @@ dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp);
*\li 'statsp' != NULL && '*statsp' != NULL
*/
+isc_boolean_t
+dns_view_iscacheshared(dns_view_t *view);
+/*%<
+ * Check if the view shares the cache created by another view.
+ *
+ * Requires:
+ * \li 'view' is valid.
+ *
+ * Returns:
+ *\li #ISC_TRUE if the cache is shared.
+ *\li #ISC_FALSE otherwise.
+ */
+
+isc_result_t
+dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx);
+/*%<
+ * Initialize security roots for the view. (Note that secroots is
+ * NULL until this function is called, so any function using
+ * secroots must check its validity first. One way to do this is
+ * use dns_view_getsecroots() and check its return value.)
+ *
+ * Requires:
+ * \li 'view' is valid.
+ * \li 'view->secroots' is NULL.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li Any other result indicates failure
+ */
+
+isc_result_t
+dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp);
+/*%<
+ * Get the security roots for this view. Returns ISC_R_NOTFOUND if
+ * the security roots keytable has not been initialized for the view.
+ *
+ * '*ktp' is attached on success; the caller is responsible for
+ * detaching it with dns_keytable_detach().
+ *
+ * Requires:
+ * \li 'view' is valid.
+ * \li 'ktp' is not NULL and '*ktp' is NULL.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_NOTFOUND
+ */
+
+isc_result_t
+dns_view_issecuredomain(dns_view_t *view, dns_name_t *name,
+ isc_boolean_t *secure_domain);
+/*%<
+ * Is 'name' at or beneath a trusted key? Put answer in
+ * '*secure_domain'.
+ *
+ * Requires:
+ * \li 'view' is valid.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li Any other value indicates failure
+ */
+
+void
+dns_view_untrust(dns_view_t *view, dns_name_t *keyname,
+ dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx);
+/*%<
+ * Remove keys that match 'keyname' and 'dnskey' from the views trust
+ * anchors.
+ *
+ * Requires:
+ * \li 'view' is valid.
+ * \li 'keyname' is valid.
+ * \li 'mctx' is valid.
+ * \li 'dnskey' is valid.
+ */
+
+void
+dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
+ void (*cfg_destroy)(void **));
+/*%<
+ * Set whether or not to allow zones to be created or deleted at runtime.
+ *
+ * If 'allow' is ISC_TRUE, determines the filename into which new zone
+ * configuration will be written. Preserves the configuration context
+ * (a pointer to which is passed in 'cfgctx') for use when parsing new
+ * zone configuration. 'cfg_destroy' points to a callback routine to
+ * destroy the configuration context when the view is destroyed. (This
+ * roundabout method is used in order to avoid libdns having a dependency
+ * on libisccfg and libbind9.)
+ *
+ * If 'allow' is ISC_FALSE, removes any existing references to
+ * configuration context and frees any memory.
+ *
+ * Requires:
+ * \li 'view' is valid.
+ */
+
+void
+dns_view_restorekeyring(dns_view_t *view);
+
#endif /* DNS_VIEW_H */
diff --git a/lib/dns/include/dns/xfrin.h b/lib/dns/include/dns/xfrin.h
index b957e25669a4..58910d257ea6 100644
--- a/lib/dns/include/dns/xfrin.h
+++ b/lib/dns/include/dns/xfrin.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: xfrin.h,v 1.28.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: xfrin.h,v 1.30 2009-01-17 23:47:43 tbox Exp $ */
#ifndef DNS_XFRIN_H
#define DNS_XFRIN_H 1
diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h
index 96cb9981098d..67756d92cb6b 100644
--- a/lib/dns/include/dns/zone.h
+++ b/lib/dns/include/dns/zone.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.h,v 1.160.50.8 2010-12-14 23:46:09 tbox Exp $ */
+/* $Id: zone.h,v 1.182 2010-12-18 01:56:22 each Exp $ */
#ifndef DNS_ZONE_H
#define DNS_ZONE_H 1
@@ -40,7 +40,10 @@ typedef enum {
dns_zone_none,
dns_zone_master,
dns_zone_slave,
- dns_zone_stub
+ dns_zone_stub,
+ dns_zone_staticstub,
+ dns_zone_key,
+ dns_zone_dlz
} dns_zonetype_t;
#define DNS_ZONEOPT_SERVERS 0x00000001U /*%< perform server checks */
@@ -70,6 +73,10 @@ typedef enum {
#define DNS_ZONEOPT_TRYTCPREFRESH 0x01000000U /*%< try tcp refresh on udp failure */
#define DNS_ZONEOPT_NOTIFYTOSOA 0x02000000U /*%< Notify the SOA MNAME */
#define DNS_ZONEOPT_NSEC3TESTZONE 0x04000000U /*%< nsec3-test-zone */
+#define DNS_ZONEOPT_SECURETOINSECURE 0x08000000U /*%< dnssec-secure-to-insecure */
+#define DNS_ZONEOPT_DNSKEYKSKONLY 0x10000000U /*%< dnssec-dnskey-kskonly */
+#define DNS_ZONEOPT_CHECKDUPRR 0x20000000U /*%< check-dup-records */
+#define DNS_ZONEOPT_CHECKDUPRRFAIL 0x40000000U /*%< fatal check-dup-records failures */
#ifndef NOMINUM_PUBLIC
/*
@@ -78,6 +85,14 @@ typedef enum {
#define DNS_ZONEOPT_NOTIFYFORWARD 0x80000000U /* forward notify to master */
#endif /* NOMINUM_PUBLIC */
+/*
+ * Zone key maintenance options
+ */
+#define DNS_ZONEKEY_ALLOW 0x00000001U /*%< fetch keys on command */
+#define DNS_ZONEKEY_MAINTAIN 0x00000002U /*%< publish/sign on schedule */
+#define DNS_ZONEKEY_CREATE 0x00000004U /*%< make keys when needed */
+#define DNS_ZONEKEY_FULLSIGN 0x00000008U /*%< roll to new keys immediately */
+
#ifndef DNS_ZONE_MINREFRESH
#define DNS_ZONE_MINREFRESH 300 /*%< 5 minutes */
#endif
@@ -367,6 +382,22 @@ dns_zone_getdb(dns_zone_t *zone, dns_db_t **dbp);
*\li DNS_R_NOTLOADED
*/
+void
+dns_zone_setdb(dns_zone_t *zone, dns_db_t *db);
+/*%<
+ * Sets the zone database to 'db'.
+ *
+ * This function is expected to be used to configure a zone with a
+ * database which is not loaded from a file or zone transfer.
+ * It can be used for a general purpose zone, but right now its use
+ * is limited to static-stub zones to avoid possible undiscovered
+ * problems in the general cases.
+ *
+ * Require:
+ *\li 'zone' to be a valid zone of static-stub.
+ *\li zone doesn't have a database.
+ */
+
isc_result_t
dns_zone_setdbtype(dns_zone_t *zone,
unsigned int dbargc, const char * const *dbargv);
@@ -568,6 +599,25 @@ dns_zone_getoptions(dns_zone_t *zone);
*/
void
+dns_zone_setkeyopt(dns_zone_t *zone, unsigned int option, isc_boolean_t value);
+/*%<
+ * Set key options on ('value' == ISC_TRUE) or off ('value' ==
+ * #ISC_FALSE).
+ *
+ * Require:
+ *\li 'zone' to be a valid zone.
+ */
+
+unsigned int
+dns_zone_getkeyopts(dns_zone_t *zone);
+/*%<
+ * Returns the current zone key options.
+ *
+ * Require:
+ *\li 'zone' to be a valid zone.
+ */
+
+void
dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val);
/*%<
* Set the minimum refresh time.
@@ -1747,6 +1797,61 @@ dns_zone_getprivatetype(dns_zone_t *zone);
* will not be permanent.
*/
+void
+dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign);
+/*%<
+ * Update the zone's DNSKEY set from the key repository.
+ *
+ * If 'fullsign' is true, trigger an immediate full signing of
+ * the zone with the new key. Otherwise, if there are no keys or
+ * if the new keys are for algorithms that have already signed the
+ * zone, then the zone can be re-signed incrementally.
+ */
+
+isc_result_t
+dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
+ unsigned int *errors);
+/*%
+ * Check if the name servers for the zone are sane (have address, don't
+ * refer to CNAMEs/DNAMEs. The number of constiancy errors detected in
+ * returned in '*errors'
+ *
+ * Requires:
+ * \li 'zone' to be valid.
+ * \li 'db' to be valid.
+ * \li 'version' to be valid or NULL.
+ * \li 'errors' to be non NULL.
+ *
+ * Returns:
+ * ISC_R_SUCCESS if there were no errors examining the zone contents.
+ */
+
+void
+dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added);
+/*%
+ * Sets the value of zone->added, which should be ISC_TRUE for
+ * zones that were originally added by "rndc addzone".
+ *
+ * Requires:
+ * \li 'zone' to be valid.
+ */
+
+isc_boolean_t
+dns_zone_getadded(dns_zone_t *zone);
+/*%
+ * Returns ISC_TRUE if the zone was originally added at runtime
+ * using "rndc addzone".
+ *
+ * Requires:
+ * \li 'zone' to be valid.
+ */
+
+isc_result_t
+dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db);
+/*%
+ * Load the origin names for a writeable DLZ database.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_ZONE_H */
diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h
index 1a30d2b1382f..3c999f6876db 100644
--- a/lib/dns/include/dst/dst.h
+++ b/lib/dns/include/dst/dst.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst.h,v 1.12.50.3 2010-12-09 01:12:55 marka Exp $ */
+/* $Id: dst.h,v 1.31 2011-01-11 23:47:14 tbox Exp $ */
#ifndef DST_DST_H
#define DST_DST_H 1
@@ -23,8 +23,11 @@
/*! \file dst/dst.h */
#include <isc/lang.h>
+#include <isc/stdtime.h>
#include <dns/types.h>
+#include <dns/name.h>
+#include <dns/secalg.h>
#include <dst/gssapi.h>
@@ -55,6 +58,7 @@ typedef struct dst_context dst_context_t;
#define DST_ALG_NSEC3RSASHA1 7
#define DST_ALG_RSASHA256 8
#define DST_ALG_RSASHA512 10
+#define DST_ALG_ECCGOST 12
#define DST_ALG_HMACMD5 157
#define DST_ALG_GSSAPI 160
#define DST_ALG_HMACSHA1 161 /* XXXMPA */
@@ -80,12 +84,55 @@ typedef struct dst_context dst_context_t;
#define DST_TYPE_PRIVATE 0x2000000
#define DST_TYPE_PUBLIC 0x4000000
+/* Key timing metadata definitions */
+#define DST_TIME_CREATED 0
+#define DST_TIME_PUBLISH 1
+#define DST_TIME_ACTIVATE 2
+#define DST_TIME_REVOKE 3
+#define DST_TIME_INACTIVE 4
+#define DST_TIME_DELETE 5
+#define DST_TIME_DSPUBLISH 6
+#define DST_MAX_TIMES 6
+
+/* Numeric metadata definitions */
+#define DST_NUM_PREDECESSOR 0
+#define DST_NUM_SUCCESSOR 1
+#define DST_NUM_MAXTTL 2
+#define DST_NUM_ROLLPERIOD 3
+#define DST_MAX_NUMERIC 3
+
+/*
+ * Current format version number of the private key parser.
+ *
+ * When parsing a key file with the same major number but a higher minor
+ * number, the key parser will ignore any fields it does not recognize.
+ * Thus, DST_MINOR_VERSION should be incremented whenever new
+ * fields are added to the private key file (such as new metadata).
+ *
+ * When rewriting these keys, those fields will be dropped, and the
+ * format version set back to the current one..
+ *
+ * When a key is seen with a higher major number, the key parser will
+ * reject it as invalid. Thus, DST_MAJOR_VERSION should be incremented
+ * and DST_MINOR_VERSION set to zero whenever there is a format change
+ * which is not backward compatible to previous versions of the dst_key
+ * parser, such as change in the syntax of an existing field, the removal
+ * of a currently mandatory field, or a new field added which would
+ * alter the functioning of the key if it were absent.
+ */
+#define DST_MAJOR_VERSION 1
+#define DST_MINOR_VERSION 3
+
/***
*** Functions
***/
isc_result_t
dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags);
+
+isc_result_t
+dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx,
+ const char *engine, unsigned int eflags);
/*%<
* Initializes the DST subsystem.
*
@@ -96,6 +143,7 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags);
* Returns:
* \li ISC_R_SUCCESS
* \li ISC_R_NOMEMORY
+ * \li DST_R_NOENGINE
*
* Ensures:
* \li DST is properly initialized.
@@ -244,13 +292,17 @@ dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type,
*/
isc_result_t
-dst_key_fromnamedfile(const char *filename, int type, isc_mem_t *mctx,
- dst_key_t **keyp);
+dst_key_fromnamedfile(const char *filename, const char *dirname,
+ int type, isc_mem_t *mctx, dst_key_t **keyp);
/*%<
* Reads a key from permanent storage. The key can either be a public or
* key, and is specified by filename. If a private key is specified, the
* public key must also be present.
*
+ * If 'dirname' is not NULL, and 'filename' is a relative path,
+ * then the file is looked up relative to the given directory.
+ * If 'filename' is an absolute path, 'dirname' is ignored.
+ *
* Requires:
* \li "filename" is not NULL
* \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union
@@ -419,7 +471,7 @@ dst_key_getgssctx(const dst_key_t *key);
isc_result_t
dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx,
- dst_key_t **keyp);
+ dst_key_t **keyp, isc_region_t *intoken);
/*%<
* Converts a GSSAPI opaque context id into a DST key.
*
@@ -450,6 +502,14 @@ dst_key_generate(dns_name_t *name, unsigned int alg,
unsigned int flags, unsigned int protocol,
dns_rdataclass_t rdclass,
isc_mem_t *mctx, dst_key_t **keyp);
+
+isc_result_t
+dst_key_generate2(dns_name_t *name, unsigned int alg,
+ unsigned int bits, unsigned int param,
+ unsigned int flags, unsigned int protocol,
+ dns_rdataclass_t rdclass,
+ isc_mem_t *mctx, dst_key_t **keyp,
+ void (*callback)(int));
/*%<
* Generate a DST key (or keypair) with the supplied parameters. The
* interpretation of the "param" field depends on the algorithm:
@@ -482,7 +542,31 @@ dst_key_generate(dns_name_t *name, unsigned int alg,
isc_boolean_t
dst_key_compare(const dst_key_t *key1, const dst_key_t *key2);
/*%<
- * Compares two DST keys.
+ * Compares two DST keys. Returns true if they match, false otherwise.
+ *
+ * Keys ARE NOT considered to match if one of them is the revoked version
+ * of the other.
+ *
+ * Requires:
+ *\li "key1" is a valid key.
+ *\li "key2" is a valid key.
+ *
+ * Returns:
+ *\li ISC_TRUE
+ * \li ISC_FALSE
+ */
+
+isc_boolean_t
+dst_key_pubcompare(const dst_key_t *key1, const dst_key_t *key2,
+ isc_boolean_t match_revoked_key);
+/*%<
+ * Compares only the public portions of two DST keys. Returns true
+ * if they match, false otherwise. This allows us, for example, to
+ * determine whether a public key found in a zone matches up with a
+ * key pair found on disk.
+ *
+ * If match_revoked_key is TRUE, then keys ARE considered to match if one
+ * of them is the revoked version of the other. Otherwise, they are not.
*
* Requires:
*\li "key1" is a valid key.
@@ -521,10 +605,12 @@ dst_key_attach(dst_key_t *source, dst_key_t **target);
void
dst_key_free(dst_key_t **keyp);
/*%<
- * Release all memory associated with the key.
+ * Decrement the key's reference counter and, when it reaches zero,
+ * release all memory associated with the key.
*
* Requires:
*\li "keyp" is not NULL and "*keyp" is a valid key.
+ *\li reference counter greater than zero.
*
* Ensures:
*\li All memory associated with "*keyp" will be freed.
@@ -633,7 +719,7 @@ dst_region_computeid(const isc_region_t *source, unsigned int alg);
isc_uint16_t
dst_key_getbits(const dst_key_t *key);
-/*
+/*%<
* Get the number of digest bits required (0 == MAX).
*
* Requires:
@@ -642,13 +728,150 @@ dst_key_getbits(const dst_key_t *key);
void
dst_key_setbits(dst_key_t *key, isc_uint16_t bits);
-/*
+/*%<
* Set the number of digest bits required (0 == MAX).
*
* Requires:
* "key" is a valid key.
*/
+isc_result_t
+dst_key_setflags(dst_key_t *key, isc_uint32_t flags);
+/*
+ * Set the key flags, and recompute the key ID.
+ *
+ * Requires:
+ * "key" is a valid key.
+ */
+
+isc_result_t
+dst_key_getnum(const dst_key_t *key, int type, isc_uint32_t *valuep);
+/*%<
+ * Get a member of the numeric metadata array and place it in '*valuep'.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "type" is no larger than DST_MAX_NUMERIC
+ * "timep" is not null.
+ */
+
+void
+dst_key_setnum(dst_key_t *key, int type, isc_uint32_t value);
+/*%<
+ * Set a member of the numeric metadata array.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "type" is no larger than DST_MAX_NUMERIC
+ */
+
+void
+dst_key_unsetnum(dst_key_t *key, int type);
+/*%<
+ * Flag a member of the numeric metadata array as "not set".
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "type" is no larger than DST_MAX_NUMERIC
+ */
+
+isc_result_t
+dst_key_gettime(const dst_key_t *key, int type, isc_stdtime_t *timep);
+/*%<
+ * Get a member of the timing metadata array and place it in '*timep'.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "type" is no larger than DST_MAX_TIMES
+ * "timep" is not null.
+ */
+
+void
+dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when);
+/*%<
+ * Set a member of the timing metadata array.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "type" is no larger than DST_MAX_TIMES
+ */
+
+void
+dst_key_unsettime(dst_key_t *key, int type);
+/*%<
+ * Flag a member of the timing metadata array as "not set".
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "type" is no larger than DST_MAX_TIMES
+ */
+
+isc_result_t
+dst_key_getprivateformat(const dst_key_t *key, int *majorp, int *minorp);
+/*%<
+ * Get the private key format version number. (If the key does not have
+ * a private key associated with it, the version will be 0.0.) The major
+ * version number is placed in '*majorp', and the minor version number in
+ * '*minorp'.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "majorp" is not NULL.
+ * "minorp" is not NULL.
+ */
+
+void
+dst_key_setprivateformat(dst_key_t *key, int major, int minor);
+/*%<
+ * Set the private key format version number.
+ *
+ * Requires:
+ * "key" is a valid key.
+ */
+
+#define DST_KEY_FORMATSIZE (DNS_NAME_FORMATSIZE + DNS_SECALG_FORMATSIZE + 7)
+
+void
+dst_key_format(const dst_key_t *key, char *cp, unsigned int size);
+/*%<
+ * Write the uniquely identifying information about the key (name,
+ * algorithm, key ID) into a string 'cp' of size 'size'.
+ */
+
+
+isc_buffer_t *
+dst_key_tkeytoken(const dst_key_t *key);
+/*%<
+ * Return the token from the TKEY request, if any. If this key was
+ * not negotiated via TKEY, return NULL.
+ */
+
+
+isc_result_t
+dst_key_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length);
+/*%<
+ * Allocate 'buffer' and dump the key into it in base64 format. The buffer
+ * is not NUL terminated. The length of the buffer is returned in *length.
+ *
+ * 'buffer' needs to be freed using isc_mem_put(mctx, buffer, length);
+ *
+ * Requires:
+ * 'buffer' to be non NULL and *buffer to be NULL.
+ * 'length' to be non NULL and *length to be zero.
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * ISC_R_NOMEMORY
+ * ISC_R_NOTIMPLEMENTED
+ * others.
+ */
+
+isc_result_t
+dst_key_restore(dns_name_t *name, unsigned int alg, unsigned int flags,
+ unsigned int protocol, dns_rdataclass_t rdclass,
+ isc_mem_t *mctx, const char *keystr, dst_key_t **keyp);
+
+
ISC_LANG_ENDDECLS
#endif /* DST_DST_H */
diff --git a/lib/dns/include/dst/gssapi.h b/lib/dns/include/dst/gssapi.h
index 0a468d37cbdd..189e6b594e80 100644
--- a/lib/dns/include/dst/gssapi.h
+++ b/lib/dns/include/dst/gssapi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: gssapi.h,v 1.9.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: gssapi.h,v 1.16 2011-01-08 23:47:01 tbox Exp $ */
#ifndef DST_GSSAPI_H
#define DST_GSSAPI_H 1
@@ -34,8 +34,12 @@
* MSVC does not like macros in #include lines.
*/
#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_krb5.h>
#else
#include ISC_PLATFORM_GSSAPIHEADER
+#ifdef ISC_PLATFORM_GSSAPI_KRB5_HEADER
+#include ISC_PLATFORM_GSSAPI_KRB5_HEADER
+#endif
#endif
#ifndef GSS_SPNEGO_MECHANISM
#define GSS_SPNEGO_MECHANISM ((void*)0)
@@ -90,7 +94,8 @@ dst_gssapi_releasecred(gss_cred_id_t *cred);
isc_result_t
dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
- isc_buffer_t *outtoken, gss_ctx_id_t *gssctx);
+ isc_buffer_t *outtoken, gss_ctx_id_t *gssctx,
+ isc_mem_t *mctx, char **err_message);
/*
* Initiates a GSS context.
*
@@ -108,10 +113,12 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
* ISC_R_SUCCESS msg was successfully updated to include the
* query to be sent
* other an error occurred while building the message
+ * *err_message optional error message
*/
isc_result_t
dst_gssapi_acceptctx(gss_cred_id_t cred,
+ const char *gssapi_keytab,
isc_region_t *intoken, isc_buffer_t **outtoken,
gss_ctx_id_t *context, dns_name_t *principal,
isc_mem_t *mctx);
diff --git a/lib/dns/iptable.c b/lib/dns/iptable.c
index 071f9a682a4b..7c334ddf8c2c 100644
--- a/lib/dns/iptable.c
+++ b/lib/dns/iptable.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: iptable.c,v 1.12.44.3 2009-02-18 23:47:12 tbox Exp $ */
+/* $Id: iptable.c,v 1.15 2009-02-18 23:47:48 tbox Exp $ */
#include <config.h>
diff --git a/lib/dns/journal.c b/lib/dns/journal.c
index 520083e5c1ae..a6d630edc4c7 100644
--- a/lib/dns/journal.c
+++ b/lib/dns/journal.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: journal.c,v 1.103.48.8 2010-11-17 23:45:45 tbox Exp $ */
+/* $Id: journal.c,v 1.112 2010-11-17 23:47:08 tbox Exp $ */
#include <config.h>
@@ -562,11 +562,9 @@ journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t write,
if (result == ISC_R_FILENOTFOUND) {
if (create) {
- isc_log_write(JOURNAL_COMMON_LOGARGS,
- ISC_LOG_INFO,
+ isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(1),
"journal file %s does not exist, "
- "creating it",
- j->filename);
+ "creating it", j->filename);
CHECK(journal_file_create(mctx, filename));
/*
* Retry.
diff --git a/lib/dns/keydata.c b/lib/dns/keydata.c
new file mode 100644
index 000000000000..c2f82c8b730a
--- /dev/null
+++ b/lib/dns/keydata.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: keydata.c,v 1.3 2009-07-01 23:47:36 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+
+#include <isc/buffer.h>
+#include <isc/mem.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/rdata.h>
+#include <dns/rdatastruct.h>
+#include <dns/keydata.h>
+
+isc_result_t
+dns_keydata_todnskey(dns_rdata_keydata_t *keydata,
+ dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx)
+{
+ REQUIRE(keydata != NULL && dnskey != NULL);
+
+ dnskey->common.rdtype = dns_rdatatype_dnskey;
+ dnskey->common.rdclass = keydata->common.rdclass;
+ dnskey->mctx = mctx;
+ dnskey->flags = keydata->flags;
+ dnskey->protocol = keydata->protocol;
+ dnskey->algorithm = keydata->algorithm;
+
+ dnskey->datalen = keydata->datalen;
+
+ if (mctx == NULL)
+ dnskey->data = keydata->data;
+ else {
+ dnskey->data = isc_mem_allocate(mctx, dnskey->datalen);
+ if (dnskey->data == NULL)
+ return (ISC_R_NOMEMORY);
+ memcpy(dnskey->data, keydata->data, dnskey->datalen);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_keydata_fromdnskey(dns_rdata_keydata_t *keydata,
+ dns_rdata_dnskey_t *dnskey,
+ isc_uint32_t refresh, isc_uint32_t addhd,
+ isc_uint32_t removehd, isc_mem_t *mctx)
+{
+ REQUIRE(keydata != NULL && dnskey != NULL);
+
+ keydata->common.rdtype = dns_rdatatype_keydata;
+ keydata->common.rdclass = dnskey->common.rdclass;
+ keydata->mctx = mctx;
+ keydata->refresh = refresh;
+ keydata->addhd = addhd;
+ keydata->removehd = removehd;
+ keydata->flags = dnskey->flags;
+ keydata->protocol = dnskey->protocol;
+ keydata->algorithm = dnskey->algorithm;
+
+ keydata->datalen = dnskey->datalen;
+ if (mctx == NULL)
+ keydata->data = dnskey->data;
+ else {
+ keydata->data = isc_mem_allocate(mctx, keydata->datalen);
+ if (keydata->data == NULL)
+ return (ISC_R_NOMEMORY);
+ memcpy(keydata->data, dnskey->data, keydata->datalen);
+ }
+
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/dns/keytable.c b/lib/dns/keytable.c
index 874868dfb552..3edc3d61cffe 100644
--- a/lib/dns/keytable.c
+++ b/lib/dns/keytable.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: keytable.c,v 1.34 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: keytable.c,v 1.41 2010-06-25 23:46:51 tbox Exp $ */
/*! \file */
@@ -31,41 +31,12 @@
#include <dns/rbt.h>
#include <dns/result.h>
-struct dns_keytable {
- /* Unlocked. */
- unsigned int magic;
- isc_mem_t *mctx;
- isc_mutex_t lock;
- isc_rwlock_t rwlock;
- /* Locked by lock. */
- isc_uint32_t active_nodes;
- /* Locked by rwlock. */
- isc_uint32_t references;
- dns_rbt_t *table;
-};
-
-#define KEYTABLE_MAGIC ISC_MAGIC('K', 'T', 'b', 'l')
-#define VALID_KEYTABLE(kt) ISC_MAGIC_VALID(kt, KEYTABLE_MAGIC)
-
-struct dns_keynode {
- unsigned int magic;
- dst_key_t * key;
- struct dns_keynode * next;
-};
-
-#define KEYNODE_MAGIC ISC_MAGIC('K', 'N', 'o', 'd')
-#define VALID_KEYNODE(kn) ISC_MAGIC_VALID(kn, KEYNODE_MAGIC)
-
static void
free_keynode(void *node, void *arg) {
dns_keynode_t *keynode = node;
isc_mem_t *mctx = arg;
- REQUIRE(VALID_KEYNODE(keynode));
- dst_key_free(&keynode->key);
- if (keynode->next != NULL)
- free_keynode(keynode->next, mctx);
- isc_mem_put(mctx, keynode, sizeof(dns_keynode_t));
+ dns_keynode_detachall(mctx, &keynode);
}
isc_result_t
@@ -116,7 +87,6 @@ dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) {
return (result);
}
-
void
dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp) {
@@ -173,50 +143,224 @@ dns_keytable_detach(dns_keytable_t **keytablep) {
*keytablep = NULL;
}
-isc_result_t
-dns_keytable_add(dns_keytable_t *keytable, dst_key_t **keyp) {
+static isc_result_t
+insert(dns_keytable_t *keytable, isc_boolean_t managed,
+ dns_name_t *keyname, dst_key_t **keyp)
+{
isc_result_t result;
- dns_keynode_t *knode;
+ dns_keynode_t *knode = NULL;
dns_rbtnode_t *node;
- dns_name_t *keyname;
-
- /*
- * Add '*keyp' to 'keytable'.
- */
+ REQUIRE(keyp == NULL || *keyp != NULL);
REQUIRE(VALID_KEYTABLE(keytable));
- REQUIRE(keyp != NULL);
- keyname = dst_key_name(*keyp);
+ result = dns_keynode_create(keytable->mctx, &knode);
+ if (result != ISC_R_SUCCESS)
+ return (result);
- knode = isc_mem_get(keytable->mctx, sizeof(*knode));
- if (knode == NULL)
- return (ISC_R_NOMEMORY);
+ knode->managed = managed;
RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
node = NULL;
result = dns_rbt_addnode(keytable->table, keyname, &node);
- if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) {
- knode->magic = KEYNODE_MAGIC;
- knode->key = *keyp;
- knode->next = node->data;
+ if (keyp != NULL) {
+ if (result == ISC_R_EXISTS) {
+ /* Key already in table? */
+ dns_keynode_t *k;
+ for (k = node->data; k != NULL; k = k->next) {
+ if (k->key == NULL) {
+ k->key = *keyp;
+ break;
+ }
+ if (dst_key_compare(k->key, *keyp) == ISC_TRUE)
+ break;
+ }
+
+ if (k == NULL)
+ result = ISC_R_SUCCESS;
+ else
+ dst_key_free(keyp);
+ }
+
+ if (result == ISC_R_SUCCESS) {
+ knode->key = *keyp;
+ knode->next = node->data;
+ *keyp = NULL;
+ }
+ }
+
+ if (result == ISC_R_SUCCESS) {
node->data = knode;
- *keyp = NULL;
knode = NULL;
- result = ISC_R_SUCCESS;
}
+ /* Key was already there? That's the same as a success */
+ if (result == ISC_R_EXISTS)
+ result = ISC_R_SUCCESS;
+
RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
if (knode != NULL)
- isc_mem_put(keytable->mctx, knode, sizeof(*knode));
+ dns_keynode_detach(keytable->mctx, &knode);
+
+ return (result);
+}
+
+isc_result_t
+dns_keytable_add(dns_keytable_t *keytable, isc_boolean_t managed,
+ dst_key_t **keyp)
+{
+ REQUIRE(keyp != NULL && *keyp != NULL);
+ return (insert(keytable, managed, dst_key_name(*keyp), keyp));
+}
+
+isc_result_t
+dns_keytable_marksecure(dns_keytable_t *keytable, dns_name_t *name) {
+ return (insert(keytable, ISC_TRUE, name, NULL));
+}
+
+isc_result_t
+dns_keytable_delete(dns_keytable_t *keytable, dns_name_t *keyname) {
+ isc_result_t result;
+ dns_rbtnode_t *node = NULL;
+
+ REQUIRE(VALID_KEYTABLE(keytable));
+ REQUIRE(keyname != NULL);
+
+ RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
+ result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
+ DNS_RBTFIND_NOOPTIONS, NULL, NULL);
+ if (result == ISC_R_SUCCESS) {
+ if (node->data != NULL)
+ result = dns_rbt_deletenode(keytable->table,
+ node, ISC_FALSE);
+ else
+ result = ISC_R_NOTFOUND;
+ } else if (result == DNS_R_PARTIALMATCH)
+ result = ISC_R_NOTFOUND;
+ RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
return (result);
}
isc_result_t
+dns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey) {
+ isc_result_t result;
+ dns_name_t *keyname;
+ dns_rbtnode_t *node = NULL;
+ dns_keynode_t *knode = NULL, **kprev = NULL;
+
+ REQUIRE(VALID_KEYTABLE(keytable));
+ REQUIRE(dstkey != NULL);
+
+ keyname = dst_key_name(dstkey);
+
+ RWLOCK(&keytable->rwlock, isc_rwlocktype_write);
+ result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
+ DNS_RBTFIND_NOOPTIONS, NULL, NULL);
+
+ if (result == DNS_R_PARTIALMATCH)
+ result = ISC_R_NOTFOUND;
+ if (result != ISC_R_SUCCESS)
+ goto finish;
+
+ if (node->data == NULL) {
+ result = ISC_R_NOTFOUND;
+ goto finish;
+ }
+
+ knode = node->data;
+ if (knode->next == NULL &&
+ (knode->key == NULL ||
+ dst_key_compare(knode->key, dstkey) == ISC_TRUE)) {
+ result = dns_rbt_deletenode(keytable->table, node, ISC_FALSE);
+ goto finish;
+ }
+
+ kprev = (dns_keynode_t **) &node->data;
+ while (knode != NULL) {
+ if (dst_key_compare(knode->key, dstkey) == ISC_TRUE)
+ break;
+ kprev = &knode->next;
+ knode = knode->next;
+ }
+
+ if (knode != NULL) {
+ if (knode->key != NULL)
+ dst_key_free(&knode->key);
+ /*
+ * This is equivalent to:
+ * dns_keynode_attach(knode->next, &tmp);
+ * dns_keynode_detach(kprev);
+ * dns_keynode_attach(tmp, &kprev);
+ * dns_keynode_detach(&tmp);
+ */
+ *kprev = knode->next;
+ knode->next = NULL;
+ dns_keynode_detach(keytable->mctx, &knode);
+ } else
+ result = DNS_R_PARTIALMATCH;
+ finish:
+ RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);
+ return (result);
+}
+
+isc_result_t
+dns_keytable_find(dns_keytable_t *keytable, dns_name_t *keyname,
+ dns_keynode_t **keynodep)
+{
+ isc_result_t result;
+ dns_rbtnode_t *node = NULL;
+
+ REQUIRE(VALID_KEYTABLE(keytable));
+ REQUIRE(keyname != NULL);
+ REQUIRE(keynodep != NULL && *keynodep == NULL);
+
+ RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
+ result = dns_rbt_findnode(keytable->table, keyname, NULL, &node, NULL,
+ DNS_RBTFIND_NOOPTIONS, NULL, NULL);
+ if (result == ISC_R_SUCCESS) {
+ if (node->data != NULL) {
+ LOCK(&keytable->lock);
+ keytable->active_nodes++;
+ UNLOCK(&keytable->lock);
+ dns_keynode_attach(node->data, keynodep);
+ } else
+ result = ISC_R_NOTFOUND;
+ } else if (result == DNS_R_PARTIALMATCH)
+ result = ISC_R_NOTFOUND;
+ RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
+
+ return (result);
+}
+
+isc_result_t
+dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
+ dns_keynode_t **nextnodep)
+{
+ /*
+ * Return the next key after 'keynode', regardless of
+ * properties.
+ */
+
+ REQUIRE(VALID_KEYTABLE(keytable));
+ REQUIRE(VALID_KEYNODE(keynode));
+ REQUIRE(nextnodep != NULL && *nextnodep == NULL);
+
+ if (keynode->next == NULL)
+ return (ISC_R_NOTFOUND);
+
+ dns_keynode_attach(keynode->next, nextnodep);
+ LOCK(&keytable->lock);
+ keytable->active_nodes++;
+ UNLOCK(&keytable->lock);
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name,
dns_secalg_t algorithm, dns_keytag_t tag,
dns_keynode_t **keynodep)
@@ -250,6 +394,10 @@ dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name,
if (result == ISC_R_SUCCESS) {
INSIST(data != NULL);
for (knode = data; knode != NULL; knode = knode->next) {
+ if (knode->key == NULL) {
+ knode = NULL;
+ break;
+ }
if (algorithm == dst_key_alg(knode->key)
&& tag == dst_key_id(knode->key))
break;
@@ -258,7 +406,7 @@ dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name,
LOCK(&keytable->lock);
keytable->active_nodes++;
UNLOCK(&keytable->lock);
- *keynodep = knode;
+ dns_keynode_attach(knode, keynodep);
} else
result = DNS_R_PARTIALMATCH;
} else if (result == DNS_R_PARTIALMATCH)
@@ -286,6 +434,10 @@ dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
REQUIRE(nextnodep != NULL && *nextnodep == NULL);
for (knode = keynode->next; knode != NULL; knode = knode->next) {
+ if (knode->key == NULL) {
+ knode = NULL;
+ break;
+ }
if (dst_key_alg(keynode->key) == dst_key_alg(knode->key) &&
dst_key_id(keynode->key) == dst_key_id(knode->key))
break;
@@ -295,7 +447,7 @@ dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode,
keytable->active_nodes++;
UNLOCK(&keytable->lock);
result = ISC_R_SUCCESS;
- *nextnodep = knode;
+ dns_keynode_attach(knode, nextnodep);
} else
result = ISC_R_NOTFOUND;
@@ -331,6 +483,25 @@ dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name,
}
void
+dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source,
+ dns_keynode_t **target)
+{
+ /*
+ * Give back a keynode found via dns_keytable_findkeynode().
+ */
+
+ REQUIRE(VALID_KEYTABLE(keytable));
+ REQUIRE(VALID_KEYNODE(source));
+ REQUIRE(target != NULL && *target == NULL);
+
+ LOCK(&keytable->lock);
+ keytable->active_nodes++;
+ UNLOCK(&keytable->lock);
+
+ dns_keynode_attach(source, target);
+}
+
+void
dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep)
{
/*
@@ -345,7 +516,7 @@ dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep)
keytable->active_nodes--;
UNLOCK(&keytable->lock);
- *keynodep = NULL;
+ dns_keynode_detach(keytable->mctx, keynodep);
}
isc_result_t
@@ -382,6 +553,44 @@ dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name,
return (result);
}
+isc_result_t
+dns_keytable_dump(dns_keytable_t *keytable, FILE *fp)
+{
+ isc_result_t result;
+ dns_keynode_t *knode;
+ dns_rbtnode_t *node;
+ dns_rbtnodechain_t chain;
+
+ REQUIRE(VALID_KEYTABLE(keytable));
+
+ RWLOCK(&keytable->rwlock, isc_rwlocktype_read);
+ dns_rbtnodechain_init(&chain, keytable->mctx);
+ result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL);
+ if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
+ goto cleanup;
+ for (;;) {
+ char pbuf[DST_KEY_FORMATSIZE];
+
+ dns_rbtnodechain_current(&chain, NULL, NULL, &node);
+ for (knode = node->data; knode != NULL; knode = knode->next) {
+ dst_key_format(knode->key, pbuf, sizeof(pbuf));
+ fprintf(fp, "%s ; %s\n", pbuf,
+ knode->managed ? "managed" : "trusted");
+ }
+ result = dns_rbtnodechain_next(&chain, NULL, NULL);
+ if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+ break;
+ }
+ }
+
+ cleanup:
+ dns_rbtnodechain_invalidate(&chain);
+ RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read);
+ return (result);
+}
+
dst_key_t *
dns_keynode_key(dns_keynode_t *keynode) {
@@ -393,3 +602,71 @@ dns_keynode_key(dns_keynode_t *keynode) {
return (keynode->key);
}
+
+isc_boolean_t
+dns_keynode_managed(dns_keynode_t *keynode) {
+ /*
+ * Is this a managed key?
+ */
+ REQUIRE(VALID_KEYNODE(keynode));
+
+ return (keynode->managed);
+}
+
+isc_result_t
+dns_keynode_create(isc_mem_t *mctx, dns_keynode_t **target) {
+ isc_result_t result;
+ dns_keynode_t *knode = NULL;
+
+ REQUIRE(target != NULL && *target == NULL);
+
+ knode = isc_mem_get(mctx, sizeof(dns_keynode_t));
+ if (knode == NULL)
+ return (ISC_R_NOMEMORY);
+
+ knode->magic = KEYNODE_MAGIC;
+ knode->managed = ISC_FALSE;
+ knode->key = NULL;
+ knode->next = NULL;
+
+ result = isc_refcount_init(&knode->refcount, 1);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ *target = knode;
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_keynode_attach(dns_keynode_t *source, dns_keynode_t **target) {
+ REQUIRE(VALID_KEYNODE(source));
+ isc_refcount_increment(&source->refcount, NULL);
+ *target = source;
+}
+
+void
+dns_keynode_detach(isc_mem_t *mctx, dns_keynode_t **keynode) {
+ unsigned int refs;
+ dns_keynode_t *node = *keynode;
+ REQUIRE(VALID_KEYNODE(node));
+ isc_refcount_decrement(&node->refcount, &refs);
+ if (refs == 0) {
+ if (node->key != NULL)
+ dst_key_free(&node->key);
+ isc_refcount_destroy(&node->refcount);
+ isc_mem_put(mctx, node, sizeof(dns_keynode_t));
+ }
+ *keynode = NULL;
+}
+
+void
+dns_keynode_detachall(isc_mem_t *mctx, dns_keynode_t **keynode) {
+ dns_keynode_t *next = NULL, *node = *keynode;
+ REQUIRE(VALID_KEYNODE(node));
+ while (node != NULL) {
+ next = node->next;
+ dns_keynode_detach(mctx, &node);
+ node = next;
+ }
+ *keynode = NULL;
+}
diff --git a/lib/dns/lib.c b/lib/dns/lib.c
index 761be56bc6d2..6953c8874042 100644
--- a/lib/dns/lib.c
+++ b/lib/dns/lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lib.c,v 1.16 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: lib.c,v 1.19 2009-09-03 00:12:23 each Exp $ */
/*! \file */
@@ -23,11 +23,20 @@
#include <stddef.h>
-#include <isc/once.h>
+#include <isc/hash.h>
+#include <isc/mem.h>
#include <isc/msgcat.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
#include <isc/util.h>
+#include <dns/db.h>
+#include <dns/ecdb.h>
#include <dns/lib.h>
+#include <dns/result.h>
+
+#include <dst/dst.h>
+
/***
*** Globals
@@ -63,3 +72,97 @@ dns_lib_initmsgcat(void) {
RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS);
}
+
+static isc_once_t init_once = ISC_ONCE_INIT;
+static isc_mem_t *dns_g_mctx = NULL;
+#ifndef BIND9
+static dns_dbimplementation_t *dbimp = NULL;
+#endif
+static isc_boolean_t initialize_done = ISC_FALSE;
+static isc_mutex_t reflock;
+static unsigned int references = 0;
+
+static void
+initialize(void) {
+ isc_result_t result;
+
+ REQUIRE(initialize_done == ISC_FALSE);
+
+ result = isc_mem_create(0, 0, &dns_g_mctx);
+ if (result != ISC_R_SUCCESS)
+ return;
+ dns_result_register();
+#ifndef BIND9
+ result = dns_ecdb_register(dns_g_mctx, &dbimp);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_mctx;
+#endif
+ result = isc_hash_create(dns_g_mctx, NULL, DNS_NAME_MAXWIRE);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_db;
+
+ result = dst_lib_init(dns_g_mctx, NULL, 0);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_hash;
+
+ result = isc_mutex_init(&reflock);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_dst;
+
+ initialize_done = ISC_TRUE;
+ return;
+
+ cleanup_dst:
+ dst_lib_destroy();
+ cleanup_hash:
+ isc_hash_destroy();
+ cleanup_db:
+#ifndef BIND9
+ dns_ecdb_unregister(&dbimp);
+ cleanup_mctx:
+#endif
+ isc_mem_detach(&dns_g_mctx);
+}
+
+isc_result_t
+dns_lib_init(void) {
+ isc_result_t result;
+
+ /*
+ * Since this routine is expected to be used by a normal application,
+ * it should be better to return an error, instead of an emergency
+ * abort, on any failure.
+ */
+ result = isc_once_do(&init_once, initialize);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ if (!initialize_done)
+ return (ISC_R_FAILURE);
+
+ LOCK(&reflock);
+ references++;
+ UNLOCK(&reflock);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_lib_shutdown(void) {
+ isc_boolean_t cleanup_ok = ISC_FALSE;
+
+ LOCK(&reflock);
+ if (--references == 0)
+ cleanup_ok = ISC_TRUE;
+ UNLOCK(&reflock);
+
+ if (!cleanup_ok)
+ return;
+
+ dst_lib_destroy();
+ isc_hash_destroy();
+#ifndef BIND9
+ dns_ecdb_unregister(&dbimp);
+#endif
+ isc_mem_detach(&dns_g_mctx);
+}
diff --git a/lib/dns/log.c b/lib/dns/log.c
index 5b3ee3226a90..9de5976a19e7 100644
--- a/lib/dns/log.c
+++ b/lib/dns/log.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: log.c,v 1.45 2007-06-18 23:47:40 tbox Exp $ */
+/* $Id: log.c,v 1.47 2009-12-18 23:49:03 tbox Exp $ */
/*! \file */
@@ -79,6 +79,7 @@ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = {
{ "dns/hints", 0 },
{ "dns/acache", 0 },
{ "dns/dlz", 0 },
+ { "dns/dnssec", 0 },
{ NULL, 0 }
};
diff --git a/lib/dns/master.c b/lib/dns/master.c
index 9c6d3b8560ed..e90a74cfd6b1 100644
--- a/lib/dns/master.c
+++ b/lib/dns/master.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: master.c,v 1.171.120.2 2009-01-18 23:47:40 tbox Exp $ */
+/* $Id: master.c,v 1.178 2009-09-01 00:22:26 jinmei Exp $ */
/*! \file */
@@ -85,7 +85,11 @@
*/
#define TOKENSIZ (8*1024)
-#define DNS_MASTER_BUFSZ 2048
+/*%
+ * Buffers sizes for $GENERATE.
+ */
+#define DNS_MASTER_LHS 2048
+#define DNS_MASTER_RHS MINTSIZ
typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t;
@@ -614,6 +618,57 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
return (result);
}
+static const char *hex = "0123456789abcdef0123456789ABCDEF";
+
+/*%
+ * Convert value into a nibble sequence from least significant to most
+ * significant nibble. Zero fill upper most significant nibbles if
+ * required to make the width.
+ *
+ * Returns the number of characters that should have been written without
+ * counting the terminating NUL.
+ */
+static unsigned int
+nibbles(char *numbuf, size_t length, unsigned int width, char mode, int value) {
+ unsigned int count = 0;
+
+ /*
+ * This reserve space for the NUL string terminator.
+ */
+ if (length > 0U) {
+ *numbuf = '\0';
+ length--;
+ }
+ do {
+ char val = hex[(value & 0x0f) + ((mode == 'n') ? 0 : 16)];
+ value >>= 4;
+ if (length > 0U) {
+ *numbuf++ = val;
+ *numbuf = '\0';
+ length--;
+ }
+ if (width > 0)
+ width--;
+ count++;
+ /*
+ * If width is non zero then we need to add a label seperator.
+ * If value is non zero then we need to add another label and
+ * that requires a label seperator.
+ */
+ if (width > 0 || value != 0) {
+ if (length > 0U) {
+ *numbuf++ = '.';
+ *numbuf = '\0';
+ length--;
+ }
+ if (width > 0)
+ width--;
+ count++;
+ }
+ } while (value != 0 || width > 0);
+ return (count);
+}
+
static isc_result_t
genname(char *name, int it, char *buffer, size_t length) {
char fmt[sizeof("%04000000000d")];
@@ -624,6 +679,7 @@ genname(char *name, int it, char *buffer, size_t length) {
isc_textregion_t r;
unsigned int n;
unsigned int width;
+ isc_boolean_t nibblemode;
r.base = buffer;
r.length = length;
@@ -638,10 +694,11 @@ genname(char *name, int it, char *buffer, size_t length) {
isc_textregion_consume(&r, 1);
continue;
}
+ nibblemode = ISC_FALSE;
strcpy(fmt, "%d");
/* Get format specifier. */
if (*name == '{' ) {
- n = sscanf(name, "{%d,%u,%1[doxX]}",
+ n = sscanf(name, "{%d,%u,%1[doxXnN]}",
&delta, &width, mode);
switch (n) {
case 1:
@@ -651,6 +708,8 @@ genname(char *name, int it, char *buffer, size_t length) {
"%%0%ud", width);
break;
case 3:
+ if (mode[0] == 'n' || mode[0] == 'N')
+ nibblemode = ISC_TRUE;
n = snprintf(fmt, sizeof(fmt),
"%%0%u%c", width, mode[0]);
break;
@@ -663,7 +722,12 @@ genname(char *name, int it, char *buffer, size_t length) {
while (*name != '\0' && *name++ != '}')
continue;
}
- n = snprintf(numbuf, sizeof(numbuf), fmt, it + delta);
+ if (nibblemode)
+ n = nibbles(numbuf, sizeof(numbuf), width,
+ mode[0], it + delta);
+ else
+ n = snprintf(numbuf, sizeof(numbuf), fmt,
+ it + delta);
if (n >= sizeof(numbuf))
return (ISC_R_NOSPACE);
cp = numbuf;
@@ -746,8 +810,8 @@ generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
ISC_LIST_INIT(head);
target_mem = isc_mem_get(lctx->mctx, target_size);
- rhsbuf = isc_mem_get(lctx->mctx, DNS_MASTER_BUFSZ);
- lhsbuf = isc_mem_get(lctx->mctx, DNS_MASTER_BUFSZ);
+ rhsbuf = isc_mem_get(lctx->mctx, DNS_MASTER_RHS);
+ lhsbuf = isc_mem_get(lctx->mctx, DNS_MASTER_LHS);
if (target_mem == NULL || rhsbuf == NULL || lhsbuf == NULL) {
result = ISC_R_NOMEMORY;
goto error_cleanup;
@@ -778,35 +842,13 @@ generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
goto insist_cleanup;
}
- switch (type) {
- case dns_rdatatype_ns:
- case dns_rdatatype_ptr:
- case dns_rdatatype_cname:
- case dns_rdatatype_dname:
- break;
-
- case dns_rdatatype_a:
- case dns_rdatatype_aaaa:
- if (lctx->zclass == dns_rdataclass_in ||
- lctx->zclass == dns_rdataclass_ch ||
- lctx->zclass == dns_rdataclass_hs)
- break;
- /* FALLTHROUGH */
- default:
- (*callbacks->error)(callbacks,
- "%s: %s:%lu: unsupported type '%s'",
- "$GENERATE", source, line, gtype);
- result = ISC_R_NOTIMPLEMENTED;
- goto error_cleanup;
- }
-
ISC_LIST_INIT(rdatalist.rdata);
ISC_LINK_INIT(&rdatalist, link);
for (i = start; i <= stop; i += step) {
- result = genname(lhs, i, lhsbuf, DNS_MASTER_BUFSZ);
+ result = genname(lhs, i, lhsbuf, DNS_MASTER_LHS);
if (result != ISC_R_SUCCESS)
goto error_cleanup;
- result = genname(rhs, i, rhsbuf, DNS_MASTER_BUFSZ);
+ result = genname(rhs, i, rhsbuf, DNS_MASTER_RHS);
if (result != ISC_R_SUCCESS)
goto error_cleanup;
@@ -820,6 +862,7 @@ generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
if ((lctx->options & DNS_MASTER_ZONE) != 0 &&
(lctx->options & DNS_MASTER_SLAVE) == 0 &&
+ (lctx->options & DNS_MASTER_KEY) == 0 &&
!dns_name_issubdomain(owner, lctx->top))
{
char namebuf[DNS_NAME_FORMATSIZE];
@@ -880,9 +923,9 @@ generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
if (target_mem != NULL)
isc_mem_put(lctx->mctx, target_mem, target_size);
if (lhsbuf != NULL)
- isc_mem_put(lctx->mctx, lhsbuf, DNS_MASTER_BUFSZ);
+ isc_mem_put(lctx->mctx, lhsbuf, DNS_MASTER_LHS);
if (rhsbuf != NULL)
- isc_mem_put(lctx->mctx, rhsbuf, DNS_MASTER_BUFSZ);
+ isc_mem_put(lctx->mctx, rhsbuf, DNS_MASTER_RHS);
return (result);
}
@@ -1270,7 +1313,8 @@ load_text(dns_loadctx_t *lctx) {
goto log_and_cleanup;
}
/* RHS */
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
+ GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING,
+ &token, ISC_FALSE);
rhs = isc_mem_strdup(mctx, DNS_AS_STR(token));
if (rhs == NULL) {
result = ISC_R_NOMEMORY;
@@ -1338,7 +1382,7 @@ load_text(dns_loadctx_t *lctx) {
isc_buffer_setactive(&buffer,
token.value.as_region.length);
result = dns_name_fromtext(new_name, &buffer,
- ictx->origin, ISC_FALSE, NULL);
+ ictx->origin, 0, NULL);
if (MANYERRS(lctx, result)) {
SETRESULT(lctx, result);
LOGIT(result);
@@ -1459,6 +1503,7 @@ load_text(dns_loadctx_t *lctx) {
}
if ((lctx->options & DNS_MASTER_ZONE) != 0 &&
(lctx->options & DNS_MASTER_SLAVE) == 0 &&
+ (lctx->options & DNS_MASTER_KEY) == 0 &&
!dns_name_issubdomain(new_name, lctx->top))
{
char namebuf[DNS_NAME_FORMATSIZE];
diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c
index d6befb5d5c98..e2adf9b24dda 100644
--- a/lib/dns/masterdump.c
+++ b/lib/dns/masterdump.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.c,v 1.94.50.3.18.3 2011-06-21 20:13:22 each Exp $ */
+/* $Id: masterdump.c,v 1.99.328.3 2011-06-21 20:15:47 each Exp $ */
/*! \file */
@@ -42,6 +42,7 @@
#include <dns/log.h>
#include <dns/master.h>
#include <dns/masterdump.h>
+#include <dns/ncache.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rdataset.h>
@@ -60,6 +61,11 @@
return (_r); \
} while (0)
+#define CHECK(x) do { \
+ if ((x) != ISC_R_SUCCESS) \
+ goto cleanup; \
+ } while (0)
+
struct dns_master_style {
unsigned int flags; /* DNS_STYLEFLAG_* */
unsigned int ttl_column;
@@ -156,6 +162,7 @@ static char spaces[N_SPACES+1] = " ";
#define N_TABS 10
static char tabs[N_TABS+1] = "\t\t\t\t\t\t\t\t\t\t";
+#ifdef BIND9
struct dns_dumpctx {
unsigned int magic;
isc_mem_t *mctx;
@@ -183,6 +190,7 @@ struct dns_dumpctx {
dns_totext_ctx_t *ctx,
isc_buffer_t *buffer, FILE *f);
};
+#endif /* BIND9 */
#define NXDOMAIN(x) (((x)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
@@ -336,6 +344,52 @@ str_totext(const char *source, isc_buffer_t *target) {
return (ISC_R_SUCCESS);
}
+static isc_result_t
+ncache_summary(dns_rdataset_t *rdataset, isc_boolean_t omit_final_dot,
+ isc_buffer_t *target)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ dns_rdataset_t rds;
+ dns_name_t name;
+
+ dns_rdataset_init(&rds);
+ dns_name_init(&name, NULL);
+
+ do {
+ dns_ncache_current(rdataset, &name, &rds);
+ for (result = dns_rdataset_first(&rds);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rds)) {
+ CHECK(str_totext("; ", target));
+ CHECK(dns_name_totext(&name, omit_final_dot, target));
+ CHECK(str_totext(" ", target));
+ CHECK(dns_rdatatype_totext(rds.type, target));
+ if (rds.type == dns_rdatatype_rrsig) {
+ CHECK(str_totext(" ", target));
+ CHECK(dns_rdatatype_totext(rds.covers, target));
+ CHECK(str_totext(" ...\n", target));
+ } else {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_current(&rds, &rdata);
+ CHECK(str_totext(" ", target));
+ CHECK(dns_rdata_tofmttext(&rdata, dns_rootname,
+ 0, 0, " ", target));
+ CHECK(str_totext("\n", target));
+ }
+ }
+ dns_rdataset_disassociate(&rds);
+ result = dns_rdataset_next(rdataset);
+ } while (result == ISC_R_SUCCESS);
+
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+ cleanup:
+ if (dns_rdataset_isassociated(&rds))
+ dns_rdataset_disassociate(&rds);
+
+ return (result);
+}
+
/*
* Convert 'rdataset' to master file text format according to 'ctx',
* storing the result in 'target'. If 'owner_name' is NULL, it
@@ -462,6 +516,13 @@ rdataset_totext(dns_rdataset_t *rdataset,
RETERR(str_totext(";-$NXDOMAIN\n", target));
else
RETERR(str_totext(";-$NXRRSET\n", target));
+ /*
+ * Print a summary of the cached records which make
+ * up the negative response.
+ */
+ RETERR(ncache_summary(rdataset, omit_final_dot,
+ target));
+ break;
} else {
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_region_t r;
@@ -637,6 +698,7 @@ dns_master_questiontotext(dns_name_t *owner_name,
ISC_FALSE, target));
}
+#ifdef BIND9
/*
* Print an rdataset. 'buffer' is a scratch buffer, which must have been
* dynamically allocated by the caller. It must be large enough to
@@ -1692,6 +1754,7 @@ dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
return (result);
}
+#endif /* BIND9 */
isc_result_t
dns_master_stylecreate(dns_master_style_t **stylep, unsigned int flags,
diff --git a/lib/dns/message.c b/lib/dns/message.c
index 20237416ab51..b58c13999492 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: message.c,v 1.245.50.7.6.3 2011-06-21 20:13:22 each Exp $ */
+/* $Id: message.c,v 1.254.186.3 2011-06-21 20:15:47 each Exp $ */
/*! \file */
@@ -1804,6 +1804,36 @@ wrong_priority(dns_rdataset_t *rds, int pass, dns_rdatatype_t preferred_glue) {
return (ISC_TRUE);
}
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+/*
+ * Decide whether to not answer with an AAAA record and its RRSIG
+ */
+static inline isc_boolean_t
+norender_rdataset(const dns_rdataset_t *rdataset, unsigned int options)
+{
+ switch (rdataset->type) {
+ case dns_rdatatype_aaaa:
+ if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0)
+ return (ISC_FALSE);
+ break;
+
+ case dns_rdatatype_rrsig:
+ if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 ||
+ rdataset->covers != dns_rdatatype_aaaa)
+ return (ISC_FALSE);
+ break;
+
+ default:
+ return (ISC_FALSE);
+ }
+
+ if (rdataset->rdclass != dns_rdataclass_in)
+ return (ISC_FALSE);
+
+ return (ISC_TRUE);
+}
+
+#endif
isc_result_t
dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
unsigned int options)
@@ -1931,6 +1961,23 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
preferred_glue))
goto next;
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ /*
+ * Suppress AAAAs if asked and we are
+ * not doing DNSSEC or are breaking DNSSEC.
+ * Say so in the AD bit if we break DNSSEC.
+ */
+ if (norender_rdataset(rdataset, options) &&
+ sectionid != DNS_SECTION_QUESTION) {
+ if (sectionid == DNS_SECTION_ANSWER ||
+ sectionid == DNS_SECTION_AUTHORITY)
+ msg->flags &= ~DNS_MESSAGEFLAG_AD;
+ if (OPTOUT(rdataset))
+ msg->flags &= ~DNS_MESSAGEFLAG_AD;
+ goto next;
+ }
+
+#endif
st = *(msg->buffer);
count = 0;
@@ -3071,6 +3118,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
dns_name_t *name, empty_name;
dns_rdataset_t *rdataset;
isc_result_t result;
+ isc_boolean_t seensoa = ISC_FALSE;
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(target != NULL);
@@ -3100,6 +3148,15 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (section == DNS_SECTION_ANSWER &&
+ rdataset->type == dns_rdatatype_soa) {
+ if ((flags & DNS_MESSAGETEXTFLAG_OMITSOA) != 0)
+ continue;
+ if (seensoa &&
+ (flags & DNS_MESSAGETEXTFLAG_ONESOA) != 0)
+ continue;
+ seensoa = ISC_TRUE;
+ }
if (section == DNS_SECTION_QUESTION) {
ADD_STRING(target, ";");
result = dns_master_questiontotext(name,
diff --git a/lib/dns/name.c b/lib/dns/name.c
index 80864b8b9160..f88f281b6188 100644
--- a/lib/dns/name.c
+++ b/lib/dns/name.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: name.c,v 1.165.120.3 2010-07-09 05:15:05 each Exp $ */
+/* $Id: name.c,v 1.174 2011-01-13 04:59:25 tbox Exp $ */
/*! \file */
@@ -34,6 +34,7 @@
#include <isc/util.h>
#include <dns/compress.h>
+#include <dns/fixedname.h>
#include <dns/name.h>
#include <dns/result.h>
@@ -1018,10 +1019,9 @@ dns_name_toregion(dns_name_t *name, isc_region_t *r) {
DNS_NAME_TOREGION(name, r);
}
-
isc_result_t
dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
- dns_name_t *origin, unsigned int options,
+ const dns_name_t *origin, unsigned int options,
isc_buffer_t *target)
{
unsigned char *ndata, *label;
@@ -2360,6 +2360,75 @@ dns_name_format(dns_name_t *name, char *cp, unsigned int size) {
snprintf(cp, size, "<unknown>");
}
+/*
+ * dns_name_tostring() -- similar to dns_name_format() but allocates its own
+ * memory.
+ */
+isc_result_t
+dns_name_tostring(dns_name_t *name, char **target, isc_mem_t *mctx) {
+ isc_result_t result;
+ isc_buffer_t buf;
+ isc_region_t reg;
+ char *p, txt[DNS_NAME_FORMATSIZE];
+
+ REQUIRE(VALID_NAME(name));
+ REQUIRE(target != NULL && *target == NULL);
+
+ isc_buffer_init(&buf, txt, sizeof(txt));
+ result = dns_name_totext(name, ISC_FALSE, &buf);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ isc_buffer_usedregion(&buf, &reg);
+ p = isc_mem_allocate(mctx, reg.length + 1);
+ memcpy(p, (char *) reg.base, (int) reg.length);
+ p[reg.length] = '\0';
+
+ *target = p;
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * dns_name_fromstring() -- convert directly from a string to a name,
+ * allocating memory as needed
+ */
+isc_result_t
+dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options,
+ isc_mem_t *mctx)
+{
+ return (dns_name_fromstring2(target, src, dns_rootname, options, mctx));
+}
+
+isc_result_t
+dns_name_fromstring2(dns_name_t *target, const char *src,
+ const dns_name_t *origin, unsigned int options,
+ isc_mem_t *mctx)
+{
+ isc_result_t result;
+ isc_buffer_t buf;
+ dns_fixedname_t fn;
+ dns_name_t *name;
+
+ REQUIRE(src != NULL);
+
+ isc_buffer_init(&buf, src, strlen(src));
+ isc_buffer_add(&buf, strlen(src));
+ if (BINDABLE(target) && target->buffer != NULL)
+ name = target;
+ else {
+ dns_fixedname_init(&fn);
+ name = dns_fixedname_name(&fn);
+ }
+
+ result = dns_name_fromtext(name, &buf, origin, options, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ if (name != target)
+ result = dns_name_dupwithoffsets(name, mctx, target);
+ return (result);
+}
+
isc_result_t
dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) {
unsigned char *ndata;
diff --git a/lib/dns/ncache.c b/lib/dns/ncache.c
index f1fc3233a595..420a1180eb23 100644
--- a/lib/dns/ncache.c
+++ b/lib/dns/ncache.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ncache.c,v 1.43.48.7.6.3 2011-06-21 20:13:22 each Exp $ */
+/* $Id: ncache.c,v 1.50.124.1.2.3 2011-06-21 20:15:47 each Exp $ */
/*! \file */
@@ -35,7 +35,7 @@
#define DNS_NCACHE_RDATA 20U
/*
- * The format of an ncache rdata is a sequence of one or more records of
+ * The format of an ncache rdata is a sequence of zero or more records of
* the following format:
*
* owner name
@@ -223,42 +223,6 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
return (result);
if (trust == 0xffff) {
- /*
- * We didn't find any authority data from which to create a
- * negative cache rdataset. In particular, we have no SOA.
- *
- * We trust that the caller wants negative caching, so this
- * means we have a "type 3 nxdomain" or "type 3 nodata"
- * response (see RFC2308 for details).
- *
- * We will now build a suitable negative cache rdataset that
- * will cause zero bytes to be emitted when converted to
- * wire format.
- */
-
- /*
- * The ownername must exist, but it doesn't matter what value
- * it has. We use the root name.
- */
- dns_name_toregion(dns_rootname, &r);
- result = isc_buffer_copyregion(&buffer, &r);
- if (result != ISC_R_SUCCESS)
- return (result);
- /*
- * Copy the type and a zero rdata count to the buffer.
- */
- isc_buffer_availableregion(&buffer, &r);
- if (r.length < 5)
- return (ISC_R_NOSPACE);
- isc_buffer_putuint16(&buffer, 0); /* type */
- /*
- * RFC2308, section 5, says that negative answers without
- * SOAs should not be cached.
- */
- ttl = 0;
- /*
- * Set trust.
- */
if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 &&
message->counts[DNS_SECTION_ANSWER] == 0) {
/*
@@ -268,22 +232,7 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
trust = dns_trust_authauthority;
} else
trust = dns_trust_additional;
- isc_buffer_putuint8(&buffer, (unsigned char)trust); /* trust */
- isc_buffer_putuint16(&buffer, 0); /* count */
-
- /*
- * Now add it to the cache.
- */
- if (next >= DNS_NCACHE_RDATA)
- return (ISC_R_NOSPACE);
- dns_rdata_init(&rdata[next]);
- isc_buffer_remainingregion(&buffer, &r);
- rdata[next].data = r.base;
- rdata[next].length = r.length;
- rdata[next].rdclass = ncrdatalist.rdclass;
- rdata[next].type = 0;
- rdata[next].flags = 0;
- ISC_LIST_APPEND(ncrdatalist.rdata, &rdata[next], link);
+ ttl = 0;
}
INSIST(trust != 0xffff);
diff --git a/lib/dns/nsec.c b/lib/dns/nsec.c
index 7d93eccb7c4e..94c5163ecc7d 100644
--- a/lib/dns/nsec.c
+++ b/lib/dns/nsec.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec.c,v 1.11.48.2 2009-01-06 23:47:26 tbox Exp $ */
+/* $Id: nsec.c,v 1.13 2009-01-06 23:47:57 tbox Exp $ */
/*! \file */
diff --git a/lib/dns/nsec3.c b/lib/dns/nsec3.c
index 9c85781c2360..e75e7440abc0 100644
--- a/lib/dns/nsec3.c
+++ b/lib/dns/nsec3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006, 2008-2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3.c,v 1.6.12.4 2009-11-03 23:47:46 tbox Exp $ */
+/* $Id: nsec3.c,v 1.19.96.1 2011-06-21 20:15:48 each Exp $ */
#include <config.h>
@@ -28,6 +28,8 @@
#include <dst/dst.h>
#include <dns/db.h>
+#include <dns/zone.h>
+#include <dns/compress.h>
#include <dns/dbiterator.h>
#include <dns/diff.h>
#include <dns/fixedname.h>
@@ -472,7 +474,6 @@ delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
return (result);
}
-#ifndef RFC5155_STRICT
static isc_boolean_t
better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
dns_rdataset_t rdataset;
@@ -487,7 +488,17 @@ better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_current(&rdataset, &rdata);
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+
+ if (rdataset.type != dns_rdatatype_nsec3param) {
+ dns_rdata_t tmprdata = DNS_RDATA_INIT;
+ dns_rdataset_current(&rdataset, &tmprdata);
+ if (!dns_nsec3param_fromprivate(&tmprdata, &rdata,
+ buf, sizeof(buf)))
+ continue;
+ } else
+ dns_rdataset_current(&rdataset, &rdata);
+
if (rdata.length != param->length)
continue;
if (rdata.data[0] != param->data[0] ||
@@ -505,7 +516,6 @@ better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
dns_rdataset_disassociate(&rdataset);
return (ISC_FALSE);
}
-#endif
static isc_result_t
find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
@@ -548,7 +558,7 @@ dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
dns_rdataset_t rdataset;
int pass;
isc_boolean_t exists;
- isc_boolean_t remove_unsecure = ISC_FALSE;
+ isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
isc_uint8_t flags;
isc_buffer_t buffer;
isc_result_t result;
@@ -629,8 +639,12 @@ dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
*/
if (!unsecure)
goto addnsec3;
- else
- remove_unsecure = ISC_TRUE;
+ else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
+ result = dns_nsec3_delnsec3(db, version, name,
+ nsec3param, diff);
+ goto failure;
+ } else
+ maybe_remove_unsecure = ISC_TRUE;
} else {
dns_rdataset_disassociate(&rdataset);
if (result != ISC_R_NOMORE)
@@ -666,26 +680,19 @@ dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
if (result != ISC_R_SUCCESS)
goto failure;
- if (remove_unsecure) {
+ if (maybe_remove_unsecure) {
dns_rdataset_disassociate(&rdataset);
/*
- * We have found the previous NSEC3 record and can now
- * see if the existing NSEC3 record needs to be
- * updated or deleted.
+ * If we have OPTOUT set in the previous NSEC3 record
+ * we actually need to delete the NSEC3 record.
+ * Otherwise we just need to replace the NSEC3 record.
*/
- if (!OPTOUT(nsec3.flags)) {
- /*
- * Just update the NSEC3 record.
- */
- goto addnsec3;
- } else {
- /*
- * This is actually a deletion not a add.
- */
+ if (OPTOUT(nsec3.flags)) {
result = dns_nsec3_delnsec3(db, version, name,
nsec3param, diff);
goto failure;
}
+ goto addnsec3;
} else {
/*
* Is this is a unsecure delegation we are adding?
@@ -928,17 +935,323 @@ dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&rdataset, &rdata);
- dns_rdata_tostruct(&rdata, &nsec3param, NULL);
+ CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
+
+ if (nsec3param.flags != 0)
+ continue;
+ /*
+ * We have a active chain. Update it.
+ */
+ CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
+ nsecttl, unsecure, diff));
+ }
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+
+ failure:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+
+ return (result);
+}
+
+isc_boolean_t
+dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
+ unsigned char *buf, size_t buflen)
+{
+ dns_decompress_t dctx;
+ isc_result_t result;
+ isc_buffer_t buf1;
+ isc_buffer_t buf2;
+
+ /*
+ * Algorithm 0 (reserved by RFC 4034) is used to identify
+ * NSEC3PARAM records from DNSKEY pointers.
+ */
+ if (src->length < 1 || src->data[0] != 0)
+ return (ISC_FALSE);
+
+ isc_buffer_init(&buf1, src->data + 1, src->length - 1);
+ isc_buffer_add(&buf1, src->length - 1);
+ isc_buffer_setactive(&buf1, src->length - 1);
+ isc_buffer_init(&buf2, buf, buflen);
+ dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
+ result = dns_rdata_fromwire(target, src->rdclass,
+ dns_rdatatype_nsec3param,
+ &buf1, &dctx, 0, &buf2);
+ dns_decompress_invalidate(&dctx);
+
+ return (ISC_TF(result == ISC_R_SUCCESS));
+}
+
+void
+dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
+ dns_rdatatype_t privatetype,
+ unsigned char *buf, size_t buflen)
+{
+ REQUIRE(buflen >= src->length + 1);
+
+ REQUIRE(DNS_RDATA_INITIALIZED(target));
+
+ memcpy(buf + 1, src->data, src->length);
+ buf[0] = 0;
+ target->data = buf;
+ target->length = src->length + 1;
+ target->type = privatetype;
+ target->rdclass = src->rdclass;
+ target->flags = 0;
+ ISC_LINK_INIT(target, link);
+}
+
+#ifdef BIND9
+static isc_result_t
+rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
+ const dns_rdata_t *rdata, isc_boolean_t *flag)
+{
+ dns_rdataset_t rdataset;
+ dns_dbnode_t *node = NULL;
+ isc_result_t result;
+
+ dns_rdataset_init(&rdataset);
+ if (rdata->type == dns_rdatatype_nsec3)
+ CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
+ else
+ CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
+ result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
+ (isc_stdtime_t) 0, &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND) {
+ *flag = ISC_FALSE;
+ result = ISC_R_SUCCESS;
+ goto failure;
+ }
+
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t myrdata = DNS_RDATA_INIT;
+ dns_rdataset_current(&rdataset, &myrdata);
+ if (!dns_rdata_casecompare(&myrdata, rdata))
+ break;
+ }
+ dns_rdataset_disassociate(&rdataset);
+ if (result == ISC_R_SUCCESS) {
+ *flag = ISC_TRUE;
+ } else if (result == ISC_R_NOMORE) {
+ *flag = ISC_FALSE;
+ result = ISC_R_SUCCESS;
+ }
+
+ failure:
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ return (result);
+}
+#endif
+
+#ifdef BIND9
+isc_result_t
+dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
+ dns_zone_t *zone, dns_diff_t *diff)
+{
+ dns_dbnode_t *node = NULL;
+ dns_difftuple_t *tuple = NULL;
+ dns_name_t next;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_t rdataset;
+ isc_boolean_t flag;
+ isc_result_t result = ISC_R_SUCCESS;
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
+ dns_name_t *origin = dns_zone_getorigin(zone);
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
+
+ dns_name_init(&next, NULL);
+ dns_rdataset_init(&rdataset);
+
+ result = dns_db_getoriginnode(db, &node);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * Cause all NSEC3 chains to be deleted.
+ */
+ result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
+ 0, (isc_stdtime_t) 0, &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ goto try_private;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t private = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&rdataset, &rdata);
+
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
+ rdataset.ttl, &rdata, &tuple));
+ CHECK(do_one_tuple(&tuple, db, ver, diff));
+ INSIST(tuple == NULL);
+
+ dns_nsec3param_toprivate(&rdata, &private, privatetype,
+ buf, sizeof(buf));
+ buf[2] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
+
+ CHECK(rr_exists(db, ver, origin, &private, &flag));
+
+ if (!flag) {
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
+ origin, 0, &private,
+ &tuple));
+ CHECK(do_one_tuple(&tuple, db, ver, diff));
+ INSIST(tuple == NULL);
+ }
+ dns_rdata_reset(&rdata);
+ }
+ if (result != ISC_R_NOMORE)
+ goto failure;
+
+ dns_rdataset_disassociate(&rdataset);
+
+ try_private:
+ if (privatetype == 0)
+ goto success;
+ result = dns_db_findrdataset(db, node, ver, privatetype, 0,
+ (isc_stdtime_t) 0, &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ goto success;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdataset_current(&rdataset, &rdata);
+ INSIST(rdata.length <= sizeof(buf));
+ memcpy(buf, rdata.data, rdata.length);
+
+ if (buf[0] != 0 ||
+ buf[2] == (DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC)) {
+ dns_rdata_reset(&rdata);
+ continue;
+ }
+
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
+ 0, &rdata, &tuple));
+ CHECK(do_one_tuple(&tuple, db, ver, diff));
+ INSIST(tuple == NULL);
+
+ rdata.data = buf;
+ buf[2] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
+
+ CHECK(rr_exists(db, ver, origin, &rdata, &flag));
+
+ if (!flag) {
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
+ origin, 0, &rdata, &tuple));
+ CHECK(do_one_tuple(&tuple, db, ver, diff));
+ INSIST(tuple == NULL);
+ }
+ dns_rdata_reset(&rdata);
+ }
+ if (result != ISC_R_NOMORE)
+ goto failure;
+ success:
+ result = ISC_R_SUCCESS;
+
+ failure:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ dns_db_detachnode(db, &node);
+ return (result);
+}
+#endif
+
+isc_result_t
+dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
+ dns_name_t *name, dns_ttl_t nsecttl,
+ isc_boolean_t unsecure, dns_rdatatype_t type,
+ dns_diff_t *diff)
+{
+ dns_dbnode_t *node = NULL;
+ dns_rdata_nsec3param_t nsec3param;
+ dns_rdataset_t rdataset;
+ dns_rdataset_t prdataset;
+ isc_result_t result;
+
+ dns_rdataset_init(&rdataset);
+ dns_rdataset_init(&prdataset);
+
+ /*
+ * Find the NSEC3 parameters for this zone.
+ */
+ result = dns_db_getoriginnode(db, &node);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = dns_db_findrdataset(db, node, version, type, 0, 0,
+ &prdataset, NULL);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
+ goto failure;
+
+ result = dns_db_findrdataset(db, node, version,
+ dns_rdatatype_nsec3param, 0, 0,
+ &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ goto try_private;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ /*
+ * Update each active NSEC3 chain.
+ */
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&rdataset, &rdata);
+ CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
-#ifdef RFC5155_STRICT
if (nsec3param.flags != 0)
continue;
-#else
+
+ /*
+ * We have a active chain. Update it.
+ */
+ CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
+ nsecttl, unsecure, diff));
+ }
+ if (result != ISC_R_NOMORE)
+ goto failure;
+
+ dns_rdataset_disassociate(&rdataset);
+
+ try_private:
+ if (!dns_rdataset_isassociated(&prdataset))
+ goto success;
+ /*
+ * Update each active NSEC3 chain.
+ */
+ for (result = dns_rdataset_first(&prdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&prdataset)) {
+ dns_rdata_t rdata1 = DNS_RDATA_INIT;
+ dns_rdata_t rdata2 = DNS_RDATA_INIT;
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+
+ dns_rdataset_current(&prdataset, &rdata1);
+ if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
+ buf, sizeof(buf)))
+ continue;
+ CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
+
if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
continue;
- if (better_param(&rdataset, &rdata))
+ if (better_param(&prdataset, &rdata2))
continue;
-#endif
/*
* We have a active chain. Update it.
@@ -947,11 +1260,13 @@ dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
nsecttl, unsecure, diff));
}
if (result == ISC_R_NOMORE)
+ success:
result = ISC_R_SUCCESS;
-
failure:
if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset);
+ if (dns_rdataset_isassociated(&prdataset))
+ dns_rdataset_disassociate(&prdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
@@ -1120,6 +1435,8 @@ dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
*/
nsec3.next = nexthash;
nsec3.next_length = next_length;
+ if (CREATE(nsec3param->flags))
+ nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
dns_rdatatype_nsec3, &nsec3,
@@ -1257,6 +1574,13 @@ isc_result_t
dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
dns_diff_t *diff)
{
+ return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
+}
+
+isc_result_t
+dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
+ dns_rdatatype_t privatetype, dns_diff_t *diff)
+{
dns_dbnode_t *node = NULL;
dns_rdata_nsec3param_t nsec3param;
dns_rdataset_t rdataset;
@@ -1274,11 +1598,10 @@ dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
result = dns_db_findrdataset(db, node, version,
dns_rdatatype_nsec3param, 0, 0,
&rdataset, NULL);
- dns_db_detachnode(db, &node);
if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
+ goto try_private;
if (result != ISC_R_SUCCESS)
- return (result);
+ goto failure;
/*
* Update each active NSEC3 chain.
@@ -1289,17 +1612,47 @@ dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&rdataset, &rdata);
- dns_rdata_tostruct(&rdata, &nsec3param, NULL);
+ CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
-#ifdef RFC5155_STRICT
if (nsec3param.flags != 0)
continue;
-#else
+ /*
+ * We have a active chain. Update it.
+ */
+ CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
+ }
+ dns_rdataset_disassociate(&rdataset);
+
+ try_private:
+ if (privatetype == 0)
+ goto success;
+ result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
+ &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ goto success;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ /*
+ * Update each NSEC3 chain being built.
+ */
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t rdata1 = DNS_RDATA_INIT;
+ dns_rdata_t rdata2 = DNS_RDATA_INIT;
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+
+ dns_rdataset_current(&rdataset, &rdata1);
+ if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
+ buf, sizeof(buf)))
+ continue;
+ CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
+
if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
continue;
- if (better_param(&rdataset, &rdata))
+ if (better_param(&rdataset, &rdata2))
continue;
-#endif
/*
* We have a active chain. Update it.
@@ -1307,6 +1660,7 @@ dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
}
if (result == ISC_R_NOMORE)
+ success:
result = ISC_R_SUCCESS;
failure:
@@ -1322,6 +1676,14 @@ isc_result_t
dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
isc_boolean_t complete, isc_boolean_t *answer)
{
+ return (dns_nsec3_activex(db, version, complete, 0, answer));
+}
+
+isc_result_t
+dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
+ isc_boolean_t complete, dns_rdatatype_t privatetype,
+ isc_boolean_t *answer)
+{
dns_dbnode_t *node = NULL;
dns_rdataset_t rdataset;
dns_rdata_nsec3param_t nsec3param;
@@ -1338,34 +1700,78 @@ dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
result = dns_db_findrdataset(db, node, version,
dns_rdatatype_nsec3param, 0, 0,
&rdataset, NULL);
- dns_db_detachnode(db, &node);
+ if (result == ISC_R_NOTFOUND)
+ goto try_private;
+
+ if (result != ISC_R_SUCCESS) {
+ dns_db_detachnode(db, &node);
+ return (result);
+ }
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ if (nsec3param.flags == 0)
+ break;
+ }
+ dns_rdataset_disassociate(&rdataset);
+ if (result == ISC_R_SUCCESS) {
+ dns_db_detachnode(db, &node);
+ *answer = ISC_TRUE;
+ return (ISC_R_SUCCESS);
+ }
+ if (result == ISC_R_NOMORE)
+ *answer = ISC_FALSE;
+
+ try_private:
+ if (privatetype == 0 || complete) {
+ *answer = ISC_FALSE;
+ return (ISC_R_SUCCESS);
+ }
+ result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
+ &rdataset, NULL);
+
+ dns_db_detachnode(db, &node);
if (result == ISC_R_NOTFOUND) {
*answer = ISC_FALSE;
return (ISC_R_SUCCESS);
}
if (result != ISC_R_SUCCESS)
return (result);
+
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
- dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_t rdata1 = DNS_RDATA_INIT;
+ dns_rdata_t rdata2 = DNS_RDATA_INIT;
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
- dns_rdataset_current(&rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
+ dns_rdataset_current(&rdataset, &rdata1);
+ if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
+ buf, sizeof(buf)))
+ continue;
+ result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if ((nsec3param.flags) == 0 ||
- (!complete && CREATE(nsec3param.flags)))
+ if (!complete && CREATE(nsec3param.flags))
break;
}
dns_rdataset_disassociate(&rdataset);
- if (result == ISC_R_SUCCESS)
+ if (result == ISC_R_SUCCESS) {
*answer = ISC_TRUE;
+ result = ISC_R_SUCCESS;
+ }
if (result == ISC_R_NOMORE) {
*answer = ISC_FALSE;
result = ISC_R_SUCCESS;
}
+
return (result);
}
diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c
index 081e3c6fe82d..8c733f68a0c3 100644
--- a/lib/dns/openssl_link.c
+++ b/lib/dns/openssl_link.c
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: openssl_link.c,v 1.22.112.5 2010-09-15 12:37:35 tbox Exp $
+ * $Id: openssl_link.c,v 1.29 2010-09-15 12:38:36 tbox Exp $
*/
#ifdef OPENSSL
@@ -45,6 +45,8 @@
#include <isc/thread.h>
#include <isc/util.h>
+#include <dst/result.h>
+
#include "dst_internal.h"
#include "dst_openssl.h"
@@ -60,12 +62,6 @@
#ifdef USE_ENGINE
#include <openssl/engine.h>
-
-#ifdef ENGINE_ID
-const char *engine_id = ENGINE_ID;
-#else
-const char *engine_id;
-#endif
#endif
static RAND_METHOD *rm = NULL;
@@ -74,15 +70,7 @@ static isc_mutex_t *locks = NULL;
static int nlocks;
#ifdef USE_ENGINE
-static ENGINE *e;
-static ENGINE *he;
-#endif
-
-#ifdef USE_PKCS11
-static isc_result_t
-dst__openssl_load_engine(const char *name, const char *engine_id,
- const char **pre_cmds, int pre_num,
- const char **post_cmds, int post_num);
+static ENGINE *e = NULL;
#endif
static int
@@ -135,8 +123,16 @@ id_callback(void) {
static void *
mem_alloc(size_t size) {
+#ifdef OPENSSL_LEAKS
+ void *ptr;
+
+ INSIST(dst__memory_pool != NULL);
+ ptr = isc_mem_allocate(dst__memory_pool, size);
+ return (ptr);
+#else
INSIST(dst__memory_pool != NULL);
return (isc_mem_allocate(dst__memory_pool, size));
+#endif
}
static void
@@ -148,16 +144,26 @@ mem_free(void *ptr) {
static void *
mem_realloc(void *ptr, size_t size) {
+#ifdef OPENSSL_LEAKS
+ void *rptr;
+
+ INSIST(dst__memory_pool != NULL);
+ rptr = isc_mem_reallocate(dst__memory_pool, ptr, size);
+ return (rptr);
+#else
INSIST(dst__memory_pool != NULL);
return (isc_mem_reallocate(dst__memory_pool, ptr, size));
+#endif
}
isc_result_t
-dst__openssl_init() {
+dst__openssl_init(const char *engine) {
isc_result_t result;
#ifdef USE_ENGINE
- /* const char *name; */
ENGINE *re;
+#else
+
+ UNUSED(engine);
#endif
#ifdef DNS_CRYPTO_LEAKS
@@ -187,70 +193,26 @@ dst__openssl_init() {
rm->add = entropy_add;
rm->pseudorand = entropy_getpseudo;
rm->status = entropy_status;
+
#ifdef USE_ENGINE
OPENSSL_config(NULL);
-#ifdef USE_PKCS11
-#ifndef PKCS11_SO_PATH
-#define PKCS11_SO_PATH "/usr/local/lib/engines/engine_pkcs11.so"
-#endif
-#ifndef PKCS11_MODULE_PATH
-#define PKCS11_MODULE_PATH "/usr/lib/libpkcs11.so"
-#endif
- {
- /*
- * to use this to config the PIN, add in openssl.cnf:
- * - at the beginning: "openssl_conf = openssl_def"
- * - at any place these sections:
- * [ openssl_def ]
- * engines = engine_section
- * [ engine_section ]
- * pkcs11 = pkcs11_section
- * [ pkcs11_section ]
- * PIN = my___pin
- */
-
- const char *pre_cmds[] = {
- "SO_PATH", PKCS11_SO_PATH,
- "LOAD", NULL,
- "MODULE_PATH", PKCS11_MODULE_PATH
- };
- const char *post_cmds[] = {
- /* "PIN", "my___pin" */
- };
- result = dst__openssl_load_engine("pkcs11", "pkcs11",
- pre_cmds, 0,
- post_cmds, /*1*/ 0);
- if (result != ISC_R_SUCCESS)
- goto cleanup_rm;
- }
-#endif /* USE_PKCS11 */
- if (engine_id != NULL) {
- e = ENGINE_by_id(engine_id);
+
+ if (engine != NULL && *engine == '\0')
+ engine = NULL;
+
+ if (engine != NULL) {
+ e = ENGINE_by_id(engine);
if (e == NULL) {
- result = ISC_R_NOTFOUND;
+ result = DST_R_NOENGINE;
goto cleanup_rm;
}
- if (!ENGINE_init(e)) {
- result = ISC_R_FAILURE;
- ENGINE_free(e);
+ /* This will init the engine. */
+ if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
+ result = DST_R_NOENGINE;
goto cleanup_rm;
}
- ENGINE_set_default(e, ENGINE_METHOD_ALL);
- ENGINE_free(e);
- } else {
- ENGINE_register_all_complete();
- for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {
-
- /*
- * Something weird here. If we call ENGINE_finish()
- * ENGINE_get_default_RAND() will fail.
- */
- if (ENGINE_init(e)) {
- if (he == NULL)
- he = e;
- }
- }
}
+
re = ENGINE_get_default_RAND();
if (re == NULL) {
re = ENGINE_new();
@@ -263,7 +225,6 @@ dst__openssl_init() {
ENGINE_free(re);
} else
ENGINE_finish(re);
-
#else
RAND_set_rand_method(rm);
#endif /* USE_ENGINE */
@@ -271,13 +232,18 @@ dst__openssl_init() {
#ifdef USE_ENGINE
cleanup_rm:
+ if (e != NULL)
+ ENGINE_free(e);
+ e = NULL;
mem_free(rm);
+ rm = NULL;
#endif
cleanup_mutexinit:
CRYPTO_set_locking_callback(NULL);
DESTROYMUTEXBLOCK(locks, nlocks);
cleanup_mutexalloc:
mem_free(locks);
+ locks = NULL;
return (result);
}
@@ -287,15 +253,22 @@ dst__openssl_destroy() {
/*
* Sequence taken from apps_shutdown() in <apps/apps.h>.
*/
+ if (rm != NULL) {
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+ RAND_cleanup();
+#endif
+ mem_free(rm);
+ rm = NULL;
+ }
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
- CONF_modules_unload(1);
+ CONF_modules_free();
#endif
+ OBJ_cleanup();
EVP_cleanup();
#if defined(USE_ENGINE)
- if (e != NULL) {
- ENGINE_finish(e);
- e = NULL;
- }
+ if (e != NULL)
+ ENGINE_free(e);
+ e = NULL;
#if defined(USE_ENGINE) && OPENSSL_VERSION_NUMBER >= 0x00907000L
ENGINE_cleanup();
#endif
@@ -304,23 +277,18 @@ dst__openssl_destroy() {
CRYPTO_cleanup_all_ex_data();
#endif
ERR_clear_error();
- ERR_free_strings();
ERR_remove_state(0);
+ ERR_free_strings();
#ifdef DNS_CRYPTO_LEAKS
CRYPTO_mem_leaks_fp(stderr);
#endif
- if (rm != NULL) {
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
- RAND_cleanup();
-#endif
- mem_free(rm);
- }
if (locks != NULL) {
CRYPTO_set_locking_callback(NULL);
DESTROYMUTEXBLOCK(locks, nlocks);
mem_free(locks);
+ locks = NULL;
}
}
@@ -341,91 +309,18 @@ dst__openssl_toresult(isc_result_t fallback) {
}
ENGINE *
-dst__openssl_getengine(const char *name) {
-
- UNUSED(name);
-
+dst__openssl_getengine(const char *engine) {
+ if (engine == NULL)
+ return (NULL);
#if defined(USE_ENGINE)
- return (he);
-#else
- return (NULL);
-#endif
-}
-
-isc_result_t
-dst__openssl_setdefault(const char *name) {
-
- UNUSED(name);
-
-#if defined(USE_ENGINE)
- ENGINE_set_default(e, ENGINE_METHOD_ALL);
-#endif
- /*
- * XXXMPA If the engine does not have a default RAND method
- * restore our method.
- */
- return (ISC_R_SUCCESS);
-}
-
-#ifdef USE_PKCS11
-/*
- * 'name' is the name the engine is known by to the dst library.
- * This may or may not match the name the engine is known by to
- * openssl. It is the name that is stored in the private key file.
- *
- * 'engine_id' is the openssl engine name.
- *
- * pre_cmds and post_cmds a sequence if command argument pairs
- * pre_num and post_num are a count of those pairs.
- *
- * "SO_PATH", PKCS11_SO_PATH ("/usr/local/lib/engines/engine_pkcs11.so")
- * "LOAD", NULL
- * "MODULE_PATH", PKCS11_MODULE_PATH ("/usr/lib/libpkcs11.so")
- */
-static isc_result_t
-dst__openssl_load_engine(const char *name, const char *engine_id,
- const char **pre_cmds, int pre_num,
- const char **post_cmds, int post_num)
-{
- ENGINE *e;
-
- UNUSED(name);
-
- if (!strcasecmp(engine_id, "dynamic"))
- ENGINE_load_dynamic();
- e = ENGINE_by_id(engine_id);
if (e == NULL)
- return (ISC_R_NOTFOUND);
- while (pre_num--) {
- if (!ENGINE_ctrl_cmd_string(e, pre_cmds[0], pre_cmds[1], 0)) {
- ENGINE_free(e);
- return (ISC_R_FAILURE);
- }
- pre_cmds += 2;
- }
- if (!ENGINE_init(e)) {
- ENGINE_free(e);
- return (ISC_R_FAILURE);
- }
- /*
- * ENGINE_init() returned a functional reference, so free the
- * structural reference from ENGINE_by_id().
- */
- ENGINE_free(e);
- while (post_num--) {
- if (!ENGINE_ctrl_cmd_string(e, post_cmds[0], post_cmds[1], 0)) {
- ENGINE_free(e);
- return (ISC_R_FAILURE);
- }
- post_cmds += 2;
- }
- if (he != NULL)
- ENGINE_finish(he);
- he = e;
- return (ISC_R_SUCCESS);
+ return (NULL);
+ if (strcmp(engine, ENGINE_get_id(e)) == 0)
+ return (e);
+#endif
+ return (NULL);
}
-#endif /* USE_PKCS11 */
#else /* OPENSSL */
diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c
index e31137f1af27..9deda6b45ebe 100644
--- a/lib/dns/openssldh_link.c
+++ b/lib/dns/openssldh_link.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: openssldh_link.c,v 1.14 2008-04-01 23:47:10 tbox Exp $
+ * $Id: openssldh_link.c,v 1.20 2011-01-11 23:47:13 tbox Exp $
*/
#ifdef OPENSSL
@@ -149,12 +149,37 @@ openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
return (ISC_TRUE);
}
+#if OPENSSL_VERSION_NUMBER > 0x00908000L
+static int
+progress_cb(int p, int n, BN_GENCB *cb)
+{
+ union {
+ void *dptr;
+ void (*fptr)(int);
+ } u;
+
+ UNUSED(n);
+
+ u.dptr = cb->arg;
+ if (u.fptr != NULL)
+ u.fptr(p);
+ return (1);
+}
+#endif
+
static isc_result_t
-openssldh_generate(dst_key_t *key, int generator) {
+openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) {
+ DH *dh = NULL;
#if OPENSSL_VERSION_NUMBER > 0x00908000L
BN_GENCB cb;
+ union {
+ void *dptr;
+ void (*fptr)(int);
+ } u;
+#else
+
+ UNUSED(callback);
#endif
- DH *dh = NULL;
if (generator == 0) {
if (key->key_size == 768 ||
@@ -181,7 +206,12 @@ openssldh_generate(dst_key_t *key, int generator) {
if (dh == NULL)
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- BN_GENCB_set_old(&cb, NULL, NULL);
+ if (callback == NULL) {
+ BN_GENCB_set_old(&cb, NULL, NULL);
+ } else {
+ u.fptr = callback;
+ BN_GENCB_set(&cb, &progress_cb, u.dptr);
+ }
if (!DH_generate_parameters_ex(dh, key->key_size, generator,
&cb)) {
@@ -476,7 +506,7 @@ openssldh_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-openssldh_parse(dst_key_t *key, isc_lex_t *lexer) {
+openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
int i;
@@ -484,6 +514,7 @@ openssldh_parse(dst_key_t *key, isc_lex_t *lexer) {
isc_mem_t *mctx;
#define DST_RET(a) {ret = a; goto err;}
+ UNUSED(pub);
mctx = key->mctx;
/* read private key file */
@@ -609,6 +640,8 @@ static dst_func_t openssldh_functions = {
openssldh_parse,
openssldh_cleanup,
NULL, /*%< fromlabel */
+ NULL, /*%< dump */
+ NULL, /*%< restore */
};
isc_result_t
diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c
index c563d9bc10ff..ae88d4c99817 100644
--- a/lib/dns/openssldsa_link.c
+++ b/lib/dns/openssldsa_link.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: openssldsa_link.c,v 1.13.120.2 2009-01-14 23:47:26 tbox Exp $ */
+/* $Id: openssldsa_link.c,v 1.20 2011-01-11 23:47:13 tbox Exp $ */
#ifdef OPENSSL
#ifndef USE_EVP
@@ -313,15 +313,40 @@ openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
return (ISC_TRUE);
}
-static isc_result_t
-openssldsa_generate(dst_key_t *key, int unused) {
#if OPENSSL_VERSION_NUMBER > 0x00908000L
- BN_GENCB cb;
+static int
+progress_cb(int p, int n, BN_GENCB *cb)
+{
+ union {
+ void *dptr;
+ void (*fptr)(int);
+ } u;
+
+ UNUSED(n);
+
+ u.dptr = cb->arg;
+ if (u.fptr != NULL)
+ u.fptr(p);
+ return (1);
+}
#endif
+
+static isc_result_t
+openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
DSA *dsa;
unsigned char rand_array[ISC_SHA1_DIGESTLENGTH];
isc_result_t result;
+#if OPENSSL_VERSION_NUMBER > 0x00908000L
+ BN_GENCB cb;
+ union {
+ void *dptr;
+ void (*fptr)(int);
+ } u;
+
+#else
+ UNUSED(callback);
+#endif
UNUSED(unused);
result = dst__entropy_getdata(rand_array, sizeof(rand_array),
@@ -334,7 +359,12 @@ openssldsa_generate(dst_key_t *key, int unused) {
if (dsa == NULL)
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- BN_GENCB_set_old(&cb, NULL, NULL);
+ if (callback == NULL) {
+ BN_GENCB_set_old(&cb, NULL, NULL);
+ } else {
+ u.fptr = callback;
+ BN_GENCB_set(&cb, &progress_cb, u.dptr);
+ }
if (!DSA_generate_parameters_ex(dsa, key->key_size, rand_array,
ISC_SHA1_DIGESTLENGTH, NULL, NULL,
@@ -512,7 +542,7 @@ openssldsa_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-openssldsa_parse(dst_key_t *key, isc_lex_t *lexer) {
+openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
int i;
@@ -520,6 +550,7 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer) {
isc_mem_t *mctx = key->mctx;
#define DST_RET(a) {ret = a; goto err;}
+ UNUSED(pub);
/* read private key file */
ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv);
if (ret != ISC_R_SUCCESS)
@@ -587,6 +618,8 @@ static dst_func_t openssldsa_functions = {
openssldsa_parse,
NULL, /*%< cleanup */
NULL, /*%< fromlabel */
+ NULL, /*%< dump */
+ NULL, /*%< restore */
};
isc_result_t
diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c
new file mode 100644
index 000000000000..1b029db4bcb5
--- /dev/null
+++ b/lib/dns/opensslgost_link.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: opensslgost_link.c,v 1.5 2011-01-19 23:47:12 tbox Exp $ */
+
+#include <config.h>
+
+#ifdef HAVE_OPENSSL_GOST
+
+#include <isc/entropy.h>
+#include <isc/mem.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dst/result.h>
+
+#include "dst_internal.h"
+#include "dst_openssl.h"
+#include "dst_parse.h"
+
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/rsa.h>
+#include <openssl/engine.h>
+
+static ENGINE *e = NULL;
+static const EVP_MD *opensslgost_digest;
+extern const EVP_MD *EVP_gost(void);
+
+const EVP_MD *EVP_gost(void) {
+ return (opensslgost_digest);
+}
+
+#define DST_RET(a) {ret = a; goto err;}
+
+static isc_result_t opensslgost_todns(const dst_key_t *key,
+ isc_buffer_t *data);
+
+static isc_result_t
+opensslgost_createctx(dst_key_t *key, dst_context_t *dctx) {
+ EVP_MD_CTX *evp_md_ctx;
+ const EVP_MD *md = EVP_gost();
+
+ UNUSED(key);
+
+ if (md == NULL)
+ return (DST_R_OPENSSLFAILURE);
+
+ evp_md_ctx = EVP_MD_CTX_create();
+ if (evp_md_ctx == NULL)
+ return (ISC_R_NOMEMORY);
+
+ if (!EVP_DigestInit_ex(evp_md_ctx, md, NULL)) {
+ EVP_MD_CTX_destroy(evp_md_ctx);
+ return (ISC_R_FAILURE);
+ }
+ dctx->ctxdata.evp_md_ctx = evp_md_ctx;
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+opensslgost_destroyctx(dst_context_t *dctx) {
+ EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
+
+ if (evp_md_ctx != NULL) {
+ EVP_MD_CTX_destroy(evp_md_ctx);
+ dctx->ctxdata.evp_md_ctx = NULL;
+ }
+}
+
+static isc_result_t
+opensslgost_adddata(dst_context_t *dctx, const isc_region_t *data) {
+ EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
+
+ if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length))
+ return (ISC_R_FAILURE);
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+opensslgost_sign(dst_context_t *dctx, isc_buffer_t *sig) {
+ dst_key_t *key = dctx->key;
+ isc_region_t r;
+ unsigned int siglen = 0;
+ EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
+ EVP_PKEY *pkey = key->keydata.pkey;
+
+ isc_buffer_availableregion(sig, &r);
+
+ if (r.length < (unsigned int) EVP_PKEY_size(pkey))
+ return (ISC_R_NOSPACE);
+
+ if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey))
+ return (ISC_R_FAILURE);
+
+ isc_buffer_add(sig, siglen);
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) {
+ dst_key_t *key = dctx->key;
+ int status = 0;
+ EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
+ EVP_PKEY *pkey = key->keydata.pkey;
+
+ status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
+ if (status != 1)
+ return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_boolean_t
+opensslgost_compare(const dst_key_t *key1, const dst_key_t *key2) {
+ EVP_PKEY *pkey1, *pkey2;
+
+ pkey1 = key1->keydata.pkey;
+ pkey2 = key2->keydata.pkey;
+
+ if (pkey1 == NULL && pkey2 == NULL)
+ return (ISC_TRUE);
+ else if (pkey1 == NULL || pkey2 == NULL)
+ return (ISC_FALSE);
+
+ if (EVP_PKEY_cmp(pkey1, pkey2) != 1)
+ return (ISC_FALSE);
+ return (ISC_TRUE);
+}
+
+static int
+progress_cb(EVP_PKEY_CTX *ctx)
+{
+ union {
+ void *dptr;
+ void (*fptr)(int);
+ } u;
+ int p;
+
+ u.dptr = EVP_PKEY_CTX_get_app_data(ctx);
+ p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+ if (u.fptr != NULL)
+ u.fptr(p);
+ return (1);
+}
+
+static isc_result_t
+opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) {
+ EVP_PKEY_CTX *ctx;
+ union {
+ void *dptr;
+ void (*fptr)(int);
+ } u;
+ EVP_PKEY *pkey = NULL;
+
+ UNUSED(unused);
+ ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL);
+ if (ctx == NULL)
+ goto err;
+ if (callback != NULL) {
+ u.fptr = callback;
+ EVP_PKEY_CTX_set_app_data(ctx, u.dptr);
+ EVP_PKEY_CTX_set_cb(ctx, &progress_cb);
+ }
+ if (EVP_PKEY_keygen_init(ctx) <= 0)
+ goto err;
+ if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0)
+ goto err;
+ if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+ goto err;
+ key->keydata.pkey = pkey;
+ EVP_PKEY_CTX_free(ctx);
+ return (ISC_R_SUCCESS);
+
+err:
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+ if (ctx != NULL)
+ EVP_PKEY_CTX_free(ctx);
+ return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+}
+
+static isc_boolean_t
+opensslgost_isprivate(const dst_key_t *key) {
+ EVP_PKEY *pkey = key->keydata.pkey;
+ EC_KEY *ec;
+
+ INSIST(pkey != NULL);
+
+ ec = EVP_PKEY_get0(pkey);
+ return (ISC_TF(ec != NULL && EC_KEY_get0_private_key(ec) != NULL));
+}
+
+static void
+opensslgost_destroy(dst_key_t *key) {
+ EVP_PKEY *pkey = key->keydata.pkey;
+
+ EVP_PKEY_free(pkey);
+ key->keydata.pkey = NULL;
+}
+
+unsigned char gost_prefix[37] = {
+ 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
+ 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07,
+ 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06,
+ 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01,
+ 0x03, 0x43, 0x00, 0x04, 0x40
+};
+
+static isc_result_t
+opensslgost_todns(const dst_key_t *key, isc_buffer_t *data) {
+ EVP_PKEY *pkey;
+ isc_region_t r;
+ unsigned char der[37 + 64], *p;
+ int len;
+
+ REQUIRE(key->keydata.pkey != NULL);
+
+ pkey = key->keydata.pkey;
+
+ isc_buffer_availableregion(data, &r);
+ if (r.length < 64)
+ return (ISC_R_NOSPACE);
+
+ p = der;
+ len = i2d_PUBKEY(pkey, &p);
+ INSIST(len == sizeof(der));
+ INSIST(memcmp(gost_prefix, der, 37) == 0);
+ memcpy(r.base, der + 37, 64);
+ isc_buffer_add(data, 64);
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) {
+ isc_region_t r;
+ EVP_PKEY *pkey = NULL;
+ unsigned char der[37 + 64];
+ const unsigned char *p;
+
+ isc_buffer_remainingregion(data, &r);
+ if (r.length == 0)
+ return (ISC_R_SUCCESS);
+
+ if (r.length != 64)
+ return (DST_R_INVALIDPUBLICKEY);
+ memcpy(der, gost_prefix, 37);
+ memcpy(der + 37, r.base, 64);
+ isc_buffer_forward(data, 64);
+
+ p = der;
+ if (d2i_PUBKEY(&pkey, &p, (long) sizeof(der)) == NULL)
+ return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ key->keydata.pkey = pkey;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+opensslgost_tofile(const dst_key_t *key, const char *directory) {
+ EVP_PKEY *pkey;
+ dst_private_t priv;
+ isc_result_t result;
+ unsigned char *der, *p;
+ int len;
+
+ if (key->keydata.pkey == NULL)
+ return (DST_R_NULLKEY);
+
+ pkey = key->keydata.pkey;
+
+ len = i2d_PrivateKey(pkey, NULL);
+ der = isc_mem_get(key->mctx, (size_t) len);
+ if (der == NULL)
+ return (ISC_R_NOMEMORY);
+
+ p = der;
+ if (i2d_PrivateKey(pkey, &p) != len) {
+ result = dst__openssl_toresult(DST_R_OPENSSLFAILURE);
+ goto fail;
+ }
+
+ priv.elements[0].tag = TAG_GOST_PRIVASN1;
+ priv.elements[0].length = len;
+ priv.elements[0].data = der;
+ priv.nelements = GOST_NTAGS;
+
+ result = dst__privstruct_writefile(key, &priv, directory);
+ fail:
+ if (der != NULL)
+ isc_mem_put(key->mctx, der, (size_t) len);
+ return (result);
+}
+
+static isc_result_t
+opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
+ dst_private_t priv;
+ isc_result_t ret;
+ isc_mem_t *mctx = key->mctx;
+ EVP_PKEY *pkey = NULL;
+ const unsigned char *p;
+
+ UNUSED(pub);
+
+ /* read private key file */
+ ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv);
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+
+ INSIST(priv.elements[0].tag == TAG_GOST_PRIVASN1);
+ p = priv.elements[0].data;
+ if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
+ (long) priv.elements[0].length) == NULL)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+ key->keydata.pkey = pkey;
+ key->key_size = EVP_PKEY_bits(pkey);
+ dst__privstruct_free(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
+ return (ISC_R_SUCCESS);
+
+ err:
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+ opensslgost_destroy(key);
+ dst__privstruct_free(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
+ return (ret);
+}
+
+static void
+opensslgost_cleanup(void) {
+ if (e != NULL) {
+ ENGINE_finish(e);
+ ENGINE_free(e);
+ e = NULL;
+ }
+}
+
+static dst_func_t opensslgost_functions = {
+ opensslgost_createctx,
+ opensslgost_destroyctx,
+ opensslgost_adddata,
+ opensslgost_sign,
+ opensslgost_verify,
+ NULL, /*%< computesecret */
+ opensslgost_compare,
+ NULL, /*%< paramcompare */
+ opensslgost_generate,
+ opensslgost_isprivate,
+ opensslgost_destroy,
+ opensslgost_todns,
+ opensslgost_fromdns,
+ opensslgost_tofile,
+ opensslgost_parse,
+ opensslgost_cleanup,
+ NULL, /*%< fromlabel */
+ NULL, /*%< dump */
+ NULL /*%< restore */
+};
+
+isc_result_t
+dst__opensslgost_init(dst_func_t **funcp) {
+ REQUIRE(funcp != NULL);
+
+ /* check if the gost engine works properly */
+ e = ENGINE_by_id("gost");
+ if (e == NULL)
+ return (DST_R_OPENSSLFAILURE);
+ if (ENGINE_init(e) <= 0) {
+ ENGINE_free(e);
+ e = NULL;
+ return (DST_R_OPENSSLFAILURE);
+ }
+ /* better than to rely on digest_gost symbol */
+ opensslgost_digest = ENGINE_get_digest(e, NID_id_GostR3411_94);
+ /* from openssl.cnf */
+ if ((opensslgost_digest == NULL) ||
+ (ENGINE_register_pkey_asn1_meths(e) <= 0) ||
+ (ENGINE_ctrl_cmd_string(e,
+ "CRYPT_PARAMS",
+ "id-Gost28147-89-CryptoPro-A-ParamSet",
+ 0) <= 0)) {
+ ENGINE_finish(e);
+ ENGINE_free(e);
+ e = NULL;
+ return (DST_R_OPENSSLFAILURE);
+ }
+
+ if (*funcp == NULL)
+ *funcp = &opensslgost_functions;
+ return (ISC_R_SUCCESS);
+}
+
+#else /* HAVE_OPENSSL_GOST */
+
+#include <isc/util.h>
+
+EMPTY_TRANSLATION_UNIT
+
+#endif /* HAVE_OPENSSL_GOST */
+/*! \file */
diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c
index 1e3c5c2e12e7..fcdc9f06b8d9 100644
--- a/lib/dns/opensslrsa_link.c
+++ b/lib/dns/opensslrsa_link.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -17,7 +17,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: opensslrsa_link.c,v 1.20.50.8 2010-01-22 02:36:49 marka Exp $
+ * $Id: opensslrsa_link.c,v 1.39 2011-01-11 23:47:13 tbox Exp $
*/
#ifdef OPENSSL
#include <config.h>
@@ -30,6 +30,7 @@
#endif
#endif
+
#include <isc/entropy.h>
#include <isc/md5.h>
#include <isc/sha1.h>
@@ -368,7 +369,7 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
RSA *rsa = key->keydata.rsa;
/* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
unsigned char digest[PREFIXLEN + ISC_SHA512_DIGESTLENGTH];
- int status = 0;
+ int status;
int type = 0;
unsigned int digestlen = 0;
char *message;
@@ -703,10 +704,32 @@ opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
return (ISC_TRUE);
}
+#if OPENSSL_VERSION_NUMBER > 0x00908000L
+static int
+progress_cb(int p, int n, BN_GENCB *cb)
+{
+ union {
+ void *dptr;
+ void (*fptr)(int);
+ } u;
+
+ UNUSED(n);
+
+ u.dptr = cb->arg;
+ if (u.fptr != NULL)
+ u.fptr(p);
+ return (1);
+}
+#endif
+
static isc_result_t
-opensslrsa_generate(dst_key_t *key, int exp) {
+opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) {
#if OPENSSL_VERSION_NUMBER > 0x00908000L
BN_GENCB cb;
+ union {
+ void *dptr;
+ void (*fptr)(int);
+ } u;
RSA *rsa = RSA_new();
BIGNUM *e = BN_new();
#if USE_EVP
@@ -732,7 +755,12 @@ opensslrsa_generate(dst_key_t *key, int exp) {
BN_set_bit(e, 32);
}
- BN_GENCB_set_old(&cb, NULL, NULL);
+ if (callback == NULL) {
+ BN_GENCB_set_old(&cb, NULL, NULL);
+ } else {
+ u.fptr = callback;
+ BN_GENCB_set(&cb, &progress_cb, u.dptr);
+ }
if (RSA_generate_key_ex(rsa, key->key_size, e, &cb)) {
BN_free(e);
@@ -763,8 +791,12 @@ err:
#if USE_EVP
EVP_PKEY *pkey = EVP_PKEY_new();
+ UNUSED(callback);
+
if (pkey == NULL)
return (ISC_R_NOMEMORY);
+#else
+ UNUSED(callback);
#endif
if (exp == 0)
@@ -1059,8 +1091,9 @@ opensslrsa_tofile(const dst_key_t *key, const char *directory) {
i++;
}
+
priv.nelements = i;
- result = dst__privstruct_writefile(key, &priv, directory);
+ result = dst__privstruct_writefile(key, &priv, directory);
fail:
#if USE_EVP
RSA_free(rsa);
@@ -1074,16 +1107,52 @@ opensslrsa_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
-opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
+rsa_check(RSA *rsa, RSA *pub)
+{
+ /* Public parameters should be the same but if they are not set
+ * copy them from the public key. */
+ if (pub != NULL) {
+ if (rsa->n != NULL) {
+ if (BN_cmp(rsa->n, pub->n) != 0)
+ return (DST_R_INVALIDPRIVATEKEY);
+ } else {
+ rsa->n = pub->n;
+ pub->n = NULL;
+ }
+ if (rsa->e != NULL) {
+ if (BN_cmp(rsa->e, pub->e) != 0)
+ return (DST_R_INVALIDPRIVATEKEY);
+ } else {
+ rsa->e = pub->e;
+ pub->e = NULL;
+ }
+ }
+ if (rsa->n == NULL || rsa->e == NULL)
+ return (DST_R_INVALIDPRIVATEKEY);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
int i;
- RSA *rsa = NULL;
+ RSA *rsa = NULL, *pubrsa = NULL;
ENGINE *e = NULL;
isc_mem_t *mctx = key->mctx;
- const char *name = NULL, *label = NULL;
+ const char *engine = NULL, *label = NULL;
EVP_PKEY *pkey = NULL;
+#if USE_EVP
+ if (pub != NULL && pub->keydata.pkey != NULL)
+ pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey);
+#else
+ if (pub != NULL && pub->keydata.rsa != NULL) {
+ pubrsa = pub->keydata.rsa;
+ pub->keydata.rsa = NULL;
+ }
+#endif
+
/* read private key file */
ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
if (ret != ISC_R_SUCCESS)
@@ -1092,7 +1161,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
for (i = 0; i < priv.nelements; i++) {
switch (priv.elements[i].tag) {
case TAG_RSA_ENGINE:
- name = (char *)priv.elements[i].data;
+ engine = (char *)priv.elements[i].data;
break;
case TAG_RSA_LABEL:
label = (char *)priv.elements[i].data;
@@ -1105,10 +1174,10 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
* Is this key is stored in a HSM?
* See if we can fetch it.
*/
- if (name != NULL || label != NULL) {
- INSIST(name != NULL);
- INSIST(label != NULL);
- e = dst__openssl_getengine(name);
+ if (label != NULL) {
+ if (engine == NULL)
+ DST_RET(DST_R_NOENGINE);
+ e = dst__openssl_getengine(engine);
if (e == NULL)
DST_RET(DST_R_NOENGINE);
pkey = ENGINE_load_private_key(e, label, NULL, NULL);
@@ -1116,22 +1185,29 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
/* ERR_print_errors_fp(stderr); */
DST_RET(ISC_R_NOTFOUND);
}
- key->engine = isc_mem_strdup(key->mctx, name);
+ key->engine = isc_mem_strdup(key->mctx, engine);
if (key->engine == NULL)
DST_RET(ISC_R_NOMEMORY);
key->label = isc_mem_strdup(key->mctx, label);
if (key->label == NULL)
DST_RET(ISC_R_NOMEMORY);
+ rsa = EVP_PKEY_get1_RSA(pkey);
+ if (rsa == NULL)
+ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+ if (pubrsa != NULL)
+ RSA_free(pubrsa);
key->key_size = EVP_PKEY_bits(pkey);
#if USE_EVP
key->keydata.pkey = pkey;
+ RSA_free(rsa);
#else
- key->keydata.rsa = EVP_PKEY_get1_RSA(pkey);
- if (rsa == NULL)
- DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ key->keydata.rsa = rsa;
EVP_PKEY_free(pkey);
#endif
dst__privstruct_free(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
return (ISC_R_SUCCESS);
}
@@ -1144,9 +1220,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
pkey = EVP_PKEY_new();
if (pkey == NULL)
DST_RET(ISC_R_NOMEMORY);
- if (!EVP_PKEY_set1_RSA(pkey, rsa)) {
+ if (!EVP_PKEY_set1_RSA(pkey, rsa))
DST_RET(ISC_R_FAILURE);
- }
key->keydata.pkey = pkey;
#else
key->keydata.rsa = rsa;
@@ -1196,8 +1271,13 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
}
}
dst__privstruct_free(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
+ if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
key->key_size = BN_num_bits(rsa->n);
+ if (pubrsa != NULL)
+ RSA_free(pubrsa);
#if USE_EVP
RSA_free(rsa);
#endif
@@ -1211,6 +1291,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
#endif
if (rsa != NULL)
RSA_free(rsa);
+ if (pubrsa != NULL)
+ RSA_free(pubrsa);
opensslrsa_destroy(key);
dst__privstruct_free(&priv, mctx);
memset(&priv, 0, sizeof(priv));
@@ -1224,33 +1306,63 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
ENGINE *e = NULL;
isc_result_t ret;
EVP_PKEY *pkey = NULL;
+ RSA *rsa = NULL, *pubrsa = NULL;
+ char *colon;
UNUSED(pin);
+ if (engine == NULL)
+ DST_RET(DST_R_NOENGINE);
e = dst__openssl_getengine(engine);
if (e == NULL)
DST_RET(DST_R_NOENGINE);
+ pkey = ENGINE_load_public_key(e, label, NULL, NULL);
+ if (pkey != NULL) {
+ pubrsa = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (pubrsa == NULL)
+ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ }
pkey = ENGINE_load_private_key(e, label, NULL, NULL);
if (pkey == NULL)
DST_RET(ISC_R_NOTFOUND);
- key->engine = isc_mem_strdup(key->mctx, label);
- if (key->engine == NULL)
- DST_RET(ISC_R_NOMEMORY);
+ if (engine != NULL) {
+ key->engine = isc_mem_strdup(key->mctx, engine);
+ if (key->engine == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+ } else {
+ key->engine = isc_mem_strdup(key->mctx, label);
+ if (key->engine == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+ colon = strchr(key->engine, ':');
+ if (colon != NULL)
+ *colon = '\0';
+ }
key->label = isc_mem_strdup(key->mctx, label);
if (key->label == NULL)
DST_RET(ISC_R_NOMEMORY);
+ rsa = EVP_PKEY_get1_RSA(pkey);
+ if (rsa == NULL)
+ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+ if (pubrsa != NULL)
+ RSA_free(pubrsa);
key->key_size = EVP_PKEY_bits(pkey);
#if USE_EVP
key->keydata.pkey = pkey;
+ RSA_free(rsa);
#else
- key->keydata.rsa = EVP_PKEY_get1_RSA(pkey);
+ key->keydata.rsa = rsa;
EVP_PKEY_free(pkey);
- if (key->keydata.rsa == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
#endif
return (ISC_R_SUCCESS);
err:
+ if (rsa != NULL)
+ RSA_free(rsa);
+ if (pubrsa != NULL)
+ RSA_free(pubrsa);
if (pkey != NULL)
EVP_PKEY_free(pkey);
return (ret);
@@ -1274,6 +1386,8 @@ static dst_func_t opensslrsa_functions = {
opensslrsa_parse,
NULL, /*%< cleanup */
opensslrsa_fromlabel,
+ NULL, /*%< dump */
+ NULL, /*%< restore */
};
isc_result_t
diff --git a/lib/dns/peer.c b/lib/dns/peer.c
index 1e81023c59ef..3851c3e9e95e 100644
--- a/lib/dns/peer.c
+++ b/lib/dns/peer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: peer.c,v 1.31 2008-04-03 06:09:04 tbox Exp $ */
+/* $Id: peer.c,v 1.33 2009-09-02 23:48:02 tbox Exp $ */
/*! \file */
@@ -536,7 +536,7 @@ dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) {
isc_buffer_init(&b, keyval, strlen(keyval));
isc_buffer_add(&b, strlen(keyval));
result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
diff --git a/lib/dns/private.c b/lib/dns/private.c
new file mode 100644
index 000000000000..ba3e8ed3be4c
--- /dev/null
+++ b/lib/dns/private.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: private.c,v 1.3 2009-10-09 23:48:09 tbox Exp $ */
+
+#include "config.h"
+
+#include <isc/result.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/base64.h>
+
+#include <dns/nsec3.h>
+#include <dns/private.h>
+
+/*
+ * We need to build the relevant chain if there exists a NSEC/NSEC3PARAM
+ * at the apex; normally only one or the other of NSEC/NSEC3PARAM will exist.
+ *
+ * If a NSEC3PARAM RRset exists then we will need to build a NSEC chain
+ * if all the NSEC3PARAM records (and associated chains) are slated for
+ * destruction and we have not been told to NOT build the NSEC chain.
+ *
+ * If the NSEC set exist then check to see if there is a request to create
+ * a NSEC3 chain.
+ *
+ * If neither NSEC/NSEC3PARAM RRsets exist at the origin and the private
+ * type exists then we need to examine it to determine if NSEC3 chain has
+ * been requested to be built otherwise a NSEC chain needs to be built.
+ */
+
+#define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
+#define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
+#define NONSEC(x) (((x) & DNS_NSEC3FLAG_NONSEC) != 0)
+
+#define CHECK(x) do { \
+ result = (x); \
+ if (result != ISC_R_SUCCESS) \
+ goto failure; \
+ } while (0)
+
+/*
+ * Work out if 'param' should be ignored or not (i.e. it is in the process
+ * of being removed).
+ *
+ * Note: we 'belt-and-braces' here by also checking for a CREATE private
+ * record and keep the param record in this case.
+ */
+
+static isc_boolean_t
+ignore(dns_rdata_t *param, dns_rdataset_t *privateset) {
+ isc_result_t result;
+
+ for (result = dns_rdataset_first(privateset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(privateset)) {
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ dns_rdata_t private = DNS_RDATA_INIT;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(privateset, &private);
+ if (!dns_nsec3param_fromprivate(&private, &rdata,
+ buf, sizeof(buf)))
+ continue;
+ /*
+ * We are going to create a new NSEC3 chain so it
+ * doesn't matter if we are removing this one.
+ */
+ if (CREATE(rdata.data[1]))
+ return (ISC_FALSE);
+ if (rdata.data[0] != param->data[0] ||
+ rdata.data[2] != param->data[2] ||
+ rdata.data[3] != param->data[3] ||
+ rdata.data[4] != param->data[4] ||
+ memcmp(&rdata.data[5], &param->data[5], param->data[4]))
+ continue;
+ /*
+ * The removal of this NSEC3 chain does NOT cause a
+ * NSEC chain to be created so we don't need to tell
+ * the caller that it will be removed.
+ */
+ if (NONSEC(rdata.data[1]))
+ return (ISC_FALSE);
+ return (ISC_TRUE);
+ }
+ return (ISC_FALSE);
+}
+
+isc_result_t
+dns_private_chains(dns_db_t *db, dns_dbversion_t *ver,
+ dns_rdatatype_t privatetype,
+ isc_boolean_t *build_nsec, isc_boolean_t *build_nsec3)
+{
+ dns_dbnode_t *node;
+ dns_rdataset_t nsecset, nsec3paramset, privateset;
+ isc_boolean_t nsec3chain;
+ isc_boolean_t signing;
+ isc_result_t result;
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ unsigned int count;
+
+ node = NULL;
+ dns_rdataset_init(&nsecset);
+ dns_rdataset_init(&nsec3paramset);
+ dns_rdataset_init(&privateset);
+
+ CHECK(dns_db_getoriginnode(db, &node));
+
+ result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
+ 0, (isc_stdtime_t) 0, &nsecset, NULL);
+
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
+ goto failure;
+
+ result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
+ 0, (isc_stdtime_t) 0, &nsec3paramset,
+ NULL);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
+ goto failure;
+
+ if (dns_rdataset_isassociated(&nsecset) &&
+ dns_rdataset_isassociated(&nsec3paramset)) {
+ if (build_nsec != NULL)
+ *build_nsec = ISC_TRUE;
+ if (build_nsec3 != NULL)
+ *build_nsec3 = ISC_TRUE;
+ goto success;
+ }
+
+ if (privatetype != (dns_rdatatype_t)0) {
+ result = dns_db_findrdataset(db, node, ver, privatetype,
+ 0, (isc_stdtime_t) 0,
+ &privateset, NULL);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
+ goto failure;
+ }
+
+ /*
+ * Look to see if we also need to be creating a NSEC3 chains.
+ */
+ if (dns_rdataset_isassociated(&nsecset)) {
+ if (build_nsec != NULL)
+ *build_nsec = ISC_TRUE;
+ if (build_nsec3 != NULL)
+ *build_nsec3 = ISC_FALSE;
+ if (!dns_rdataset_isassociated(&privateset))
+ goto success;
+ for (result = dns_rdataset_first(&privateset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&privateset)) {
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ dns_rdata_t private = DNS_RDATA_INIT;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&privateset, &private);
+ if (!dns_nsec3param_fromprivate(&private, &rdata,
+ buf, sizeof(buf)))
+ continue;
+ if (REMOVE(rdata.data[1]))
+ continue;
+ if (build_nsec3 != NULL)
+ *build_nsec3 = ISC_TRUE;
+ break;
+ }
+ goto success;
+ }
+
+ if (dns_rdataset_isassociated(&nsec3paramset)) {
+ if (build_nsec3 != NULL)
+ *build_nsec3 = ISC_TRUE;
+ if (build_nsec != NULL)
+ *build_nsec = ISC_FALSE;
+ if (!dns_rdataset_isassociated(&privateset))
+ goto success;
+ /*
+ * If we are in the process of building a new NSEC3 chain
+ * then we don't need to build a NSEC chain.
+ */
+ for (result = dns_rdataset_first(&privateset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&privateset)) {
+ dns_rdata_t private = DNS_RDATA_INIT;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&privateset, &private);
+ if (!dns_nsec3param_fromprivate(&private, &rdata,
+ buf, sizeof(buf)))
+ continue;
+ if (CREATE(rdata.data[1]))
+ goto success;
+ }
+
+ /*
+ * Check to see if there will be a active NSEC3CHAIN once
+ * the changes queued complete.
+ */
+ count = 0;
+ for (result = dns_rdataset_first(&nsec3paramset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&nsec3paramset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ /*
+ * If there is more that one NSEC3 chain present then
+ * we don't need to construct a NSEC chain.
+ */
+ if (++count > 1)
+ goto success;
+ dns_rdataset_current(&nsec3paramset, &rdata);
+ if (ignore(&rdata, &privateset))
+ continue;
+ /*
+ * We still have a good NSEC3 chain or we are
+ * not creating a NSEC chain as NONSEC is set.
+ */
+ goto success;
+ }
+
+ /*
+ * The last NSEC3 chain is being removed and does not have
+ * have NONSEC set.
+ */
+ if (build_nsec != NULL)
+ *build_nsec = ISC_TRUE;
+ goto success;
+ }
+
+ if (build_nsec != NULL)
+ *build_nsec = ISC_FALSE;
+ if (build_nsec3 != NULL)
+ *build_nsec3 = ISC_FALSE;
+ if (!dns_rdataset_isassociated(&privateset))
+ goto success;
+
+ signing = ISC_FALSE;
+ nsec3chain = ISC_FALSE;
+
+ for (result = dns_rdataset_first(&privateset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&privateset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_t private = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&privateset, &private);
+ if (!dns_nsec3param_fromprivate(&private, &rdata,
+ buf, sizeof(buf))) {
+ /*
+ * Look for record that says we are signing the
+ * zone with a key.
+ */
+ if (private.length == 5 && private.data[0] != 0 &&
+ private.data[3] == 0 && private.data[4] == 0)
+ signing = ISC_TRUE;
+ } else {
+ if (CREATE(rdata.data[1]))
+ nsec3chain = ISC_TRUE;
+ }
+ }
+
+ if (signing) {
+ if (nsec3chain) {
+ if (build_nsec3 != NULL)
+ *build_nsec3 = ISC_TRUE;
+ } else {
+ if (build_nsec != NULL)
+ *build_nsec = ISC_TRUE;
+ }
+ }
+
+ success:
+ result = ISC_R_SUCCESS;
+ failure:
+ if (dns_rdataset_isassociated(&nsecset))
+ dns_rdataset_disassociate(&nsecset);
+ if (dns_rdataset_isassociated(&nsec3paramset))
+ dns_rdataset_disassociate(&nsec3paramset);
+ if (dns_rdataset_isassociated(&privateset))
+ dns_rdataset_disassociate(&privateset);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ return (result);
+}
diff --git a/lib/dns/rbt.c b/lib/dns/rbt.c
index 5e09db3374e3..6c14e8e702a0 100644
--- a/lib/dns/rbt.c
+++ b/lib/dns/rbt.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbt.c,v 1.142.50.3 2009-10-20 05:06:04 marka Exp $ */
+/* $Id: rbt.c,v 1.146 2009-10-27 04:46:58 marka Exp $ */
/*! \file */
@@ -537,7 +537,10 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
* current node.
*/
new_current->is_root = current->is_root;
- new_current->nsec3 = current->nsec3;
+ if (current->nsec == DNS_RBT_NSEC_HAS_NSEC)
+ new_current->nsec = DNS_RBT_NSEC_NORMAL;
+ else
+ new_current->nsec = current->nsec;
PARENT(new_current) = PARENT(current);
LEFT(new_current) = LEFT(current);
RIGHT(new_current) = RIGHT(current);
@@ -1451,7 +1454,7 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) {
DIRTY(node) = 0;
dns_rbtnode_refinit(node, 0);
node->find_callback = 0;
- node->nsec3 = 0;
+ node->nsec = DNS_RBT_NSEC_NORMAL;
MAKE_BLACK(node);
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 87b70e376e05..d4415d8906d6 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.270.12.26.4.1 2011-06-21 20:13:23 each Exp $ */
+/* $Id: rbtdb.c,v 1.310.8.1.2.1 2011-06-21 20:15:48 each Exp $ */
/*! \file */
@@ -53,6 +53,7 @@
#include <dns/nsec.h>
#include <dns/nsec3.h>
#include <dns/rbt.h>
+#include <dns/rpz.h>
#include <dns/rdata.h>
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
@@ -441,7 +442,9 @@ typedef struct {
/* Locked by tree_lock. */
dns_rbt_t * tree;
+ dns_rbt_t * nsec;
dns_rbt_t * nsec3;
+ dns_rpz_cidr_t * rpz_cidr;
/* Unlocked */
unsigned int quantum;
@@ -621,8 +624,9 @@ typedef struct rbtdb_dbiterator {
static void free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log,
isc_event_t *event);
static void overmem(dns_db_t *db, isc_boolean_t overmem);
-static void setnsec3parameters(dns_db_t *db, rbtdb_version_t *version,
- isc_boolean_t *nsec3createflag);
+#ifdef BIND9
+static void setnsec3parameters(dns_db_t *db, rbtdb_version_t *version);
+#endif
/*%
* 'init_count' is used to initialize 'newheader->count' which inturn
@@ -830,6 +834,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
isc_ondestroy_t ondest;
isc_result_t result;
char buf[DNS_NAME_FORMATSIZE];
+ dns_rbt_t **treep;
isc_time_t start;
if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in)
@@ -866,33 +871,26 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
if (event == NULL)
rbtdb->quantum = (rbtdb->task != NULL) ? 100 : 0;
- again:
- if (rbtdb->tree != NULL) {
- isc_time_now(&start);
- result = dns_rbt_destroy2(&rbtdb->tree, rbtdb->quantum);
- if (result == ISC_R_QUOTA) {
- INSIST(rbtdb->task != NULL);
- if (rbtdb->quantum != 0)
- rbtdb->quantum = adjust_quantum(rbtdb->quantum,
- &start);
- if (event == NULL)
- event = isc_event_allocate(rbtdb->common.mctx,
- NULL,
- DNS_EVENT_FREESTORAGE,
- free_rbtdb_callback,
- rbtdb,
- sizeof(isc_event_t));
- if (event == NULL)
- goto again;
- isc_task_send(rbtdb->task, &event);
- return;
+
+ for (;;) {
+ /*
+ * pick the next tree to (start to) destroy
+ */
+ treep = &rbtdb->tree;
+ if (*treep == NULL) {
+ treep = &rbtdb->nsec;
+ if (*treep == NULL) {
+ treep = &rbtdb->nsec3;
+ /*
+ * we're finished after clear cutting
+ */
+ if (*treep == NULL)
+ break;
+ }
}
- INSIST(result == ISC_R_SUCCESS && rbtdb->tree == NULL);
- }
- if (rbtdb->nsec3 != NULL) {
isc_time_now(&start);
- result = dns_rbt_destroy2(&rbtdb->nsec3, rbtdb->quantum);
+ result = dns_rbt_destroy2(treep, rbtdb->quantum);
if (result == ISC_R_QUOTA) {
INSIST(rbtdb->task != NULL);
if (rbtdb->quantum != 0)
@@ -906,11 +904,11 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
rbtdb,
sizeof(isc_event_t));
if (event == NULL)
- goto again;
+ continue;
isc_task_send(rbtdb->task, &event);
return;
}
- INSIST(result == ISC_R_SUCCESS && rbtdb->nsec3 == NULL);
+ INSIST(result == ISC_R_SUCCESS && *treep == NULL);
}
if (event != NULL)
@@ -965,6 +963,11 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
if (rbtdb->rrsetstats != NULL)
dns_stats_detach(&rbtdb->rrsetstats);
+#ifdef BIND9
+ if (rbtdb->rpz_cidr != NULL)
+ dns_rpz_cidr_free(&rbtdb->rpz_cidr);
+#endif
+
isc_mem_put(rbtdb->common.mctx, rbtdb->node_locks,
rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t));
isc_rwlock_destroy(&rbtdb->tree_lock);
@@ -1488,6 +1491,82 @@ clean_zone_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
node->dirty = 0;
}
+static void
+delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node)
+{
+ dns_rbtnode_t *nsecnode;
+ dns_fixedname_t fname;
+ dns_name_t *name;
+ isc_result_t result = ISC_R_UNEXPECTED;
+
+ INSIST(!ISC_LINK_LINKED(node, deadlink));
+
+ switch (node->nsec) {
+ case DNS_RBT_NSEC_NORMAL:
+#ifdef BIND9
+ if (rbtdb->rpz_cidr != NULL) {
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_rbt_fullnamefromnode(node, name);
+ dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name);
+ }
+#endif
+ result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE);
+ break;
+ case DNS_RBT_NSEC_HAS_NSEC:
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_rbt_fullnamefromnode(node, name);
+ /*
+ * Delete the corresponding node from the auxiliary NSEC
+ * tree before deleting from the main tree.
+ */
+ nsecnode = NULL;
+ result = dns_rbt_findnode(rbtdb->nsec, name, NULL, &nsecnode,
+ NULL, DNS_RBTFIND_EMPTYDATA,
+ NULL, NULL);
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_CACHE, ISC_LOG_WARNING,
+ "delete_node: "
+ "dns_rbt_findnode(nsec): %s",
+ isc_result_totext(result));
+ } else {
+ result = dns_rbt_deletenode(rbtdb->nsec, nsecnode,
+ ISC_FALSE);
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx,
+ DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_CACHE,
+ ISC_LOG_WARNING,
+ "delete_nsecnode(): "
+ "dns_rbt_deletenode(nsecnode): %s",
+ isc_result_totext(result));
+ }
+ }
+ result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE);
+#ifdef BIND9
+ dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name);
+#endif
+ break;
+ case DNS_RBT_NSEC_NSEC:
+ result = dns_rbt_deletenode(rbtdb->nsec, node, ISC_FALSE);
+ break;
+ case DNS_RBT_NSEC_NSEC3:
+ result = dns_rbt_deletenode(rbtdb->nsec3, node, ISC_FALSE);
+ break;
+ }
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx,
+ DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_CACHE,
+ ISC_LOG_WARNING,
+ "delete_nsecnode(): "
+ "dns_rbt_deletenode: %s",
+ isc_result_totext(result));
+ }
+}
+
/*%
* Clean up dead nodes. These are nodes which have no references, and
* have no data. They are dead but we could not or chose not to delete
@@ -1499,7 +1578,6 @@ clean_zone_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
static void
cleanup_dead_nodes(dns_rbtdb_t *rbtdb, int bucketnum) {
dns_rbtnode_t *node;
- isc_result_t result;
int count = 10; /* XXXJT: should be adjustable */
node = ISC_LIST_HEAD(rbtdb->deadnodes[bucketnum]);
@@ -1513,19 +1591,8 @@ cleanup_dead_nodes(dns_rbtdb_t *rbtdb, int bucketnum) {
INSIST(dns_rbtnode_refcurrent(node) == 0 &&
node->data == NULL);
- INSIST(!ISC_LINK_LINKED(node, deadlink));
- if (node->nsec3)
- result = dns_rbt_deletenode(rbtdb->nsec3, node,
- ISC_FALSE);
- else
- result = dns_rbt_deletenode(rbtdb->tree, node,
- ISC_FALSE);
- if (result != ISC_R_SUCCESS)
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE, ISC_LOG_WARNING,
- "cleanup_dead_nodes: "
- "dns_rbt_deletenode: %s",
- isc_result_totext(result));
+ delete_node(rbtdb, node);
+
node = ISC_LIST_HEAD(rbtdb->deadnodes[bucketnum]);
count--;
}
@@ -1774,22 +1841,7 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
sizeof(printname)));
}
- INSIST(!ISC_LINK_LINKED(node, deadlink));
- if (node->nsec3)
- result = dns_rbt_deletenode(rbtdb->nsec3, node,
- ISC_FALSE);
- else
- result = dns_rbt_deletenode(rbtdb->tree, node,
- ISC_FALSE);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx,
- DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE,
- ISC_LOG_WARNING,
- "decrement_reference: "
- "dns_rbt_deletenode: %s",
- isc_result_totext(result));
- }
+ delete_node(rbtdb, node);
}
} else if (dns_rbtnode_refcurrent(node) == 0) {
INSIST(!ISC_LINK_LINKED(node, deadlink));
@@ -1925,13 +1977,17 @@ cleanup_nondirty(rbtdb_version_t *version, rbtdb_changedlist_t *cleanup_list) {
static void
iszonesecure(dns_db_t *db, rbtdb_version_t *version, dns_dbnode_t *origin) {
+#ifndef BIND9
+ UNUSED(db);
+ UNUSED(version);
+ UNUSED(origin);
+
+ return;
+#else
dns_rdataset_t keyset;
dns_rdataset_t nsecset, signsecset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
isc_boolean_t haszonekey = ISC_FALSE;
isc_boolean_t hasnsec = ISC_FALSE;
- isc_boolean_t hasoptbit = ISC_FALSE;
- isc_boolean_t nsec3createflag = ISC_FALSE;
isc_result_t result;
dns_rdataset_init(&keyset);
@@ -1963,41 +2019,30 @@ iszonesecure(dns_db_t *db, rbtdb_version_t *version, dns_dbnode_t *origin) {
if (result == ISC_R_SUCCESS) {
if (dns_rdataset_isassociated(&signsecset)) {
hasnsec = ISC_TRUE;
- result = dns_rdataset_first(&nsecset);
- if (result == ISC_R_SUCCESS) {
- dns_rdataset_current(&nsecset, &rdata);
- hasoptbit = dns_nsec_typepresent(&rdata,
- dns_rdatatype_opt);
- }
dns_rdataset_disassociate(&signsecset);
}
dns_rdataset_disassociate(&nsecset);
}
- setnsec3parameters(db, version, &nsec3createflag);
+ setnsec3parameters(db, version);
/*
* Do we have a valid NSEC/NSEC3 chain?
*/
- if (version->havensec3 || (hasnsec && !hasoptbit))
+ if (version->havensec3 || hasnsec)
version->secure = dns_db_secure;
- /*
- * Do we have a NSEC/NSEC3 chain under creation?
- */
- else if (hasoptbit || nsec3createflag)
- version->secure = dns_db_partial;
else
version->secure = dns_db_insecure;
+#endif
}
/*%<
* Walk the origin node looking for NSEC3PARAM records.
* Cache the nsec3 parameters.
*/
+#ifdef BIND9
static void
-setnsec3parameters(dns_db_t *db, rbtdb_version_t *version,
- isc_boolean_t *nsec3createflag)
-{
+setnsec3parameters(dns_db_t *db, rbtdb_version_t *version) {
dns_rbtnode_t *node;
dns_rdata_nsec3param_t nsec3param;
dns_rdata_t rdata = DNS_RDATA_INIT;
@@ -2028,7 +2073,7 @@ setnsec3parameters(dns_db_t *db, rbtdb_version_t *version,
} while (header != NULL);
if (header != NULL &&
- header->type == dns_rdatatype_nsec3param) {
+ (header->type == dns_rdatatype_nsec3param)) {
/*
* Find A NSEC3PARAM with a supported algorithm.
*/
@@ -2063,17 +2108,8 @@ setnsec3parameters(dns_db_t *db, rbtdb_version_t *version,
!dns_nsec3_supportedhash(nsec3param.hash))
continue;
-#ifdef RFC5155_STRICT
if (nsec3param.flags != 0)
continue;
-#else
- if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE)
- != 0)
- *nsec3createflag = ISC_TRUE;
- if ((nsec3param.flags & ~DNS_NSEC3FLAG_OPTOUT)
- != 0)
- continue;
-#endif
memcpy(version->salt, nsec3param.salt,
nsec3param.salt_length);
@@ -2096,6 +2132,7 @@ setnsec3parameters(dns_db_t *db, rbtdb_version_t *version,
isc_rwlocktype_read);
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
}
+#endif
static void
cleanup_dead_nodes_callback(isc_task_t *task, isc_event_t *event) {
@@ -2415,7 +2452,8 @@ add_wildcard_magic(dns_rbtdb_t *rbtdb, dns_name_t *name) {
result = dns_rbt_addnode(rbtdb->tree, &foundname, &node);
if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS)
return (result);
- node->nsec3 = 0;
+ if (result == ISC_R_SUCCESS)
+ node->nsec = DNS_RBT_NSEC_NORMAL;
node->find_callback = 1;
node->wild = 1;
return (ISC_R_SUCCESS);
@@ -2443,7 +2481,8 @@ add_empty_wildcards(dns_rbtdb_t *rbtdb, dns_name_t *name) {
&node);
if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS)
return (result);
- node->nsec3 = 0;
+ if (result == ISC_R_SUCCESS)
+ node->nsec = DNS_RBT_NSEC_NORMAL;
}
i++;
}
@@ -2482,6 +2521,17 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
node = NULL;
result = dns_rbt_addnode(rbtdb->tree, name, &node);
if (result == ISC_R_SUCCESS) {
+#ifdef BIND9
+ if (rbtdb->rpz_cidr != NULL) {
+ dns_fixedname_t fnamef;
+ dns_name_t *fname;
+
+ dns_fixedname_init(&fnamef);
+ fname = dns_fixedname_name(&fnamef);
+ dns_rbt_fullnamefromnode(node, fname);
+ dns_rpz_cidr_addip(rbtdb->rpz_cidr, fname);
+ }
+#endif
dns_rbt_namefromnode(node, &nodename);
#ifdef DNS_RBT_USEHASH
node->locknum = node->hashval % rbtdb->node_lock_count;
@@ -2489,7 +2539,6 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
node->locknum = dns_name_hash(&nodename, ISC_TRUE) %
rbtdb->node_lock_count;
#endif
- node->nsec3 = 0;
add_empty_wildcards(rbtdb, name);
if (dns_name_iswildcard(name)) {
@@ -2551,13 +2600,14 @@ findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
node->locknum = dns_name_hash(&nodename, ISC_TRUE) %
rbtdb->node_lock_count;
#endif
- node->nsec3 = 1U;
+ node->nsec = DNS_RBT_NSEC_NSEC3;
} else if (result != ISC_R_EXISTS) {
RWUNLOCK(&rbtdb->tree_lock, locktype);
return (result);
}
- } else
- INSIST(node->nsec3);
+ } else {
+ INSIST(node->nsec == DNS_RBT_NSEC_NSEC3);
+ }
NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
new_reference(rbtdb, node);
NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
@@ -3268,13 +3318,125 @@ matchparams(rdatasetheader_t *header, rbtdb_search_t *search)
* Find node of the NSEC/NSEC3 record that is 'name'.
*/
static inline isc_result_t
+previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search,
+ dns_name_t *name, dns_name_t *origin,
+ dns_rbtnode_t **nodep, dns_rbtnodechain_t *nsecchain,
+ isc_boolean_t *firstp)
+{
+ dns_fixedname_t ftarget;
+ dns_name_t *target;
+ dns_rbtnode_t *nsecnode;
+ isc_result_t result;
+
+ REQUIRE(nodep != NULL && *nodep == NULL);
+
+ if (type == dns_rdatatype_nsec3) {
+ result = dns_rbtnodechain_prev(&search->chain, NULL, NULL);
+ if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
+ return (result);
+ result = dns_rbtnodechain_current(&search->chain, name, origin,
+ nodep);
+ return (result);
+ }
+
+ dns_fixedname_init(&ftarget);
+ target = dns_fixedname_name(&ftarget);
+
+ for (;;) {
+ if (*firstp) {
+ /*
+ * Construct the name of the second node to check.
+ * It is the first node sought in the NSEC tree.
+ */
+ *firstp = ISC_FALSE;
+ dns_rbtnodechain_init(nsecchain, NULL);
+ result = dns_name_concatenate(name, origin,
+ target, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ nsecnode = NULL;
+ result = dns_rbt_findnode(search->rbtdb->nsec,
+ target, NULL,
+ &nsecnode, nsecchain,
+ DNS_RBTFIND_NOOPTIONS,
+ NULL, NULL);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * Since this was the first loop, finding the
+ * name in the NSEC tree implies that the first
+ * node checked in the main tree had an
+ * unacceptable NSEC record.
+ * Try the previous node in the NSEC tree.
+ */
+ result = dns_rbtnodechain_prev(nsecchain,
+ name, origin);
+ if (result == DNS_R_NEWORIGIN)
+ result = ISC_R_SUCCESS;
+ } else if (result == ISC_R_NOTFOUND ||
+ result == DNS_R_PARTIALMATCH) {
+ result = dns_rbtnodechain_current(nsecchain,
+ name, origin, NULL);
+ if (result == ISC_R_NOTFOUND)
+ result = ISC_R_NOMORE;
+ }
+ } else {
+ /*
+ * This is a second or later trip through the auxiliary
+ * tree for the name of a third or earlier NSEC node in
+ * the main tree. Previous trips through the NSEC tree
+ * must have found nodes in the main tree with NSEC
+ * records. Perhaps they lacked signature records.
+ */
+ result = dns_rbtnodechain_prev(nsecchain, name, origin);
+ if (result == DNS_R_NEWORIGIN)
+ result = ISC_R_SUCCESS;
+ }
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * Construct the name to seek in the main tree.
+ */
+ result = dns_name_concatenate(name, origin, target, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ *nodep = NULL;
+ result = dns_rbt_findnode(search->rbtdb->tree, target, NULL,
+ nodep, &search->chain,
+ DNS_RBTFIND_NOOPTIONS, NULL, NULL);
+ if (result == ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * There should always be a node in the main tree with the
+ * same name as the node in the auxiliary NSEC tree, except for
+ * nodes in the auxiliary tree that are awaiting deletion.
+ */
+ if (result != DNS_R_PARTIALMATCH && result != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_CACHE, ISC_LOG_ERROR,
+ "previous_closest_nsec(): %s",
+ isc_result_totext(result));
+ return (DNS_R_BADDB);
+ }
+ }
+}
+
+/*
+ * Find the NSEC/NSEC3 which is or before the current point on the
+ * search chain. For NSEC3 records only NSEC3 records that match the
+ * current NSEC3PARAM record are considered.
+ */
+static inline isc_result_t
find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset, dns_rbt_t *tree,
dns_db_secure_t secure)
{
- dns_rbtnode_t *node;
+ dns_rbtnode_t *node, *prevnode;
rdatasetheader_t *header, *header_next, *found, *foundsig;
+ dns_rbtnodechain_t nsecchain;
isc_boolean_t empty_node;
isc_result_t result;
dns_fixedname_t fname, forigin;
@@ -3282,6 +3444,7 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
dns_rdatatype_t type;
rbtdb_rdatatype_t sigtype;
isc_boolean_t wraps;
+ isc_boolean_t first = ISC_TRUE;
isc_boolean_t need_sig = ISC_TF(secure == dns_db_secure);
if (tree == search->rbtdb->nsec3) {
@@ -3294,17 +3457,21 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
wraps = ISC_FALSE;
}
+ /*
+ * Use the auxiliary tree only starting with the second node in the
+ * hope that the original node will be right much of the time.
+ */
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_fixedname_init(&forigin);
+ origin = dns_fixedname_name(&forigin);
again:
+ node = NULL;
+ prevnode = NULL;
+ result = dns_rbtnodechain_current(&search->chain, name, origin, &node);
+ if (result != ISC_R_SUCCESS)
+ return (result);
do {
- node = NULL;
- dns_fixedname_init(&fname);
- name = dns_fixedname_name(&fname);
- dns_fixedname_init(&forigin);
- origin = dns_fixedname_name(&forigin);
- result = dns_rbtnodechain_current(&search->chain, name,
- origin, &node);
- if (result != ISC_R_SUCCESS)
- return (result);
NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock),
isc_rwlocktype_read);
found = NULL;
@@ -3354,11 +3521,12 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
empty_node = ISC_TRUE;
found = NULL;
foundsig = NULL;
- result = dns_rbtnodechain_prev(&search->chain,
- NULL, NULL);
+ result = previous_closest_nsec(type, search,
+ name, origin,
+ &prevnode, NULL,
+ NULL);
} else if (found != NULL &&
- (foundsig != NULL || !need_sig))
- {
+ (foundsig != NULL || !need_sig)) {
/*
* We've found the right NSEC/NSEC3 record.
*
@@ -3395,8 +3563,11 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
* node as if it were empty and keep looking.
*/
empty_node = ISC_TRUE;
- result = dns_rbtnodechain_prev(&search->chain,
- NULL, NULL);
+ result = previous_closest_nsec(type, search,
+ name, origin,
+ &prevnode,
+ &nsecchain,
+ &first);
} else {
/*
* We found an active node, but either the
@@ -3410,13 +3581,19 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
* This node isn't active. We've got to keep
* looking.
*/
- result = dns_rbtnodechain_prev(&search->chain, NULL,
- NULL);
+ result = previous_closest_nsec(type, search,
+ name, origin, &prevnode,
+ &nsecchain, &first);
}
NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
isc_rwlocktype_read);
+ node = prevnode;
+ prevnode = NULL;
} while (empty_node && result == ISC_R_SUCCESS);
+ if (!first)
+ dns_rbtnodechain_invalidate(&nsecchain);
+
if (result == ISC_R_NOMORE && wraps) {
result = dns_rbtnodechain_last(&search->chain, tree,
NULL, NULL);
@@ -3960,6 +4137,7 @@ zone_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
FATAL_ERROR(__FILE__, __LINE__, "zone_findzonecut() called!");
+ /* NOTREACHED */
return (ISC_R_NOTIMPLEMENTED);
}
@@ -4371,6 +4549,200 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
return (result);
}
+/*
+ * Mark a database for response policy rewriting.
+ */
+#ifdef BIND9
+static void
+get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
+{
+ dns_rbtdb_t *rbtdb;
+
+ rbtdb = (dns_rbtdb_t *)db;
+ REQUIRE(VALID_RBTDB(rbtdb));
+ RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ dns_rpz_enabled(rbtdb->rpz_cidr, st);
+ RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+}
+
+/*
+ * Search the CDIR block tree of a response policy tree of trees for all of
+ * the IP addresses in an A or AAAA rdataset.
+ * Among the policies for all IPv4 and IPv6 addresses for a name, choose
+ * the longest prefix. Among those with the longest prefix, the first
+ * configured policy. Among answers for with the longest prefixes for
+ * two or more IP addresses in the A and AAAA rdatasets the lexically
+ * smallest address.
+ */
+static isc_result_t
+rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
+ dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
+ dns_rdataset_t *ardataset, dns_rpz_st_t *st)
+{
+ dns_rbtdb_t *rbtdb;
+ struct in_addr ina;
+ struct in6_addr in6a;
+ isc_netaddr_t netaddr;
+ dns_fixedname_t selfnamef, qnamef;
+ dns_name_t *selfname, *qname;
+ dns_rbtnode_t *node;
+ dns_rdataset_t zrdataset;
+ dns_rpz_cidr_bits_t prefix;
+ isc_result_t result;
+ dns_rpz_policy_t rpz_policy;
+ dns_ttl_t ttl;
+
+ rbtdb = (dns_rbtdb_t *)db;
+ REQUIRE(VALID_RBTDB(rbtdb));
+ RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+
+ if (rbtdb->rpz_cidr == NULL) {
+ RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ dns_db_detach(&db);
+ dns_zone_detach(&zone);
+ return (ISC_R_UNEXPECTED);
+ }
+
+ dns_fixedname_init(&selfnamef);
+ dns_fixedname_init(&qnamef);
+ selfname = dns_fixedname_name(&selfnamef);
+ qname = dns_fixedname_name(&qnamef);
+
+ for (result = dns_rdataset_first(ardataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(ardataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_current(ardataset, &rdata);
+ switch (rdata.type) {
+ case dns_rdatatype_a:
+ INSIST(rdata.length == 4);
+ memcpy(&ina.s_addr, rdata.data, 4);
+ isc_netaddr_fromin(&netaddr, &ina);
+ break;
+ case dns_rdatatype_aaaa:
+ INSIST(rdata.length == 16);
+ memcpy(in6a.s6_addr, rdata.data, 16);
+ isc_netaddr_fromin6(&netaddr, &in6a);
+ break;
+ default:
+ continue;
+ }
+
+ result = dns_rpz_cidr_find(rbtdb->rpz_cidr, &netaddr, rpz_type,
+ selfname, qname, &prefix);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ /*
+ * Choose the policy with the longest matching prefix.
+ * Between policies with the same prefix, choose the first
+ * configured.
+ */
+ if (st->m.policy != DNS_RPZ_POLICY_MISS) {
+ if (prefix < st->m.prefix)
+ continue;
+ if (prefix == st->m.prefix &&
+ rpz->num > st->m.rpz->num)
+ continue;
+ }
+
+ /*
+ * We have rpz_st an entry with a prefix at least as long as
+ * the prefix of the entry we had before. Find the node
+ * corresponding to CDIR tree entry.
+ */
+ node = NULL;
+ result = dns_rbt_findnode(rbtdb->tree, qname, NULL,
+ &node, NULL, 0, NULL, NULL);
+ if (result != ISC_R_SUCCESS) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+
+ dns_name_format(qname, namebuf, sizeof(namebuf));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_CACHE, DNS_RPZ_ERROR_LEVEL,
+ "rpz_findips findnode(%s): %s",
+ namebuf, isc_result_totext(result));
+ continue;
+ }
+ /*
+ * First look for a simple rewrite of the IP address.
+ * If that fails, look for a CNAME. If we cannot find
+ * a CNAME or the CNAME is neither of the special forms
+ * "*" or ".", treat it like a real CNAME.
+ */
+ dns_rdataset_init(&zrdataset);
+ result = dns_db_findrdataset(db, node, version, ardataset->type,
+ 0, 0, &zrdataset, NULL);
+ if (result != ISC_R_SUCCESS)
+ result = dns_db_findrdataset(db, node, version,
+ dns_rdatatype_cname,
+ 0, 0, &zrdataset, NULL);
+ if (result == ISC_R_SUCCESS) {
+ if (zrdataset.type != dns_rdatatype_cname) {
+ rpz_policy = DNS_RPZ_POLICY_RECORD;
+ } else {
+ rpz_policy = dns_rpz_decode_cname(&zrdataset,
+ selfname);
+ if (rpz_policy == DNS_RPZ_POLICY_RECORD)
+ result = DNS_R_CNAME;
+ }
+ ttl = zrdataset.ttl;
+ } else {
+ rpz_policy = DNS_RPZ_POLICY_RECORD;
+ result = DNS_R_NXRRSET;
+ ttl = DNS_RPZ_TTL_DEFAULT;
+ }
+
+ /*
+ * Use an overriding action specified in the configuration file
+ */
+ if (rpz->policy != DNS_RPZ_POLICY_GIVEN &&
+ rpz_policy != DNS_RPZ_POLICY_NO_OP)
+ rpz_policy = rpz->policy;
+
+ /*
+ * We know the new prefix is at least as long as the current.
+ * Prefer the new answer if the new prefix is longer.
+ * Prefer the zone configured first if the prefixes are equal.
+ * With two actions from the same zone, prefer the action
+ * on the "smallest" name.
+ */
+ if (st->m.policy == DNS_RPZ_POLICY_MISS ||
+ prefix > st->m.prefix ||
+ rpz->num <= st->m.rpz->num ||
+ 0 > dns_name_compare(qname, st->qname)) {
+ if (dns_rdataset_isassociated(st->m.rdataset))
+ dns_rdataset_disassociate(st->m.rdataset);
+ if (st->m.node != NULL)
+ dns_db_detachnode(st->m.db, &st->m.node);
+ if (st->m.db != NULL)
+ dns_db_detach(&st->m.db);
+ if (st->m.zone != NULL)
+ dns_zone_detach(&st->m.zone);
+ st->m.rpz = rpz;
+ st->m.type = rpz_type;
+ st->m.prefix = prefix;
+ st->m.policy = rpz_policy;
+ st->m.ttl = ttl;
+ st->m.result = result;
+ dns_name_copy(qname, st->qname, NULL);
+ if (rpz_policy == DNS_RPZ_POLICY_RECORD &&
+ result != DNS_R_NXRRSET) {
+ dns_rdataset_clone(&zrdataset,st->m.rdataset);
+ dns_db_attachnode(db, node, &st->m.node);
+ }
+ dns_db_attach(db, &st->m.db);
+ dns_zone_attach(zone, &st->m.zone);
+ }
+ if (dns_rdataset_isassociated(&zrdataset))
+ dns_rdataset_disassociate(&zrdataset);
+ }
+
+ RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ return (ISC_R_SUCCESS);
+}
+#endif
+
static isc_result_t
cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
@@ -5693,6 +6065,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
free_rdataset(rbtdb, rbtdb->common.mctx,
newheader);
newheader = (rdatasetheader_t *)merged;
+ init_rdataset(rbtdb, newheader);
if (loading && RESIGN(newheader) &&
RESIGN(header) &&
header->resign < newheader->resign)
@@ -6015,16 +6388,17 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
rdatasetheader_t *header;
isc_result_t result;
isc_boolean_t delegating;
+ isc_boolean_t newnsec;
isc_boolean_t tree_locked = ISC_FALSE;
isc_boolean_t cache_is_overmem = ISC_FALSE;
REQUIRE(VALID_RBTDB(rbtdb));
if (rbtdb->common.methods == &zone_methods)
- REQUIRE(((rbtnode->nsec3 &&
+ REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
(rdataset->type == dns_rdatatype_nsec3 ||
rdataset->covers == dns_rdatatype_nsec3)) ||
- (!rbtnode->nsec3 &&
+ (rbtnode->nsec != DNS_RBT_NSEC_NSEC3 &&
rdataset->type != dns_rdatatype_nsec3 &&
rdataset->covers != dns_rdatatype_nsec3)));
@@ -6101,14 +6475,23 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
delegating = ISC_FALSE;
/*
- * If we're adding a delegation type or the DB is a cache in an overmem
- * state, hold an exclusive lock on the tree. In the latter case
- * the lock does not necessarily have to be acquired but it will help
- * purge stale entries more effectively.
+ * Add to the auxiliary NSEC tree if we're adding an NSEC record.
+ */
+ if (rbtnode->nsec != DNS_RBT_NSEC_HAS_NSEC &&
+ rdataset->type == dns_rdatatype_nsec)
+ newnsec = ISC_TRUE;
+ else
+ newnsec = ISC_FALSE;
+
+ /*
+ * If we're adding a delegation type, adding to the auxiliary NSEC tree,
+ * or the DB is a cache in an overmem state, hold an exclusive lock on
+ * the tree. In the latter case the lock does not necessarily have to
+ * be acquired but it will help purge stale entries more effectively.
*/
if (IS_CACHE(rbtdb) && isc_mem_isovermem(rbtdb->common.mctx))
cache_is_overmem = ISC_TRUE;
- if (delegating || cache_is_overmem) {
+ if (delegating || newnsec || cache_is_overmem) {
tree_locked = ISC_TRUE;
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
}
@@ -6137,14 +6520,35 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
* cleaning, we can release it now. However, we still need the
* node lock.
*/
- if (tree_locked && !delegating) {
+ if (tree_locked && !delegating && !newnsec) {
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
tree_locked = ISC_FALSE;
}
}
- result = add(rbtdb, rbtnode, rbtversion, newheader, options, ISC_FALSE,
- addedrdataset, now);
+ result = ISC_R_SUCCESS;
+ if (newnsec) {
+ dns_fixedname_t fname;
+ dns_name_t *name;
+ dns_rbtnode_t *nsecnode;
+
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_rbt_fullnamefromnode(rbtnode, name);
+ nsecnode = NULL;
+ result = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode);
+ if (result == ISC_R_SUCCESS) {
+ nsecnode->nsec = DNS_RBT_NSEC_NSEC;
+ rbtnode->nsec = DNS_RBT_NSEC_HAS_NSEC;
+ } else if (result == ISC_R_EXISTS) {
+ rbtnode->nsec = DNS_RBT_NSEC_HAS_NSEC;
+ result = ISC_R_SUCCESS;
+ }
+ }
+
+ if (result == ISC_R_SUCCESS)
+ result = add(rbtdb, rbtnode, rbtversion, newheader, options,
+ ISC_FALSE, addedrdataset, now);
if (result == ISC_R_SUCCESS && delegating)
rbtnode->find_callback = 1;
@@ -6181,10 +6585,10 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
REQUIRE(VALID_RBTDB(rbtdb));
if (rbtdb->common.methods == &zone_methods)
- REQUIRE(((rbtnode->nsec3 &&
+ REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
(rdataset->type == dns_rdatatype_nsec3 ||
rdataset->covers == dns_rdatatype_nsec3)) ||
- (!rbtnode->nsec3 &&
+ (rbtnode->nsec != DNS_RBT_NSEC_NSEC3 &&
rdataset->type != dns_rdatatype_nsec3 &&
rdataset->covers != dns_rdatatype_nsec3)));
@@ -6403,6 +6807,78 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
return (result);
}
+/*
+ * load a non-NSEC3 node in the main tree and optionally to the auxiliary NSEC
+ */
+static isc_result_t
+loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep,
+ isc_boolean_t hasnsec)
+{
+ isc_result_t noderesult, nsecresult;
+ dns_rbtnode_t *nsecnode;
+
+ noderesult = dns_rbt_addnode(rbtdb->tree, name, nodep);
+
+#ifdef BIND9
+ if (noderesult == ISC_R_SUCCESS)
+ dns_rpz_cidr_addip(rbtdb->rpz_cidr, name);
+#endif
+
+ if (!hasnsec)
+ return (noderesult);
+ if (noderesult == ISC_R_EXISTS) {
+ /*
+ * Add a node to the auxiliary NSEC tree for an old node
+ * just now getting an NSEC record.
+ */
+ if ((*nodep)->nsec == DNS_RBT_NSEC_HAS_NSEC)
+ return (noderesult);
+ } else if (noderesult != ISC_R_SUCCESS) {
+ return (noderesult);
+ }
+
+ /*
+ * Build the auxiliary tree for NSECs as we go.
+ * This tree speeds searches for closest NSECs that would otherwise
+ * need to examine many irrelevant nodes in large TLDs.
+ *
+ * Add nodes to the auxiliary tree after corresponding nodes have
+ * been added to the main tree.
+ */
+ nsecnode = NULL;
+ nsecresult = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode);
+ if (nsecresult == ISC_R_SUCCESS) {
+ nsecnode->nsec = DNS_RBT_NSEC_NSEC;
+ (*nodep)->nsec = DNS_RBT_NSEC_HAS_NSEC;
+ return (noderesult);
+ }
+
+ if (nsecresult == ISC_R_EXISTS) {
+#if 1 /* 0 */
+ isc_log_write(dns_lctx,
+ DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_CACHE,
+ ISC_LOG_WARNING,
+ "addnode: NSEC node already exists");
+#endif
+ (*nodep)->nsec = DNS_RBT_NSEC_HAS_NSEC;
+ return (noderesult);
+ }
+
+ nsecresult = dns_rbt_deletenode(rbtdb->tree, *nodep, ISC_FALSE);
+ if (nsecresult != ISC_R_SUCCESS)
+ isc_log_write(dns_lctx,
+ DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_CACHE,
+ ISC_LOG_WARNING,
+ "loading_addrdataset: "
+ "dns_rbt_deletenode: %s after "
+ "dns_rbt_addnode(NSEC): %s",
+ isc_result_totext(nsecresult),
+ isc_result_totext(noderesult));
+ return (noderesult);
+}
+
static isc_result_t
loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
rbtdb_load_t *loadctx = arg;
@@ -6451,15 +6927,15 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
rdataset->covers == dns_rdatatype_nsec3) {
result = dns_rbt_addnode(rbtdb->nsec3, name, &node);
if (result == ISC_R_SUCCESS)
- node->nsec3 = 1;
+ node->nsec = DNS_RBT_NSEC_NSEC3;
+ } else if (rdataset->type == dns_rdatatype_nsec) {
+ result = loadnode(rbtdb, name, &node, ISC_TRUE);
} else {
- result = dns_rbt_addnode(rbtdb->tree, name, &node);
- if (result == ISC_R_SUCCESS)
- node->nsec3 = 0;
+ result = loadnode(rbtdb, name, &node, ISC_FALSE);
}
if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS)
return (result);
- if (result != ISC_R_EXISTS) {
+ if (result == ISC_R_SUCCESS) {
dns_name_t foundname;
dns_name_init(&foundname, NULL);
dns_rbt_namefromnode(node, &foundname);
@@ -6585,9 +7061,17 @@ dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
REQUIRE(VALID_RBTDB(rbtdb));
+#ifdef BIND9
return (dns_master_dump2(rbtdb->common.mctx, db, version,
&dns_master_style_default,
filename, masterformat));
+#else
+ UNUSED(version);
+ UNUSED(filename);
+ UNUSED(masterformat);
+
+ return (ISC_R_NOTIMPLEMENTED);
+#endif /* BIND9 */
}
static void
@@ -6768,7 +7252,7 @@ setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) {
} else if (resign < oldresign)
isc_heap_increased(rbtdb->heaps[header->node->locknum],
header->heap_index);
- else
+ else if (resign > oldresign)
isc_heap_decreased(rbtdb->heaps[header->node->locknum],
header->heap_index);
} else if (resign && header->heap_index == 0) {
@@ -6913,7 +7397,14 @@ static dns_dbmethods_t zone_methods = {
getsigningtime,
resigned,
isdnssec,
+ NULL,
+#ifdef BIND9
+ get_rpz_enabled,
+ rpz_findips
+#else
+ NULL,
NULL
+#endif
};
static dns_dbmethods_t cache_methods = {
@@ -6952,7 +7443,9 @@ static dns_dbmethods_t cache_methods = {
NULL,
NULL,
isdnssec,
- getrrsetstats
+ getrrsetstats,
+ NULL,
+ NULL
};
isc_result_t
@@ -7122,12 +7615,36 @@ dns_rbtdb_create
return (result);
}
+ result = dns_rbt_create(mctx, delete_callback, rbtdb, &rbtdb->nsec);
+ if (result != ISC_R_SUCCESS) {
+ free_rbtdb(rbtdb, ISC_FALSE, NULL);
+ return (result);
+ }
+
result = dns_rbt_create(mctx, delete_callback, rbtdb, &rbtdb->nsec3);
if (result != ISC_R_SUCCESS) {
free_rbtdb(rbtdb, ISC_FALSE, NULL);
return (result);
}
+#ifdef BIND9
+ /*
+ * Get ready for response policy IP address searching if at least one
+ * zone has been configured as a response policy zone and this
+ * is not a cache zone.
+ * It would be better to know that this database is for a policy
+ * zone named for a view, but that would require knowledge from
+ * above such as an argv[] set from data in the zone.
+ */
+ if (type == dns_dbtype_zone && !dns_name_equal(origin, dns_rootname)) {
+ result = dns_rpz_new_cidr(mctx, origin, &rbtdb->rpz_cidr);
+ if (result != ISC_R_SUCCESS) {
+ free_rbtdb(rbtdb, ISC_FALSE, NULL);
+ return (result);
+ }
+ }
+#endif
+
/*
* In order to set the node callback bit correctly in zone databases,
* we need to know if the node has the origin name of the zone.
@@ -7152,7 +7669,7 @@ dns_rbtdb_create
free_rbtdb(rbtdb, ISC_FALSE, NULL);
return (result);
}
- rbtdb->origin_node->nsec3 = 0;
+ rbtdb->origin_node->nsec = DNS_RBT_NSEC_NORMAL;
/*
* We need to give the origin node the right locknum.
*/
@@ -7180,7 +7697,7 @@ dns_rbtdb_create
free_rbtdb(rbtdb, ISC_FALSE, NULL);
return (result);
}
- nsec3node->nsec3 = 1;
+ nsec3node->nsec = DNS_RBT_NSEC_NSEC3;
/*
* We need to give the nsec3 origin node the right locknum.
*/
@@ -8238,6 +8755,21 @@ rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
dns_name_t *fname, dns_message_t *msg,
isc_stdtime_t now)
{
+#ifndef BIND9
+ UNUSED(rdataset);
+ UNUSED(type);
+ UNUSED(qtype);
+ UNUSED(acache);
+ UNUSED(zonep);
+ UNUSED(dbp);
+ UNUSED(versionp);
+ UNUSED(nodep);
+ UNUSED(fname);
+ UNUSED(msg);
+ UNUSED(now);
+
+ return (ISC_R_NOTIMPLEMENTED);
+#else
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
@@ -8354,8 +8886,10 @@ acache_callback(dns_acacheentry_t *entry, void **arg) {
dns_db_detach((dns_db_t **)(void*)&rbtdb);
*arg = NULL;
+#endif /* BIND9 */
}
+#ifdef BIND9
static void
acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry,
acache_cbarg_t **cbargp)
@@ -8376,6 +8910,7 @@ acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry,
*cbargp = NULL;
}
+#endif /* BIND9 */
static isc_result_t
rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
@@ -8384,6 +8919,19 @@ rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
dns_dbversion_t *version, dns_dbnode_t *node,
dns_name_t *fname)
{
+#ifndef BIND9
+ UNUSED(rdataset);
+ UNUSED(type);
+ UNUSED(qtype);
+ UNUSED(acache);
+ UNUSED(zone);
+ UNUSED(db);
+ UNUSED(version);
+ UNUSED(node);
+ UNUSED(fname);
+
+ return (ISC_R_NOTIMPLEMENTED);
+#else
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
@@ -8507,12 +9055,21 @@ rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
}
return (result);
+#endif
}
static isc_result_t
rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset,
dns_rdatasetadditional_t type, dns_rdatatype_t qtype)
{
+#ifndef BIND9
+ UNUSED(acache);
+ UNUSED(rdataset);
+ UNUSED(type);
+ UNUSED(qtype);
+
+ return (ISC_R_NOTIMPLEMENTED);
+#else
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
@@ -8577,6 +9134,7 @@ rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset,
}
return (ISC_R_SUCCESS);
+#endif
}
/*%
diff --git a/lib/dns/rcode.c b/lib/dns/rcode.c
index 2dc0a293ea29..18fedcdefcd4 100644
--- a/lib/dns/rcode.c
+++ b/lib/dns/rcode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rcode.c,v 1.8.48.2 2010-01-15 23:47:33 tbox Exp $ */
+/* $Id: rcode.c,v 1.16 2010-12-23 04:07:58 marka Exp $ */
#include <config.h>
#include <ctype.h>
@@ -79,12 +79,17 @@
{ dns_tsigerror_badtrunc, "BADTRUNC", 0}, \
{ 0, NULL, 0 }
-/* RFC2538 section 2.1 */
+/* RFC4398 section 2.1 */
#define CERTNAMES \
{ 1, "PKIX", 0}, \
{ 2, "SPKI", 0}, \
{ 3, "PGP", 0}, \
+ { 4, "IPKIX", 0}, \
+ { 5, "ISPKI", 0}, \
+ { 6, "IPGP", 0}, \
+ { 7, "ACPKIX", 0}, \
+ { 8, "IACPKIX", 0}, \
{ 253, "URI", 0}, \
{ 254, "OID", 0}, \
{ 0, NULL, 0}
@@ -102,6 +107,7 @@
{ DNS_KEYALG_NSEC3RSASHA1, "NSEC3RSASHA1", 0 }, \
{ DNS_KEYALG_RSASHA256, "RSASHA256", 0 }, \
{ DNS_KEYALG_RSASHA512, "RSASHA512", 0 }, \
+ { DNS_KEYALG_ECCGOST, "ECCGOST", 0 }, \
{ DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \
{ DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \
{ DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \
@@ -313,6 +319,21 @@ dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target) {
return (dns_mnemonic_totext(secalg, target, secalgs));
}
+void
+dns_secalg_format(dns_secalg_t alg, char *cp, unsigned int size) {
+ isc_buffer_t b;
+ isc_region_t r;
+ isc_result_t result;
+
+ REQUIRE(cp != NULL && size > 0);
+ isc_buffer_init(&b, cp, size - 1);
+ result = dns_secalg_totext(alg, &b);
+ isc_buffer_usedregion(&b, &r);
+ r.base[r.length] = 0;
+ if (result != ISC_R_SUCCESS)
+ r.base[0] = 0;
+}
+
isc_result_t
dns_secproto_fromtext(dns_secproto_t *secprotop, isc_textregion_t *source) {
unsigned int value;
diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c
index daaa83ac4afc..c282b033cfc8 100644
--- a/lib/dns/rdata.c
+++ b/lib/dns/rdata.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdata.c,v 1.199.50.4 2011-01-13 04:48:21 tbox Exp $ */
+/* $Id: rdata.c,v 1.209 2011-01-13 04:59:25 tbox Exp $ */
/*! \file */
@@ -38,6 +38,7 @@
#include <dns/enumtype.h>
#include <dns/keyflags.h>
#include <dns/keyvalues.h>
+#include <dns/message.h>
#include <dns/rcode.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
@@ -275,23 +276,6 @@ dns_rdata_init(dns_rdata_t *rdata) {
/* ISC_LIST_INIT(rdata->list); */
}
-#if 1
-#define DNS_RDATA_INITIALIZED(rdata) \
- ((rdata)->data == NULL && (rdata)->length == 0 && \
- (rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 0 && \
- !ISC_LINK_LINKED((rdata), link))
-#else
-#ifdef ISC_LIST_CHECKINIT
-#define DNS_RDATA_INITIALIZED(rdata) \
- (!ISC_LINK_LINKED((rdata), link))
-#else
-#define DNS_RDATA_INITIALIZED(rdata) ISC_TRUE
-#endif
-#endif
-
-#define DNS_RDATA_VALIDFLAGS(rdata) \
- (((rdata)->flags & ~(DNS_RDATA_UPDATE|DNS_RDATA_OFFLINE)) == 0)
-
void
dns_rdata_reset(dns_rdata_t *rdata) {
@@ -365,6 +349,37 @@ dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) {
return (result);
}
+int
+dns_rdata_casecompare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) {
+ int result = 0;
+ isc_boolean_t use_default = ISC_FALSE;
+
+ REQUIRE(rdata1 != NULL);
+ REQUIRE(rdata2 != NULL);
+ REQUIRE(rdata1->data != NULL);
+ REQUIRE(rdata2->data != NULL);
+ REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
+ REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
+
+ if (rdata1->rdclass != rdata2->rdclass)
+ return (rdata1->rdclass < rdata2->rdclass ? -1 : 1);
+
+ if (rdata1->type != rdata2->type)
+ return (rdata1->type < rdata2->type ? -1 : 1);
+
+ CASECOMPARESWITCH
+
+ if (use_default) {
+ isc_region_t r1;
+ isc_region_t r2;
+
+ dns_rdata_toregion(rdata1, &r1);
+ dns_rdata_toregion(rdata2, &r2);
+ result = isc_region_compare(&r1, &r2);
+ }
+ return (result);
+}
+
/***
*** Conversions
***/
@@ -1772,3 +1787,93 @@ dns_rdatatype_isknown(dns_rdatatype_t type) {
return (ISC_TRUE);
return (ISC_FALSE);
}
+
+void
+dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type) {
+
+ REQUIRE(rdata != NULL);
+ REQUIRE(DNS_RDATA_INITIALIZED(rdata));
+
+ rdata->data = NULL;
+ rdata->length = 0;
+ rdata->flags = DNS_RDATA_UPDATE;
+ rdata->type = type;
+ rdata->rdclass = dns_rdataclass_any;
+}
+
+void
+dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type) {
+
+ REQUIRE(rdata != NULL);
+ REQUIRE(DNS_RDATA_INITIALIZED(rdata));
+
+ rdata->data = NULL;
+ rdata->length = 0;
+ rdata->flags = DNS_RDATA_UPDATE;
+ rdata->type = type;
+ rdata->rdclass = dns_rdataclass_none;
+}
+
+void
+dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type) {
+
+ REQUIRE(rdata != NULL);
+ REQUIRE(DNS_RDATA_INITIALIZED(rdata));
+
+ rdata->data = NULL;
+ rdata->length = 0;
+ rdata->flags = DNS_RDATA_UPDATE;
+ rdata->type = type;
+ rdata->rdclass = dns_rdataclass_any;
+}
+
+void
+dns_rdata_makedelete(dns_rdata_t *rdata) {
+ REQUIRE(rdata != NULL);
+
+ rdata->rdclass = dns_rdataclass_none;
+}
+
+const char *
+dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section) {
+
+ REQUIRE(rdata != NULL);
+ REQUIRE(DNS_RDATA_INITIALIZED(rdata));
+
+ switch (section) {
+ case DNS_SECTION_PREREQUISITE:
+ switch (rdata->rdclass) {
+ case dns_rdataclass_none:
+ switch (rdata->type) {
+ case dns_rdatatype_any:
+ return ("domain doesn't exist");
+ default:
+ return ("rrset doesn't exist");
+ }
+ case dns_rdataclass_any:
+ switch (rdata->type) {
+ case dns_rdatatype_any:
+ return ("domain exists");
+ default:
+ return ("rrset exists (value independent)");
+ }
+ default:
+ return ("rrset exists (value dependent)");
+ }
+ case DNS_SECTION_UPDATE:
+ switch (rdata->rdclass) {
+ case dns_rdataclass_none:
+ return ("delete");
+ case dns_rdataclass_any:
+ switch (rdata->type) {
+ case dns_rdatatype_any:
+ return ("delete all rrsets");
+ default:
+ return ("delete rrset");
+ }
+ default:
+ return ("add");
+ }
+ }
+ return ("invalid");
+}
diff --git a/lib/dns/rdata/any_255/tsig_250.c b/lib/dns/rdata/any_255/tsig_250.c
index e6982390efaa..9763f6d0e511 100644
--- a/lib/dns/rdata/any_255/tsig_250.c
+++ b/lib/dns/rdata/any_255/tsig_250.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tsig_250.c,v 1.63 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: tsig_250.c,v 1.65 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Thu Mar 16 13:39:43 PST 2000 by gson */
@@ -594,4 +594,9 @@ checknames_any_tsig(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_any_tsig(ARGS_COMPARE) {
+ return (compare_any_tsig(rdata1, rdata2));
+}
+
#endif /* RDATA_ANY_255_TSIG_250_C */
diff --git a/lib/dns/rdata/ch_3/a_1.c b/lib/dns/rdata/ch_3/a_1.c
index 156caace2fec..2623f76a49f1 100644
--- a/lib/dns/rdata/ch_3/a_1.c
+++ b/lib/dns/rdata/ch_3/a_1.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: a_1.c,v 1.6 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: a_1.c,v 1.8 2009-12-04 22:06:37 tbox Exp $ */
/* by Bjorn.Victor@it.uu.se, 2005-05-07 */
/* Based on generic/soa_6.c and generic/mx_15.c */
@@ -107,7 +107,7 @@ fromwire_ch_a(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
dns_name_init(&name, NULL);
-
+
RETERR(dns_name_fromwire(&name, source, dctx, options, target));
isc_buffer_activeregion(source, &sregion);
@@ -205,7 +205,7 @@ fromstruct_ch_a(ARGS_FROMSTRUCT) {
dns_name_toregion(&a->ch_addr_dom, &region);
RETERR(isc_buffer_copyregion(target, &region));
-
+
return (uint16_tobuffer(ntohs(a->ch_addr), target));
}
@@ -313,4 +313,8 @@ checknames_ch_a(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_ch_a(ARGS_COMPARE) {
+ return (compare_ch_a(rdata1, rdata2));
+}
#endif /* RDATA_CH_3_A_1_C */
diff --git a/lib/dns/rdata/generic/afsdb_18.c b/lib/dns/rdata/generic/afsdb_18.c
index f82167bee23d..bd1d1e02402c 100644
--- a/lib/dns/rdata/generic/afsdb_18.c
+++ b/lib/dns/rdata/generic/afsdb_18.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: afsdb_18.c,v 1.47 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: afsdb_18.c,v 1.49 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Wed Mar 15 14:59:00 PST 2000 by explorer */
@@ -306,4 +306,8 @@ checknames_afsdb(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_afsdb(ARGS_COMPARE) {
+ return (compare_afsdb(rdata1, rdata2));
+}
#endif /* RDATA_GENERIC_AFSDB_18_C */
diff --git a/lib/dns/rdata/generic/cert_37.c b/lib/dns/rdata/generic/cert_37.c
index e0398d21cf16..d06b4e631559 100644
--- a/lib/dns/rdata/generic/cert_37.c
+++ b/lib/dns/rdata/generic/cert_37.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: cert_37.c,v 1.50 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: cert_37.c,v 1.52 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Wed Mar 15 21:14:32 EST 2000 by tale */
@@ -276,5 +276,9 @@ checknames_cert(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
-#endif /* RDATA_GENERIC_CERT_37_C */
+static inline int
+casecompare_cert(ARGS_COMPARE) {
+ return (compare_cert(rdata1, rdata2));
+}
+#endif /* RDATA_GENERIC_CERT_37_C */
diff --git a/lib/dns/rdata/generic/cname_5.c b/lib/dns/rdata/generic/cname_5.c
index f44d8c54f5f8..508bb2000139 100644
--- a/lib/dns/rdata/generic/cname_5.c
+++ b/lib/dns/rdata/generic/cname_5.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: cname_5.c,v 1.47 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: cname_5.c,v 1.49 2009-12-04 22:06:37 tbox Exp $ */
/* reviewed: Wed Mar 15 16:48:45 PST 2000 by brister */
@@ -229,4 +229,9 @@ checknames_cname(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_cname(ARGS_COMPARE) {
+ return (compare_cname(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_CNAME_5_C */
diff --git a/lib/dns/rdata/generic/dlv_32769.c b/lib/dns/rdata/generic/dlv_32769.c
index 21d7abbb4532..0f87433c0163 100644
--- a/lib/dns/rdata/generic/dlv_32769.c
+++ b/lib/dns/rdata/generic/dlv_32769.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2006, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dlv_32769.c,v 1.6 2007-06-18 23:47:43 tbox Exp $ */
+/* $Id: dlv_32769.c,v 1.10 2010-12-23 23:47:08 tbox Exp $ */
/* draft-ietf-dnsext-delegation-signer-05.txt */
@@ -74,12 +74,20 @@ fromtext_dlv(ARGS_FROMTEXT) {
/*
* Digest.
*/
- if (c == DNS_DSDIGEST_SHA1)
+ switch (c) {
+ case DNS_DSDIGEST_SHA1:
length = ISC_SHA1_DIGESTLENGTH;
- else if (c == DNS_DSDIGEST_SHA256)
+ break;
+ case DNS_DSDIGEST_SHA256:
length = ISC_SHA256_DIGESTLENGTH;
- else
+ break;
+ case DNS_DSDIGEST_GOST:
+ length = ISC_GOST_DIGESTLENGTH;
+ break;
+ default:
length = -1;
+ break;
+ }
return (isc_hex_tobuffer(lexer, target, -1));
}
@@ -144,7 +152,7 @@ fromwire_dlv(ARGS_FROMWIRE) {
UNUSED(options);
isc_buffer_activeregion(source, &sr);
-
+
/*
* Check digest lengths if we know them.
*/
@@ -152,7 +160,9 @@ fromwire_dlv(ARGS_FROMWIRE) {
(sr.base[3] == DNS_DSDIGEST_SHA1 &&
sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
(sr.base[3] == DNS_DSDIGEST_SHA256 &&
- sr.length < 4 + ISC_SHA256_DIGESTLENGTH))
+ sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
+ (sr.base[3] == DNS_DSDIGEST_GOST &&
+ sr.length < 4 + ISC_GOST_DIGESTLENGTH))
return (ISC_R_UNEXPECTEDEND);
/*
@@ -164,7 +174,9 @@ fromwire_dlv(ARGS_FROMWIRE) {
sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
else if (sr.base[3] == DNS_DSDIGEST_SHA256)
sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
-
+ else if (sr.base[3] == DNS_DSDIGEST_GOST)
+ sr.length = 4 + ISC_GOST_DIGESTLENGTH;
+
isc_buffer_forward(source, sr.length);
return (mem_tobuffer(target, sr.base, sr.length));
}
@@ -213,6 +225,9 @@ fromstruct_dlv(ARGS_FROMSTRUCT) {
case DNS_DSDIGEST_SHA256:
REQUIRE(dlv->length == ISC_SHA256_DIGESTLENGTH);
break;
+ case DNS_DSDIGEST_GOST:
+ REQUIRE(dlv->length == ISC_GOST_DIGESTLENGTH);
+ break;
}
UNUSED(type);
@@ -318,4 +333,9 @@ checknames_dlv(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_dlv(ARGS_COMPARE) {
+ return (compare_dlv(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_DLV_32769_C */
diff --git a/lib/dns/rdata/generic/dname_39.c b/lib/dns/rdata/generic/dname_39.c
index e36702d7de17..61356bfe3453 100644
--- a/lib/dns/rdata/generic/dname_39.c
+++ b/lib/dns/rdata/generic/dname_39.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dname_39.c,v 1.38 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: dname_39.c,v 1.40 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Wed Mar 15 16:52:38 PST 2000 by explorer */
@@ -230,4 +230,8 @@ checknames_dname(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_dname(ARGS_COMPARE) {
+ return (compare_dname(rdata1, rdata2));
+}
#endif /* RDATA_GENERIC_DNAME_39_C */
diff --git a/lib/dns/rdata/generic/dnskey_48.c b/lib/dns/rdata/generic/dnskey_48.c
index d526ca0db168..91fe9f8d5b61 100644
--- a/lib/dns/rdata/generic/dnskey_48.c
+++ b/lib/dns/rdata/generic/dnskey_48.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnskey_48.c,v 1.8 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: dnskey_48.c,v 1.10 2009-12-04 22:06:37 tbox Exp $ */
/*
* Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley.
@@ -76,6 +76,7 @@ totext_dnskey(ARGS_TOTEXT) {
char buf[sizeof("64000")];
unsigned int flags;
unsigned char algorithm;
+ char namebuf[DNS_NAME_FORMATSIZE];
REQUIRE(rdata->type == 48);
REQUIRE(rdata->length != 0);
@@ -105,6 +106,15 @@ totext_dnskey(ARGS_TOTEXT) {
if ((flags & 0xc000) == 0xc000)
return (ISC_R_SUCCESS);
+ if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0 &&
+ algorithm == DNS_KEYALG_PRIVATEDNS) {
+ dns_name_t name;
+ dns_name_init(&name, NULL);
+ dns_name_fromregion(&name, &sr);
+ dns_name_format(&name, namebuf, sizeof(namebuf));
+ } else
+ namebuf[0] = 0;
+
/* key */
if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
RETERR(str_totext(" (", target));
@@ -127,12 +137,18 @@ totext_dnskey(ARGS_TOTEXT) {
dns_rdata_toregion(rdata, &tmpr);
sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
RETERR(str_totext(buf, target));
+ if (algorithm == DNS_KEYALG_PRIVATEDNS) {
+ RETERR(str_totext(tctx->linebreak, target));
+ RETERR(str_totext("; alg = ", target));
+ RETERR(str_totext(namebuf, target));
+ }
}
return (ISC_R_SUCCESS);
}
static inline isc_result_t
fromwire_dnskey(ARGS_FROMWIRE) {
+ unsigned char algorithm;
isc_region_t sr;
REQUIRE(type == 48);
@@ -146,6 +162,18 @@ fromwire_dnskey(ARGS_FROMWIRE) {
if (sr.length < 4)
return (ISC_R_UNEXPECTEDEND);
+ algorithm = sr.base[3];
+ RETERR(mem_tobuffer(target, sr.base, 4));
+ isc_region_consume(&sr, 4);
+ isc_buffer_forward(source, 4);
+
+ if (algorithm == DNS_KEYALG_PRIVATEDNS) {
+ dns_name_t name;
+ dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
+ dns_name_init(&name, NULL);
+ RETERR(dns_name_fromwire(&name, source, dctx, options, target));
+ }
+ isc_buffer_activeregion(source, &sr);
isc_buffer_forward(source, sr.length);
return (mem_tobuffer(target, sr.base, sr.length));
}
@@ -309,4 +337,13 @@ checknames_dnskey(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_dnskey(ARGS_COMPARE) {
+
+ /*
+ * Treat ALG 253 (private DNS) subtype name case sensistively.
+ */
+ return (compare_dnskey(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_DNSKEY_48_C */
diff --git a/lib/dns/rdata/generic/ds_43.c b/lib/dns/rdata/generic/ds_43.c
index fcaa69b73c0f..ee74ab67713f 100644
--- a/lib/dns/rdata/generic/ds_43.c
+++ b/lib/dns/rdata/generic/ds_43.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ds_43.c,v 1.12 2007-06-18 23:47:43 tbox Exp $ */
+/* $Id: ds_43.c,v 1.16 2010-12-23 23:47:08 tbox Exp $ */
/* draft-ietf-dnsext-delegation-signer-05.txt */
@@ -74,12 +74,20 @@ fromtext_ds(ARGS_FROMTEXT) {
/*
* Digest.
*/
- if (c == DNS_DSDIGEST_SHA1)
+ switch (c) {
+ case DNS_DSDIGEST_SHA1:
length = ISC_SHA1_DIGESTLENGTH;
- else if (c == DNS_DSDIGEST_SHA256)
+ break;
+ case DNS_DSDIGEST_SHA256:
length = ISC_SHA256_DIGESTLENGTH;
- else
+ break;
+ case DNS_DSDIGEST_GOST:
+ length = ISC_GOST_DIGESTLENGTH;
+ break;
+ default:
length = -1;
+ break;
+ }
return (isc_hex_tobuffer(lexer, target, length));
}
@@ -152,7 +160,9 @@ fromwire_ds(ARGS_FROMWIRE) {
(sr.base[3] == DNS_DSDIGEST_SHA1 &&
sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
(sr.base[3] == DNS_DSDIGEST_SHA256 &&
- sr.length < 4 + ISC_SHA256_DIGESTLENGTH))
+ sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
+ (sr.base[3] == DNS_DSDIGEST_GOST &&
+ sr.length < 4 + ISC_GOST_DIGESTLENGTH))
return (ISC_R_UNEXPECTEDEND);
/*
@@ -164,6 +174,8 @@ fromwire_ds(ARGS_FROMWIRE) {
sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
else if (sr.base[3] == DNS_DSDIGEST_SHA256)
sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
+ else if (sr.base[3] == DNS_DSDIGEST_GOST)
+ sr.length = 4 + ISC_GOST_DIGESTLENGTH;
isc_buffer_forward(source, sr.length);
return (mem_tobuffer(target, sr.base, sr.length));
@@ -213,6 +225,9 @@ fromstruct_ds(ARGS_FROMSTRUCT) {
case DNS_DSDIGEST_SHA256:
REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH);
break;
+ case DNS_DSDIGEST_GOST:
+ REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH);
+ break;
}
UNUSED(type);
@@ -318,4 +333,9 @@ checknames_ds(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_ds(ARGS_COMPARE) {
+ return (compare_ds(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_DS_43_C */
diff --git a/lib/dns/rdata/generic/gpos_27.c b/lib/dns/rdata/generic/gpos_27.c
index 35fcc50c38a3..7a3992a4c59f 100644
--- a/lib/dns/rdata/generic/gpos_27.c
+++ b/lib/dns/rdata/generic/gpos_27.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: gpos_27.c,v 1.41 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: gpos_27.c,v 1.43 2009-12-04 22:06:37 tbox Exp $ */
/* reviewed: Wed Mar 15 16:48:45 PST 2000 by brister */
@@ -249,4 +249,9 @@ checknames_gpos(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_gpos(ARGS_COMPARE) {
+ return (compare_gpos(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_GPOS_27_C */
diff --git a/lib/dns/rdata/generic/hinfo_13.c b/lib/dns/rdata/generic/hinfo_13.c
index 7f31ab04569d..6b301e603394 100644
--- a/lib/dns/rdata/generic/hinfo_13.c
+++ b/lib/dns/rdata/generic/hinfo_13.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: hinfo_13.c,v 1.44 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: hinfo_13.c,v 1.46 2009-12-04 22:06:37 tbox Exp $ */
/*
* Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley.
@@ -221,4 +221,8 @@ checknames_hinfo(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_hinfo(ARGS_COMPARE) {
+ return (compare_hinfo(rdata1, rdata2));
+}
#endif /* RDATA_GENERIC_HINFO_13_C */
diff --git a/lib/dns/rdata/generic/hip_55.c b/lib/dns/rdata/generic/hip_55.c
new file mode 100644
index 000000000000..4cda9c6474d3
--- /dev/null
+++ b/lib/dns/rdata/generic/hip_55.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: hip_55.c,v 1.8 2011-01-13 04:59:26 tbox Exp $ */
+
+/* reviewed: TBC */
+
+/* RFC 5205 */
+
+#ifndef RDATA_GENERIC_HIP_5_C
+#define RDATA_GENERIC_HIP_5_C
+
+#define RRTYPE_HIP_ATTRIBUTES (0)
+
+static inline isc_result_t
+fromtext_hip(ARGS_FROMTEXT) {
+ isc_token_t token;
+ dns_name_t name;
+ isc_buffer_t buffer;
+ isc_buffer_t hit_len;
+ isc_buffer_t key_len;
+ unsigned char *start;
+ size_t len;
+
+ REQUIRE(type == 55);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(callbacks);
+
+ /*
+ * Dummy HIT len.
+ */
+ hit_len = *target;
+ RETERR(uint8_tobuffer(0, target));
+
+ /*
+ * Algorithm.
+ */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 0xffU)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint8_tobuffer(token.value.as_ulong, target));
+
+ /*
+ * Dummy KEY len.
+ */
+ key_len = *target;
+ RETERR(uint16_tobuffer(0, target));
+
+ /*
+ * HIT (base16).
+ */
+ start = isc_buffer_used(target);
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+ RETTOK(isc_hex_decodestring(DNS_AS_STR(token), target));
+
+ /*
+ * Fill in HIT len.
+ */
+ len = (unsigned char *)isc_buffer_used(target) - start;
+ if (len > 0xffU)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint8_tobuffer(len, &hit_len));
+
+ /*
+ * Public key (base64).
+ */
+ start = isc_buffer_used(target);
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+ RETTOK(isc_base64_decodestring(DNS_AS_STR(token), target));
+
+ /*
+ * Fill in KEY len.
+ */
+ len = (unsigned char *)isc_buffer_used(target) - start;
+ if (len > 0xffffU)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint16_tobuffer(len, &key_len));
+
+ /*
+ * Rendezvous Servers.
+ */
+ dns_name_init(&name, NULL);
+ do {
+ RETERR(isc_lex_getmastertoken(lexer, &token,
+ isc_tokentype_string,
+ ISC_TRUE));
+ if (token.type != isc_tokentype_string)
+ break;
+ buffer_fromregion(&buffer, &token.value.as_region);
+ origin = (origin != NULL) ? origin : dns_rootname;
+ RETTOK(dns_name_fromtext(&name, &buffer, origin, options,
+ target));
+ } while (1);
+
+ /*
+ * Let upper layer handle eol/eof.
+ */
+ isc_lex_ungettoken(lexer, &token);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+totext_hip(ARGS_TOTEXT) {
+ isc_region_t region;
+ dns_name_t name;
+ size_t length, key_len, hit_len;
+ unsigned char algorithm;
+ char buf[sizeof("225 ")];
+
+ REQUIRE(rdata->type == 55);
+ REQUIRE(rdata->length != 0);
+
+ dns_rdata_toregion(rdata, &region);
+
+ hit_len = uint8_fromregion(&region);
+ isc_region_consume(&region, 1);
+
+ algorithm = uint8_fromregion(&region);
+ isc_region_consume(&region, 1);
+
+ key_len = uint16_fromregion(&region);
+ isc_region_consume(&region, 2);
+
+ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
+ RETERR(str_totext("( ", target));
+
+ /*
+ * Algorithm
+ */
+ sprintf(buf, "%u ", algorithm);
+ RETERR(str_totext(buf, target));
+
+ /*
+ * HIT.
+ */
+ INSIST(hit_len < region.length);
+ length = region.length;
+ region.length = hit_len;
+ RETERR(isc_hex_totext(&region, 1, "", target));
+ region.length = length - hit_len;
+ RETERR(str_totext(tctx->linebreak, target));
+
+ /*
+ * Public KEY.
+ */
+ INSIST(key_len <= region.length);
+ length = region.length;
+ region.length = key_len;
+ RETERR(isc_base64_totext(&region, 1, "", target));
+ region.length = length - key_len;
+ RETERR(str_totext(tctx->linebreak, target));
+
+ /*
+ * Rendezvous Servers.
+ */
+ dns_name_init(&name, NULL);
+ while (region.length > 0) {
+ dns_name_fromregion(&name, &region);
+
+ RETERR(dns_name_totext(&name, ISC_FALSE, target));
+ isc_region_consume(&region, name.length);
+ if (region.length > 0)
+ RETERR(str_totext(tctx->linebreak, target));
+ }
+ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
+ RETERR(str_totext(" )", target));
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+fromwire_hip(ARGS_FROMWIRE) {
+ isc_region_t region, rr;
+ dns_name_t name;
+ isc_uint8_t hit_len;
+ isc_uint16_t key_len;
+
+ REQUIRE(type == 55);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ isc_buffer_activeregion(source, &region);
+ if (region.length < 4U)
+ RETERR(DNS_R_FORMERR);
+
+ rr = region;
+ hit_len = uint8_fromregion(&region);
+ if (hit_len == 0)
+ RETERR(DNS_R_FORMERR);
+ isc_region_consume(&region, 2); /* hit length + algorithm */
+ key_len = uint16_fromregion(&region);
+ if (key_len == 0)
+ RETERR(DNS_R_FORMERR);
+ isc_region_consume(&region, 2);
+ if (region.length < (unsigned) (hit_len + key_len))
+ RETERR(DNS_R_FORMERR);
+
+ RETERR(mem_tobuffer(target, rr.base, 4 + hit_len + key_len));
+ isc_buffer_forward(source, 4 + hit_len + key_len);
+
+ dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
+ while (isc_buffer_activelength(source) > 0) {
+ dns_name_init(&name, NULL);
+ RETERR(dns_name_fromwire(&name, source, dctx, options, target));
+ }
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+towire_hip(ARGS_TOWIRE) {
+ isc_region_t region;
+
+ REQUIRE(rdata->type == 55);
+ REQUIRE(rdata->length != 0);
+
+ UNUSED(cctx);
+
+ dns_rdata_toregion(rdata, &region);
+ return (mem_tobuffer(target, region.base, region.length));
+}
+
+static inline int
+compare_hip(ARGS_COMPARE) {
+ isc_region_t region1;
+ isc_region_t region2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 55);
+ REQUIRE(rdata1->length != 0);
+ REQUIRE(rdata2->length != 0);
+
+ dns_rdata_toregion(rdata1, &region1);
+ dns_rdata_toregion(rdata2, &region2);
+ return (isc_region_compare(&region1, &region2));
+}
+
+static inline isc_result_t
+fromstruct_hip(ARGS_FROMSTRUCT) {
+ dns_rdata_hip_t *hip = source;
+ dns_rdata_hip_t myhip;
+ isc_result_t result;
+
+ REQUIRE(type == 55);
+ REQUIRE(source != NULL);
+ REQUIRE(hip->common.rdtype == type);
+ REQUIRE(hip->common.rdclass == rdclass);
+ REQUIRE(hip->hit_len > 0 && hip->hit != NULL);
+ REQUIRE(hip->key_len > 0 && hip->key != NULL);
+ REQUIRE((hip->servers == NULL && hip->servers_len == 0) ||
+ (hip->servers != NULL && hip->servers_len != 0));
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ RETERR(uint8_tobuffer(hip->hit_len, target));
+ RETERR(uint8_tobuffer(hip->algorithm, target));
+ RETERR(uint16_tobuffer(hip->key_len, target));
+ RETERR(mem_tobuffer(target, hip->hit, hip->hit_len));
+ RETERR(mem_tobuffer(target, hip->key, hip->key_len));
+
+ myhip = *hip;
+ for (result = dns_rdata_hip_first(&myhip);
+ result == ISC_R_SUCCESS;
+ result = dns_rdata_hip_next(&myhip))
+ /* empty */;
+
+ return(mem_tobuffer(target, hip->servers, hip->servers_len));
+}
+
+static inline isc_result_t
+tostruct_hip(ARGS_TOSTRUCT) {
+ isc_region_t region;
+ dns_rdata_hip_t *hip = target;
+
+ REQUIRE(rdata->type == 55);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length != 0);
+
+ hip->common.rdclass = rdata->rdclass;
+ hip->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&hip->common, link);
+
+ dns_rdata_toregion(rdata, &region);
+
+ hip->hit_len = uint8_fromregion(&region);
+ isc_region_consume(&region, 1);
+
+ hip->algorithm = uint8_fromregion(&region);
+ isc_region_consume(&region, 1);
+
+ hip->key_len = uint16_fromregion(&region);
+ isc_region_consume(&region, 2);
+
+ hip->hit = hip->key = hip->servers = NULL;
+
+ hip->hit = mem_maybedup(mctx, region.base, hip->hit_len);
+ if (hip->hit == NULL)
+ goto cleanup;
+ isc_region_consume(&region, hip->hit_len);
+
+ hip->key = mem_maybedup(mctx, region.base, hip->key_len);
+ if (hip->key == NULL)
+ goto cleanup;
+ isc_region_consume(&region, hip->key_len);
+
+ hip->servers_len = region.length;
+ if (hip->servers_len != 0) {
+ hip->servers = mem_maybedup(mctx, region.base, region.length);
+ if (hip->servers == NULL)
+ goto cleanup;
+ }
+
+ hip->offset = hip->servers_len;
+ hip->mctx = mctx;
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (hip->hit != NULL)
+ isc_mem_free(mctx, hip->hit);
+ if (hip->key != NULL)
+ isc_mem_free(mctx, hip->key);
+ if (hip->servers != NULL)
+ isc_mem_free(mctx, hip->servers);
+ return (ISC_R_NOMEMORY);
+
+}
+
+static inline void
+freestruct_hip(ARGS_FREESTRUCT) {
+ dns_rdata_hip_t *hip = source;
+
+ REQUIRE(source != NULL);
+
+ if (hip->mctx == NULL)
+ return;
+
+ isc_mem_free(hip->mctx, hip->hit);
+ isc_mem_free(hip->mctx, hip->key);
+ if (hip->servers != NULL)
+ isc_mem_free(hip->mctx, hip->servers);
+ hip->mctx = NULL;
+}
+
+static inline isc_result_t
+additionaldata_hip(ARGS_ADDLDATA) {
+ UNUSED(rdata);
+ UNUSED(add);
+ UNUSED(arg);
+
+ REQUIRE(rdata->type == 55);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_hip(ARGS_DIGEST) {
+ isc_region_t r;
+
+ REQUIRE(rdata->type == 55);
+
+ dns_rdata_toregion(rdata, &r);
+ return ((digest)(arg, &r));
+}
+
+static inline isc_boolean_t
+checkowner_hip(ARGS_CHECKOWNER) {
+
+ REQUIRE(type == 55);
+
+ UNUSED(name);
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(wildcard);
+
+ return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_hip(ARGS_CHECKNAMES) {
+
+ REQUIRE(rdata->type == 55);
+
+ UNUSED(rdata);
+ UNUSED(owner);
+ UNUSED(bad);
+
+ return (ISC_TRUE);
+}
+
+isc_result_t
+dns_rdata_hip_first(dns_rdata_hip_t *hip) {
+ if (hip->servers_len == 0)
+ return (ISC_R_NOMORE);
+ hip->offset = 0;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_rdata_hip_next(dns_rdata_hip_t *hip) {
+ isc_region_t region;
+ dns_name_t name;
+
+ if (hip->offset >= hip->servers_len)
+ return (ISC_R_NOMORE);
+
+ region.base = hip->servers + hip->offset;
+ region.length = hip->servers_len - hip->offset;
+ dns_name_init(&name, NULL);
+ dns_name_fromregion(&name, &region);
+ hip->offset += name.length;
+ INSIST(hip->offset <= hip->servers_len);
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_rdata_hip_current(dns_rdata_hip_t *hip, dns_name_t *name) {
+ isc_region_t region;
+
+ REQUIRE(hip->offset < hip->servers_len);
+
+ region.base = hip->servers + hip->offset;
+ region.length = hip->servers_len - hip->offset;
+ dns_name_fromregion(name, &region);
+
+ INSIST(name->length + hip->offset <= hip->servers_len);
+}
+
+static inline int
+casecompare_hip(ARGS_COMPARE) {
+ isc_region_t r1;
+ isc_region_t r2;
+ dns_name_t name1;
+ dns_name_t name2;
+ int order;
+ isc_uint8_t hit_len;
+ isc_uint16_t key_len;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 55);
+ REQUIRE(rdata1->length != 0);
+ REQUIRE(rdata2->length != 0);
+
+ dns_rdata_toregion(rdata1, &r1);
+ dns_rdata_toregion(rdata2, &r2);
+
+ INSIST(r1.length > 4);
+ INSIST(r2.length > 4);
+ r1.length = 4;
+ r2.length = 4;
+ order = isc_region_compare(&r1, &r2);
+ if (order != 0)
+ return (order);
+
+ hit_len = uint8_fromregion(&r1);
+ isc_region_consume(&r1, 2); /* hit length + algorithm */
+ key_len = uint16_fromregion(&r1);
+
+ dns_rdata_toregion(rdata1, &r1);
+ dns_rdata_toregion(rdata2, &r2);
+ isc_region_consume(&r1, 4);
+ isc_region_consume(&r2, 4);
+ INSIST(r1.length >= (unsigned) (hit_len + key_len));
+ INSIST(r2.length >= (unsigned) (hit_len + key_len));
+ order = isc_region_compare(&r1, &r2);
+ if (order != 0)
+ return (order);
+ isc_region_consume(&r1, hit_len + key_len);
+ isc_region_consume(&r2, hit_len + key_len);
+
+ dns_name_init(&name1, NULL);
+ dns_name_init(&name2, NULL);
+ while (r1.length != 0 && r2.length != 0) {
+ dns_name_fromregion(&name1, &r1);
+ dns_name_fromregion(&name2, &r2);
+ order = dns_name_rdatacompare(&name1, &name2);
+ if (order != 0)
+ return (order);
+
+ isc_region_consume(&r1, name_length(&name1));
+ isc_region_consume(&r2, name_length(&name2));
+ }
+ return (isc_region_compare(&r1, &r2));
+}
+
+#endif /* RDATA_GENERIC_HIP_5_C */
diff --git a/lib/dns/rdata/generic/hip_55.h b/lib/dns/rdata/generic/hip_55.h
new file mode 100644
index 000000000000..79828ad1e144
--- /dev/null
+++ b/lib/dns/rdata/generic/hip_55.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: hip_55.h,v 1.2 2009-02-26 06:09:19 marka Exp $ */
+
+#ifndef GENERIC_HIP_5_H
+#define GENERIC_HIP_5_H 1
+
+/* RFC 5205 */
+
+typedef struct dns_rdata_hip {
+ dns_rdatacommon_t common;
+ isc_mem_t * mctx;
+ unsigned char * hit;
+ unsigned char * key;
+ unsigned char * servers;
+ isc_uint8_t algorithm;
+ isc_uint8_t hit_len;
+ isc_uint16_t key_len;
+ isc_uint16_t servers_len;
+ /* Private */
+ isc_uint16_t offset;
+} dns_rdata_hip_t;
+
+isc_result_t
+dns_rdata_hip_first(dns_rdata_hip_t *);
+
+isc_result_t
+dns_rdata_hip_next(dns_rdata_hip_t *);
+
+void
+dns_rdata_hip_current(dns_rdata_hip_t *, dns_name_t *);
+
+#endif /* GENERIC_HIP_5_H */
diff --git a/lib/dns/rdata/generic/ipseckey_45.c b/lib/dns/rdata/generic/ipseckey_45.c
index f971d49a0a46..995a13535e7b 100644
--- a/lib/dns/rdata/generic/ipseckey_45.c
+++ b/lib/dns/rdata/generic/ipseckey_45.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ipseckey_45.c,v 1.4.332.5 2011-01-13 04:48:23 tbox Exp $ */
+/* $Id: ipseckey_45.c,v 1.11 2011-01-13 04:59:26 tbox Exp $ */
#ifndef RDATA_GENERIC_IPSECKEY_45_C
#define RDATA_GENERIC_IPSECKEY_45_C
@@ -456,4 +456,43 @@ checknames_ipseckey(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_ipseckey(ARGS_COMPARE) {
+ isc_region_t region1;
+ isc_region_t region2;
+ dns_name_t name1;
+ dns_name_t name2;
+ int order;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 45);
+ REQUIRE(rdata1->length >= 3);
+ REQUIRE(rdata2->length >= 3);
+
+ dns_rdata_toregion(rdata1, &region1);
+ dns_rdata_toregion(rdata2, &region2);
+
+ if (memcmp(region1.base, region2.base, 3) != 0 || region1.base[1] != 3)
+ return (isc_region_compare(&region1, &region2));
+
+ dns_name_init(&name1, NULL);
+ dns_name_init(&name2, NULL);
+
+ isc_region_consume(&region1, 3);
+ isc_region_consume(&region2, 3);
+
+ dns_name_fromregion(&name1, &region1);
+ dns_name_fromregion(&name2, &region2);
+
+ order = dns_name_rdatacompare(&name1, &name2);
+ if (order != 0)
+ return (order);
+
+ isc_region_consume(&region1, name_length(&name1));
+ isc_region_consume(&region2, name_length(&name2));
+
+ return (isc_region_compare(&region1, &region2));
+}
+
#endif /* RDATA_GENERIC_IPSECKEY_45_C */
diff --git a/lib/dns/rdata/generic/isdn_20.c b/lib/dns/rdata/generic/isdn_20.c
index a9e03b2ce620..b58776ca8a35 100644
--- a/lib/dns/rdata/generic/isdn_20.c
+++ b/lib/dns/rdata/generic/isdn_20.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: isdn_20.c,v 1.38 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: isdn_20.c,v 1.40 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Wed Mar 15 16:53:11 PST 2000 by bwelling */
@@ -231,4 +231,9 @@ checknames_isdn(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_isdn(ARGS_COMPARE) {
+ return (compare_isdn(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_ISDN_20_C */
diff --git a/lib/dns/rdata/generic/key_25.c b/lib/dns/rdata/generic/key_25.c
index acd314cba0c0..6fe27cbbc35c 100644
--- a/lib/dns/rdata/generic/key_25.c
+++ b/lib/dns/rdata/generic/key_25.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: key_25.c,v 1.51 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: key_25.c,v 1.53 2009-12-04 22:06:37 tbox Exp $ */
/*
* Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley.
@@ -76,6 +76,7 @@ totext_key(ARGS_TOTEXT) {
char buf[sizeof("64000")];
unsigned int flags;
unsigned char algorithm;
+ char namebuf[DNS_NAME_FORMATSIZE];
REQUIRE(rdata->type == 25);
REQUIRE(rdata->length != 0);
@@ -105,6 +106,15 @@ totext_key(ARGS_TOTEXT) {
if ((flags & 0xc000) == 0xc000)
return (ISC_R_SUCCESS);
+ if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0 &&
+ algorithm == DNS_KEYALG_PRIVATEDNS) {
+ dns_name_t name;
+ dns_name_init(&name, NULL);
+ dns_name_fromregion(&name, &sr);
+ dns_name_format(&name, namebuf, sizeof(namebuf));
+ } else
+ namebuf[0] = 0;
+
/* key */
if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
RETERR(str_totext(" (", target));
@@ -127,12 +137,18 @@ totext_key(ARGS_TOTEXT) {
dns_rdata_toregion(rdata, &tmpr);
sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
RETERR(str_totext(buf, target));
+ if (algorithm == DNS_KEYALG_PRIVATEDNS) {
+ RETERR(str_totext(tctx->linebreak, target));
+ RETERR(str_totext("; alg = ", target));
+ RETERR(str_totext(namebuf, target));
+ }
}
return (ISC_R_SUCCESS);
}
static inline isc_result_t
fromwire_key(ARGS_FROMWIRE) {
+ unsigned char algorithm;
isc_region_t sr;
REQUIRE(type == 25);
@@ -146,6 +162,18 @@ fromwire_key(ARGS_FROMWIRE) {
if (sr.length < 4)
return (ISC_R_UNEXPECTEDEND);
+ algorithm = sr.base[3];
+ RETERR(mem_tobuffer(target, sr.base, 4));
+ isc_region_consume(&sr, 4);
+ isc_buffer_forward(source, 4);
+
+ if (algorithm == DNS_KEYALG_PRIVATEDNS) {
+ dns_name_t name;
+ dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
+ dns_name_init(&name, NULL);
+ RETERR(dns_name_fromwire(&name, source, dctx, options, target));
+ }
+ isc_buffer_activeregion(source, &sr);
isc_buffer_forward(source, sr.length);
return (mem_tobuffer(target, sr.base, sr.length));
}
@@ -309,4 +337,9 @@ checknames_key(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_key(ARGS_COMPARE) {
+ return (compare_key(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_KEY_25_C */
diff --git a/lib/dns/rdata/generic/keydata_65533.c b/lib/dns/rdata/generic/keydata_65533.c
new file mode 100644
index 000000000000..3636209d56e0
--- /dev/null
+++ b/lib/dns/rdata/generic/keydata_65533.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: keydata_65533.c,v 1.3 2009-12-04 21:09:33 marka Exp $ */
+
+#ifndef GENERIC_KEYDATA_65533_C
+#define GENERIC_KEYDATA_65533_C 1
+
+#include <dst/dst.h>
+
+#define RRTYPE_KEYDATA_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
+
+static inline isc_result_t
+fromtext_keydata(ARGS_FROMTEXT) {
+ isc_token_t token;
+ dns_secalg_t alg;
+ dns_secproto_t proto;
+ dns_keyflags_t flags;
+ isc_uint32_t refresh, addhd, removehd;
+
+ REQUIRE(type == 65533);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(origin);
+ UNUSED(options);
+ UNUSED(callbacks);
+
+ /* refresh timer */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+ RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &refresh));
+ RETERR(uint32_tobuffer(refresh, target));
+
+ /* add hold-down */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+ RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &addhd));
+ RETERR(uint32_tobuffer(addhd, target));
+
+ /* remove hold-down */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+ RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &removehd));
+ RETERR(uint32_tobuffer(removehd, target));
+
+ /* flags */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+ RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion));
+ RETERR(uint16_tobuffer(flags, target));
+
+ /* protocol */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+ RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion));
+ RETERR(mem_tobuffer(target, &proto, 1));
+
+ /* algorithm */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+ RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
+ RETERR(mem_tobuffer(target, &alg, 1));
+
+ /* No Key? */
+ if ((flags & 0xc000) == 0xc000)
+ return (ISC_R_SUCCESS);
+
+ return (isc_base64_tobuffer(lexer, target, -1));
+}
+
+static inline isc_result_t
+totext_keydata(ARGS_TOTEXT) {
+ isc_region_t sr;
+ char buf[sizeof("64000")];
+ unsigned int flags;
+ unsigned char algorithm;
+ unsigned long when;
+
+ REQUIRE(rdata->type == 65533);
+ REQUIRE(rdata->length != 0);
+
+ dns_rdata_toregion(rdata, &sr);
+
+ /* refresh timer */
+ when = uint32_fromregion(&sr);
+ isc_region_consume(&sr, 4);
+ RETERR(dns_time32_totext(when, target));
+ RETERR(str_totext(" ", target));
+
+ /* add hold-down */
+ when = uint32_fromregion(&sr);
+ isc_region_consume(&sr, 4);
+ RETERR(dns_time32_totext(when, target));
+ RETERR(str_totext(" ", target));
+
+ /* remove hold-down */
+ when = uint32_fromregion(&sr);
+ isc_region_consume(&sr, 4);
+ RETERR(dns_time32_totext(when, target));
+ RETERR(str_totext(" ", target));
+
+ /* flags */
+ flags = uint16_fromregion(&sr);
+ isc_region_consume(&sr, 2);
+ sprintf(buf, "%u", flags);
+ RETERR(str_totext(buf, target));
+ RETERR(str_totext(" ", target));
+
+ /* protocol */
+ sprintf(buf, "%u", sr.base[0]);
+ isc_region_consume(&sr, 1);
+ RETERR(str_totext(buf, target));
+ RETERR(str_totext(" ", target));
+
+ /* algorithm */
+ algorithm = sr.base[0];
+ sprintf(buf, "%u", algorithm);
+ isc_region_consume(&sr, 1);
+ RETERR(str_totext(buf, target));
+
+ /* No Key? */
+ if ((flags & 0xc000) == 0xc000)
+ return (ISC_R_SUCCESS);
+
+ /* key */
+ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
+ RETERR(str_totext(" (", target));
+ RETERR(str_totext(tctx->linebreak, target));
+ RETERR(isc_base64_totext(&sr, tctx->width - 2,
+ tctx->linebreak, target));
+
+ if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0)
+ RETERR(str_totext(tctx->linebreak, target));
+ else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
+ RETERR(str_totext(" ", target));
+
+ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
+ RETERR(str_totext(")", target));
+
+ if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) {
+ isc_region_t tmpr;
+
+ RETERR(str_totext(" ; key id = ", target));
+ dns_rdata_toregion(rdata, &tmpr);
+ /* Skip over refresh, addhd, and removehd */
+ isc_region_consume(&tmpr, 12);
+ sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
+ RETERR(str_totext(buf, target));
+ }
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+fromwire_keydata(ARGS_FROMWIRE) {
+ isc_region_t sr;
+
+ REQUIRE(type == 65533);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(dctx);
+ UNUSED(options);
+
+ isc_buffer_activeregion(source, &sr);
+ if (sr.length < 4)
+ return (ISC_R_UNEXPECTEDEND);
+
+ isc_buffer_forward(source, sr.length);
+ return (mem_tobuffer(target, sr.base, sr.length));
+}
+
+static inline isc_result_t
+towire_keydata(ARGS_TOWIRE) {
+ isc_region_t sr;
+
+ REQUIRE(rdata->type == 65533);
+ REQUIRE(rdata->length != 0);
+
+ UNUSED(cctx);
+
+ dns_rdata_toregion(rdata, &sr);
+ return (mem_tobuffer(target, sr.base, sr.length));
+}
+
+static inline int
+compare_keydata(ARGS_COMPARE) {
+ isc_region_t r1;
+ isc_region_t r2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 65533);
+ REQUIRE(rdata1->length != 0);
+ REQUIRE(rdata2->length != 0);
+
+ dns_rdata_toregion(rdata1, &r1);
+ dns_rdata_toregion(rdata2, &r2);
+ return (isc_region_compare(&r1, &r2));
+}
+
+static inline isc_result_t
+fromstruct_keydata(ARGS_FROMSTRUCT) {
+ dns_rdata_keydata_t *keydata = source;
+
+ REQUIRE(type == 65533);
+ REQUIRE(source != NULL);
+ REQUIRE(keydata->common.rdtype == type);
+ REQUIRE(keydata->common.rdclass == rdclass);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ /* Refresh timer */
+ RETERR(uint32_tobuffer(keydata->refresh, target));
+
+ /* Add hold-down */
+ RETERR(uint32_tobuffer(keydata->addhd, target));
+
+ /* Remove hold-down */
+ RETERR(uint32_tobuffer(keydata->removehd, target));
+
+ /* Flags */
+ RETERR(uint16_tobuffer(keydata->flags, target));
+
+ /* Protocol */
+ RETERR(uint8_tobuffer(keydata->protocol, target));
+
+ /* Algorithm */
+ RETERR(uint8_tobuffer(keydata->algorithm, target));
+
+ /* Data */
+ return (mem_tobuffer(target, keydata->data, keydata->datalen));
+}
+
+static inline isc_result_t
+tostruct_keydata(ARGS_TOSTRUCT) {
+ dns_rdata_keydata_t *keydata = target;
+ isc_region_t sr;
+
+ REQUIRE(rdata->type == 65533);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length != 0);
+
+ keydata->common.rdclass = rdata->rdclass;
+ keydata->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&keydata->common, link);
+
+ dns_rdata_toregion(rdata, &sr);
+
+ /* Refresh timer */
+ if (sr.length < 4)
+ return (ISC_R_UNEXPECTEDEND);
+ keydata->refresh = uint32_fromregion(&sr);
+ isc_region_consume(&sr, 4);
+
+ /* Add hold-down */
+ if (sr.length < 4)
+ return (ISC_R_UNEXPECTEDEND);
+ keydata->addhd = uint32_fromregion(&sr);
+ isc_region_consume(&sr, 4);
+
+ /* Remove hold-down */
+ if (sr.length < 4)
+ return (ISC_R_UNEXPECTEDEND);
+ keydata->removehd = uint32_fromregion(&sr);
+ isc_region_consume(&sr, 4);
+
+ /* Flags */
+ if (sr.length < 2)
+ return (ISC_R_UNEXPECTEDEND);
+ keydata->flags = uint16_fromregion(&sr);
+ isc_region_consume(&sr, 2);
+
+ /* Protocol */
+ if (sr.length < 1)
+ return (ISC_R_UNEXPECTEDEND);
+ keydata->protocol = uint8_fromregion(&sr);
+ isc_region_consume(&sr, 1);
+
+ /* Algorithm */
+ if (sr.length < 1)
+ return (ISC_R_UNEXPECTEDEND);
+ keydata->algorithm = uint8_fromregion(&sr);
+ isc_region_consume(&sr, 1);
+
+ /* Data */
+ keydata->datalen = sr.length;
+ keydata->data = mem_maybedup(mctx, sr.base, keydata->datalen);
+ if (keydata->data == NULL)
+ return (ISC_R_NOMEMORY);
+
+ keydata->mctx = mctx;
+ return (ISC_R_SUCCESS);
+}
+
+static inline void
+freestruct_keydata(ARGS_FREESTRUCT) {
+ dns_rdata_keydata_t *keydata = (dns_rdata_keydata_t *) source;
+
+ REQUIRE(source != NULL);
+ REQUIRE(keydata->common.rdtype == 65533);
+
+ if (keydata->mctx == NULL)
+ return;
+
+ if (keydata->data != NULL)
+ isc_mem_free(keydata->mctx, keydata->data);
+ keydata->mctx = NULL;
+}
+
+static inline isc_result_t
+additionaldata_keydata(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == 65533);
+
+ UNUSED(rdata);
+ UNUSED(add);
+ UNUSED(arg);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_keydata(ARGS_DIGEST) {
+ isc_region_t r;
+
+ REQUIRE(rdata->type == 65533);
+
+ dns_rdata_toregion(rdata, &r);
+
+ return ((digest)(arg, &r));
+}
+
+static inline isc_boolean_t
+checkowner_keydata(ARGS_CHECKOWNER) {
+
+ REQUIRE(type == 65533);
+
+ UNUSED(name);
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(wildcard);
+
+ return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_keydata(ARGS_CHECKNAMES) {
+
+ REQUIRE(rdata->type == 65533);
+
+ UNUSED(rdata);
+ UNUSED(owner);
+ UNUSED(bad);
+
+ return (ISC_TRUE);
+}
+
+static inline int
+casecompare_keydata(ARGS_COMPARE) {
+ return (compare_keydata(rdata1, rdata2));
+}
+
+#endif /* GENERIC_KEYDATA_65533_C */
diff --git a/lib/dns/rdata/generic/keydata_65533.h b/lib/dns/rdata/generic/keydata_65533.h
new file mode 100644
index 000000000000..21cb1ba81251
--- /dev/null
+++ b/lib/dns/rdata/generic/keydata_65533.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef GENERIC_KEYDATA_65533_H
+#define GENERIC_KEYDATA_65533_H 1
+
+/* $Id: keydata_65533.h,v 1.2 2009-06-30 02:52:32 each Exp $ */
+
+typedef struct dns_rdata_keydata {
+ dns_rdatacommon_t common;
+ isc_mem_t * mctx;
+ isc_uint32_t refresh; /* Timer for refreshing data */
+ isc_uint32_t addhd; /* Hold-down timer for adding */
+ isc_uint32_t removehd; /* Hold-down timer for removing */
+ isc_uint16_t flags; /* Copy of DNSKEY_48 */
+ isc_uint8_t protocol;
+ isc_uint8_t algorithm;
+ isc_uint16_t datalen;
+ unsigned char * data;
+} dns_rdata_keydata_t;
+
+#endif /* GENERIC_KEYDATA_65533_H */
diff --git a/lib/dns/rdata/generic/loc_29.c b/lib/dns/rdata/generic/loc_29.c
index a5efb01ae621..62d5cd0a3fae 100644
--- a/lib/dns/rdata/generic/loc_29.c
+++ b/lib/dns/rdata/generic/loc_29.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: loc_29.c,v 1.45.332.4 2009-02-17 05:54:12 marka Exp $ */
+/* $Id: loc_29.c,v 1.50 2009-12-04 21:09:33 marka Exp $ */
/* Reviewed: Wed Mar 15 18:13:09 PST 2000 by explorer */
@@ -796,4 +796,9 @@ checknames_loc(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_loc(ARGS_COMPARE) {
+ return (compare_loc(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_LOC_29_C */
diff --git a/lib/dns/rdata/generic/mb_7.c b/lib/dns/rdata/generic/mb_7.c
index c47365a4c7c2..7a4af1cc7dd8 100644
--- a/lib/dns/rdata/generic/mb_7.c
+++ b/lib/dns/rdata/generic/mb_7.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mb_7.c,v 1.45 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: mb_7.c,v 1.47 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Wed Mar 15 17:31:26 PST 2000 by bwelling */
@@ -69,7 +69,7 @@ totext_mb(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_mb(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
REQUIRE(type == 7);
@@ -78,8 +78,8 @@ fromwire_mb(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
+ dns_name_init(&name, NULL);
+ return (dns_name_fromwire(&name, source, dctx, options, target));
}
static inline isc_result_t
@@ -231,4 +231,9 @@ checknames_mb(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_mb(ARGS_COMPARE) {
+ return (compare_mb(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_MB_7_C */
diff --git a/lib/dns/rdata/generic/md_3.c b/lib/dns/rdata/generic/md_3.c
index 269f9be5198f..ee06274bc815 100644
--- a/lib/dns/rdata/generic/md_3.c
+++ b/lib/dns/rdata/generic/md_3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: md_3.c,v 1.47 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: md_3.c,v 1.49 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Wed Mar 15 17:48:20 PST 2000 by bwelling */
@@ -69,7 +69,7 @@ totext_md(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_md(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
REQUIRE(type == 3);
@@ -78,8 +78,8 @@ fromwire_md(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
+ dns_name_init(&name, NULL);
+ return (dns_name_fromwire(&name, source, dctx, options, target));
}
static inline isc_result_t
@@ -233,4 +233,9 @@ checknames_md(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_md(ARGS_COMPARE) {
+ return (compare_md(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_MD_3_C */
diff --git a/lib/dns/rdata/generic/mf_4.c b/lib/dns/rdata/generic/mf_4.c
index 9223384acdeb..d14bf6c864e7 100644
--- a/lib/dns/rdata/generic/mf_4.c
+++ b/lib/dns/rdata/generic/mf_4.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mf_4.c,v 1.45 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: mf_4.c,v 1.47 2009-12-04 22:06:37 tbox Exp $ */
/* reviewed: Wed Mar 15 17:47:33 PST 2000 by brister */
@@ -69,7 +69,7 @@ totext_mf(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_mf(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
REQUIRE(type == 4);
@@ -78,8 +78,8 @@ fromwire_mf(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
+ dns_name_init(&name, NULL);
+ return (dns_name_fromwire(&name, source, dctx, options, target));
}
static inline isc_result_t
@@ -232,4 +232,9 @@ checknames_mf(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_mf(ARGS_COMPARE) {
+ return (compare_mf(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_MF_4_C */
diff --git a/lib/dns/rdata/generic/mg_8.c b/lib/dns/rdata/generic/mg_8.c
index ba7630c480b4..c1d553a38ea7 100644
--- a/lib/dns/rdata/generic/mg_8.c
+++ b/lib/dns/rdata/generic/mg_8.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mg_8.c,v 1.43 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: mg_8.c,v 1.45 2009-12-04 22:06:37 tbox Exp $ */
/* reviewed: Wed Mar 15 17:49:21 PST 2000 by brister */
@@ -69,7 +69,7 @@ totext_mg(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_mg(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
REQUIRE(type == 8);
@@ -78,8 +78,8 @@ fromwire_mg(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
+ dns_name_init(&name, NULL);
+ return (dns_name_fromwire(&name, source, dctx, options, target));
}
static inline isc_result_t
@@ -227,4 +227,9 @@ checknames_mg(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_mg(ARGS_COMPARE) {
+ return (compare_mg(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_MG_8_C */
diff --git a/lib/dns/rdata/generic/minfo_14.c b/lib/dns/rdata/generic/minfo_14.c
index 6848a4edc840..881e624a84e1 100644
--- a/lib/dns/rdata/generic/minfo_14.c
+++ b/lib/dns/rdata/generic/minfo_14.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: minfo_14.c,v 1.45 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: minfo_14.c,v 1.47 2009-12-04 22:06:37 tbox Exp $ */
/* reviewed: Wed Mar 15 17:45:32 PST 2000 by brister */
@@ -93,8 +93,8 @@ totext_minfo(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_minfo(ARGS_FROMWIRE) {
- dns_name_t rmail;
- dns_name_t email;
+ dns_name_t rmail;
+ dns_name_t email;
REQUIRE(type == 14);
@@ -103,11 +103,11 @@ fromwire_minfo(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
- dns_name_init(&rmail, NULL);
- dns_name_init(&email, NULL);
+ dns_name_init(&rmail, NULL);
+ dns_name_init(&email, NULL);
- RETERR(dns_name_fromwire(&rmail, source, dctx, options, target));
- return (dns_name_fromwire(&email, source, dctx, options, target));
+ RETERR(dns_name_fromwire(&rmail, source, dctx, options, target));
+ return (dns_name_fromwire(&email, source, dctx, options, target));
}
static inline isc_result_t
@@ -321,4 +321,9 @@ checknames_minfo(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_minfo(ARGS_COMPARE) {
+ return (compare_minfo(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_MINFO_14_C */
diff --git a/lib/dns/rdata/generic/mr_9.c b/lib/dns/rdata/generic/mr_9.c
index a480bd434855..6c02108b4383 100644
--- a/lib/dns/rdata/generic/mr_9.c
+++ b/lib/dns/rdata/generic/mr_9.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mr_9.c,v 1.42 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: mr_9.c,v 1.44 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Wed Mar 15 21:30:35 EST 2000 by tale */
@@ -69,7 +69,7 @@ totext_mr(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_mr(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
REQUIRE(type == 9);
@@ -78,8 +78,8 @@ fromwire_mr(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
+ dns_name_init(&name, NULL);
+ return (dns_name_fromwire(&name, source, dctx, options, target));
}
static inline isc_result_t
@@ -228,4 +228,9 @@ checknames_mr(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_mr(ARGS_COMPARE) {
+ return (compare_mr(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_MR_9_C */
diff --git a/lib/dns/rdata/generic/mx_15.c b/lib/dns/rdata/generic/mx_15.c
index b7b43f392333..0d8e6cd864dd 100644
--- a/lib/dns/rdata/generic/mx_15.c
+++ b/lib/dns/rdata/generic/mx_15.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mx_15.c,v 1.56 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: mx_15.c,v 1.58 2009-12-04 22:06:37 tbox Exp $ */
/* reviewed: Wed Mar 15 18:05:46 PST 2000 by brister */
@@ -120,7 +120,7 @@ totext_mx(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_mx(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
isc_region_t sregion;
REQUIRE(type == 15);
@@ -130,7 +130,7 @@ fromwire_mx(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
- dns_name_init(&name, NULL);
+ dns_name_init(&name, NULL);
isc_buffer_activeregion(source, &sregion);
if (sregion.length < 2)
@@ -316,4 +316,9 @@ checknames_mx(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_mx(ARGS_COMPARE) {
+ return (compare_mx(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_MX_15_C */
diff --git a/lib/dns/rdata/generic/ns_2.c b/lib/dns/rdata/generic/ns_2.c
index 14e0c9db0a95..f3df004adc5b 100644
--- a/lib/dns/rdata/generic/ns_2.c
+++ b/lib/dns/rdata/generic/ns_2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ns_2.c,v 1.46 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: ns_2.c,v 1.48 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Wed Mar 15 18:15:00 PST 2000 by bwelling */
@@ -77,7 +77,7 @@ totext_ns(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_ns(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
REQUIRE(type == 2);
@@ -86,8 +86,8 @@ fromwire_ns(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
+ dns_name_init(&name, NULL);
+ return (dns_name_fromwire(&name, source, dctx, options, target));
}
static inline isc_result_t
@@ -248,4 +248,9 @@ checknames_ns(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_ns(ARGS_COMPARE) {
+ return (compare_ns(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_NS_2_C */
diff --git a/lib/dns/rdata/generic/nsec3_50.c b/lib/dns/rdata/generic/nsec3_50.c
index 890af1aab5da..d21b009fe5ba 100644
--- a/lib/dns/rdata/generic/nsec3_50.c
+++ b/lib/dns/rdata/generic/nsec3_50.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3_50.c,v 1.4.48.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: nsec3_50.c,v 1.7 2009-12-04 21:09:34 marka Exp $ */
/*
* Copyright (C) 2004 Nominet, Ltd.
@@ -478,4 +478,9 @@ checknames_nsec3(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_nsec3(ARGS_COMPARE) {
+ return (compare_nsec3(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_NSEC3_50_C */
diff --git a/lib/dns/rdata/generic/nsec3param_51.c b/lib/dns/rdata/generic/nsec3param_51.c
index 14570156eb44..01beb3c17b2f 100644
--- a/lib/dns/rdata/generic/nsec3param_51.c
+++ b/lib/dns/rdata/generic/nsec3param_51.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3param_51.c,v 1.4.48.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: nsec3param_51.c,v 1.7 2009-12-04 21:09:34 marka Exp $ */
/*
* Copyright (C) 2004 Nominet, Ltd.
@@ -311,4 +311,9 @@ checknames_nsec3param(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_nsec3param(ARGS_COMPARE) {
+ return (compare_nsec3param(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_NSEC3PARAM_51_C */
diff --git a/lib/dns/rdata/generic/nsec_47.c b/lib/dns/rdata/generic/nsec_47.c
index ace1035d1872..5807d5f6b7bd 100644
--- a/lib/dns/rdata/generic/nsec_47.c
+++ b/lib/dns/rdata/generic/nsec_47.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007, 2008, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec_47.c,v 1.11.82.2 2011-01-13 04:48:23 tbox Exp $ */
+/* $Id: nsec_47.c,v 1.15 2011-01-13 04:59:26 tbox Exp $ */
/* reviewed: Wed Mar 15 18:21:15 PST 2000 by brister */
@@ -361,4 +361,36 @@ checknames_nsec(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_nsec(ARGS_COMPARE) {
+ isc_region_t region1;
+ isc_region_t region2;
+ dns_name_t name1;
+ dns_name_t name2;
+ int order;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 47);
+ REQUIRE(rdata1->length != 0);
+ REQUIRE(rdata2->length != 0);
+
+ dns_name_init(&name1, NULL);
+ dns_name_init(&name2, NULL);
+
+ dns_rdata_toregion(rdata1, &region1);
+ dns_rdata_toregion(rdata2, &region2);
+
+ dns_name_fromregion(&name1, &region1);
+ dns_name_fromregion(&name2, &region2);
+
+ order = dns_name_rdatacompare(&name1, &name2);
+ if (order != 0)
+ return (order);
+
+ isc_region_consume(&region1, name_length(&name1));
+ isc_region_consume(&region2, name_length(&name2));
+
+ return (isc_region_compare(&region1, &region2));
+}
#endif /* RDATA_GENERIC_NSEC_47_C */
diff --git a/lib/dns/rdata/generic/null_10.c b/lib/dns/rdata/generic/null_10.c
index 06a887782c36..e6d9b9ad0790 100644
--- a/lib/dns/rdata/generic/null_10.c
+++ b/lib/dns/rdata/generic/null_10.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: null_10.c,v 1.42 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: null_10.c,v 1.44 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Thu Mar 16 13:57:50 PST 2000 by explorer */
@@ -189,4 +189,9 @@ checknames_null(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_null(ARGS_COMPARE) {
+ return (compare_null(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_NULL_10_C */
diff --git a/lib/dns/rdata/generic/nxt_30.c b/lib/dns/rdata/generic/nxt_30.c
index 362e6fc05ec8..44ded55c2dac 100644
--- a/lib/dns/rdata/generic/nxt_30.c
+++ b/lib/dns/rdata/generic/nxt_30.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nxt_30.c,v 1.63 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: nxt_30.c,v 1.65 2009-12-04 22:06:37 tbox Exp $ */
/* reviewed: Wed Mar 15 18:21:15 PST 2000 by brister */
@@ -326,4 +326,8 @@ checknames_nxt(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_nxt(ARGS_COMPARE) {
+ return (compare_nxt(rdata1, rdata2));
+}
#endif /* RDATA_GENERIC_NXT_30_C */
diff --git a/lib/dns/rdata/generic/opt_41.c b/lib/dns/rdata/generic/opt_41.c
index 506f4a33cc00..695057dcf5fa 100644
--- a/lib/dns/rdata/generic/opt_41.c
+++ b/lib/dns/rdata/generic/opt_41.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: opt_41.c,v 1.33 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: opt_41.c,v 1.35 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Thu Mar 16 14:06:44 PST 2000 by gson */
@@ -277,4 +277,9 @@ checknames_opt(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_opt(ARGS_COMPARE) {
+ return (compare_opt(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_OPT_41_C */
diff --git a/lib/dns/rdata/generic/proforma.c b/lib/dns/rdata/generic/proforma.c
index c3db196e567e..0efc197b0864 100644
--- a/lib/dns/rdata/generic/proforma.c
+++ b/lib/dns/rdata/generic/proforma.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: proforma.c,v 1.36 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: proforma.c,v 1.38 2009-12-04 22:06:37 tbox Exp $ */
#ifndef RDATA_GENERIC_#_#_C
#define RDATA_GENERIC_#_#_C
@@ -170,4 +170,21 @@ checknames_#(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_#(ARGS_COMPARE) {
+ isc_region_t r1;
+ isc_region_t r2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == #);
+ REQUIRE(rdata1->rdclass == #);
+ REQUIRE(rdata1->length != 0); /* XXX */
+ REQUIRE(rdata2->length != 0); /* XXX */
+
+ dns_rdata_toregion(rdata1, &r1);
+ dns_rdata_toregion(rdata2, &r2);
+ return (isc_region_compare(&r1, &r2));
+}
+
#endif /* RDATA_GENERIC_#_#_C */
diff --git a/lib/dns/rdata/generic/ptr_12.c b/lib/dns/rdata/generic/ptr_12.c
index 8e718cd92d96..0ed648f45134 100644
--- a/lib/dns/rdata/generic/ptr_12.c
+++ b/lib/dns/rdata/generic/ptr_12.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ptr_12.c,v 1.43 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: ptr_12.c,v 1.45 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Thu Mar 16 14:05:12 PST 2000 by explorer */
@@ -79,7 +79,7 @@ totext_ptr(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_ptr(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
REQUIRE(type == 12);
@@ -88,8 +88,8 @@ fromwire_ptr(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
+ dns_name_init(&name, NULL);
+ return (dns_name_fromwire(&name, source, dctx, options, target));
}
static inline isc_result_t
@@ -288,4 +288,8 @@ checknames_ptr(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_ptr(ARGS_COMPARE) {
+ return (compare_ptr(rdata1, rdata2));
+}
#endif /* RDATA_GENERIC_PTR_12_C */
diff --git a/lib/dns/rdata/generic/rp_17.c b/lib/dns/rdata/generic/rp_17.c
index 19d7b353900e..2865e2f2ef02 100644
--- a/lib/dns/rdata/generic/rp_17.c
+++ b/lib/dns/rdata/generic/rp_17.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rp_17.c,v 1.42 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: rp_17.c,v 1.44 2009-12-04 22:06:37 tbox Exp $ */
/* RFC1183 */
@@ -93,8 +93,8 @@ totext_rp(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_rp(ARGS_FROMWIRE) {
- dns_name_t rmail;
- dns_name_t email;
+ dns_name_t rmail;
+ dns_name_t email;
REQUIRE(type == 17);
@@ -103,11 +103,11 @@ fromwire_rp(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
- dns_name_init(&rmail, NULL);
- dns_name_init(&email, NULL);
+ dns_name_init(&rmail, NULL);
+ dns_name_init(&email, NULL);
- RETERR(dns_name_fromwire(&rmail, source, dctx, options, target));
- return (dns_name_fromwire(&email, source, dctx, options, target));
+ RETERR(dns_name_fromwire(&rmail, source, dctx, options, target));
+ return (dns_name_fromwire(&email, source, dctx, options, target));
}
static inline isc_result_t
@@ -311,4 +311,8 @@ checknames_rp(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_rp(ARGS_COMPARE) {
+ return (compare_rp(rdata1, rdata2));
+}
#endif /* RDATA_GENERIC_RP_17_C */
diff --git a/lib/dns/rdata/generic/rrsig_46.c b/lib/dns/rdata/generic/rrsig_46.c
index bcbb05b17ebe..1fa7d07b6ecf 100644
--- a/lib/dns/rdata/generic/rrsig_46.c
+++ b/lib/dns/rdata/generic/rrsig_46.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rrsig_46.c,v 1.10.332.2 2011-01-13 04:48:23 tbox Exp $ */
+/* $Id: rrsig_46.c,v 1.14 2011-01-13 04:59:26 tbox Exp $ */
/* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */
@@ -544,4 +544,47 @@ checknames_rrsig(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_rrsig(ARGS_COMPARE) {
+ isc_region_t r1;
+ isc_region_t r2;
+ dns_name_t name1;
+ dns_name_t name2;
+ int order;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 46);
+ REQUIRE(rdata1->length != 0);
+ REQUIRE(rdata2->length != 0);
+
+ dns_rdata_toregion(rdata1, &r1);
+ dns_rdata_toregion(rdata2, &r2);
+
+ INSIST(r1.length > 18);
+ INSIST(r2.length > 18);
+ r1.length = 18;
+ r2.length = 18;
+ order = isc_region_compare(&r1, &r2);
+ if (order != 0)
+ return (order);
+
+ dns_name_init(&name1, NULL);
+ dns_name_init(&name2, NULL);
+ dns_rdata_toregion(rdata1, &r1);
+ dns_rdata_toregion(rdata2, &r2);
+ isc_region_consume(&r1, 18);
+ isc_region_consume(&r2, 18);
+ dns_name_fromregion(&name1, &r1);
+ dns_name_fromregion(&name2, &r2);
+ order = dns_name_rdatacompare(&name1, &name2);
+ if (order != 0)
+ return (order);
+
+ isc_region_consume(&r1, name_length(&name1));
+ isc_region_consume(&r2, name_length(&name2));
+
+ return (isc_region_compare(&r1, &r2));
+}
+
#endif /* RDATA_GENERIC_RRSIG_46_C */
diff --git a/lib/dns/rdata/generic/rt_21.c b/lib/dns/rdata/generic/rt_21.c
index 48323c789d77..efd51e212cf4 100644
--- a/lib/dns/rdata/generic/rt_21.c
+++ b/lib/dns/rdata/generic/rt_21.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rt_21.c,v 1.46 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: rt_21.c,v 1.48 2009-12-04 22:06:37 tbox Exp $ */
/* reviewed: Thu Mar 16 15:02:31 PST 2000 by brister */
@@ -90,7 +90,7 @@ totext_rt(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_rt(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
isc_region_t sregion;
isc_region_t tregion;
@@ -101,7 +101,7 @@ fromwire_rt(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
- dns_name_init(&name, NULL);
+ dns_name_init(&name, NULL);
isc_buffer_activeregion(source, &sregion);
isc_buffer_availableregion(target, &tregion);
@@ -308,4 +308,9 @@ checknames_rt(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_rt(ARGS_COMPARE) {
+ return (compare_rt(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_RT_21_C */
diff --git a/lib/dns/rdata/generic/sig_24.c b/lib/dns/rdata/generic/sig_24.c
index 3010b8e47ec7..63663095411d 100644
--- a/lib/dns/rdata/generic/sig_24.c
+++ b/lib/dns/rdata/generic/sig_24.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sig_24.c,v 1.66 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: sig_24.c,v 1.68 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */
@@ -575,4 +575,8 @@ checknames_sig(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_sig(ARGS_COMPARE) {
+ return (compare_sig(rdata1, rdata2));
+}
#endif /* RDATA_GENERIC_SIG_24_C */
diff --git a/lib/dns/rdata/generic/soa_6.c b/lib/dns/rdata/generic/soa_6.c
index d3fdf4109a97..34361a8e1707 100644
--- a/lib/dns/rdata/generic/soa_6.c
+++ b/lib/dns/rdata/generic/soa_6.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: soa_6.c,v 1.61.332.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: soa_6.c,v 1.64 2009-12-04 21:09:34 marka Exp $ */
/* Reviewed: Thu Mar 16 15:18:32 PST 2000 by explorer */
@@ -441,4 +441,9 @@ checknames_soa(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_soa(ARGS_COMPARE) {
+ return (compare_soa(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_SOA_6_C */
diff --git a/lib/dns/rdata/generic/spf_99.c b/lib/dns/rdata/generic/spf_99.c
index b1ad062ab0cc..0f8ba5f94cd1 100644
--- a/lib/dns/rdata/generic/spf_99.c
+++ b/lib/dns/rdata/generic/spf_99.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: spf_99.c,v 1.4 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: spf_99.c,v 1.6 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Thu Mar 16 15:40:00 PST 2000 by bwelling */
@@ -235,4 +235,8 @@ checknames_spf(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_spf(ARGS_COMPARE) {
+ return (compare_spf(rdata1, rdata2));
+}
#endif /* RDATA_GENERIC_SPF_99_C */
diff --git a/lib/dns/rdata/generic/sshfp_44.c b/lib/dns/rdata/generic/sshfp_44.c
index 892c1ec480df..7b344517ce50 100644
--- a/lib/dns/rdata/generic/sshfp_44.c
+++ b/lib/dns/rdata/generic/sshfp_44.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2006, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sshfp_44.c,v 1.7 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: sshfp_44.c,v 1.9 2009-12-04 22:06:37 tbox Exp $ */
/* RFC 4255 */
@@ -259,4 +259,9 @@ checknames_sshfp(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_sshfp(ARGS_COMPARE) {
+ return (compare_sshfp(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_SSHFP_44_C */
diff --git a/lib/dns/rdata/generic/tkey_249.c b/lib/dns/rdata/generic/tkey_249.c
index 6927c8defd50..64acc0ffdec9 100644
--- a/lib/dns/rdata/generic/tkey_249.c
+++ b/lib/dns/rdata/generic/tkey_249.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: tkey_249.c,v 1.57 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: tkey_249.c,v 1.59 2009-12-04 22:06:37 tbox Exp $ */
/*
* Reviewed: Thu Mar 16 17:35:30 PST 2000 by halley.
@@ -552,4 +552,8 @@ checknames_tkey(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline isc_result_t
+casecompare_tkey(ARGS_COMPARE) {
+ return (compare_tkey(rdata1, rdata2));
+}
#endif /* RDATA_GENERIC_TKEY_249_C */
diff --git a/lib/dns/rdata/generic/txt_16.c b/lib/dns/rdata/generic/txt_16.c
index fa14b8650234..e04e0f048421 100644
--- a/lib/dns/rdata/generic/txt_16.c
+++ b/lib/dns/rdata/generic/txt_16.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: txt_16.c,v 1.45 2008-02-15 23:46:51 tbox Exp $ */
+/* $Id: txt_16.c,v 1.47 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Thu Mar 16 15:40:00 PST 2000 by bwelling */
@@ -235,4 +235,9 @@ checknames_txt(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline isc_result_t
+casecompare_txt(ARGS_COMPARE) {
+ return (compare_txt(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_TXT_16_C */
diff --git a/lib/dns/rdata/generic/unspec_103.c b/lib/dns/rdata/generic/unspec_103.c
index ffd14d949e13..0ce9a908776b 100644
--- a/lib/dns/rdata/generic/unspec_103.c
+++ b/lib/dns/rdata/generic/unspec_103.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: unspec_103.c,v 1.35 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: unspec_103.c,v 1.37 2009-12-04 22:06:37 tbox Exp $ */
#ifndef RDATA_GENERIC_UNSPEC_103_C
#define RDATA_GENERIC_UNSPEC_103_C
@@ -186,4 +186,9 @@ checknames_unspec(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_unspec(ARGS_COMPARE) {
+ return (compare_unspec(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_UNSPEC_103_C */
diff --git a/lib/dns/rdata/generic/x25_19.c b/lib/dns/rdata/generic/x25_19.c
index 47aeb7ff2d5e..f315b891cb1c 100644
--- a/lib/dns/rdata/generic/x25_19.c
+++ b/lib/dns/rdata/generic/x25_19.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: x25_19.c,v 1.39 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: x25_19.c,v 1.41 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Thu Mar 16 16:15:57 PST 2000 by bwelling */
@@ -216,4 +216,9 @@ checknames_x25(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_x25(ARGS_COMPARE) {
+ return (compare_x25(rdata1, rdata2));
+}
+
#endif /* RDATA_GENERIC_X25_19_C */
diff --git a/lib/dns/rdata/hs_4/a_1.c b/lib/dns/rdata/hs_4/a_1.c
index ae307196e4af..6d02b79392cd 100644
--- a/lib/dns/rdata/hs_4/a_1.c
+++ b/lib/dns/rdata/hs_4/a_1.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: a_1.c,v 1.31 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: a_1.c,v 1.33 2009-12-04 22:06:37 tbox Exp $ */
/* reviewed: Thu Mar 16 15:58:36 PST 2000 by brister */
@@ -229,4 +229,9 @@ checknames_hs_a(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_hs_a(ARGS_COMPARE) {
+ return (compare_hs_a(rdata1, rdata2));
+}
+
#endif /* RDATA_HS_4_A_1_C */
diff --git a/lib/dns/rdata/in_1/a6_38.c b/lib/dns/rdata/in_1/a6_38.c
index 450b74ca794f..ec453b1dd22c 100644
--- a/lib/dns/rdata/in_1/a6_38.c
+++ b/lib/dns/rdata/in_1/a6_38.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: a6_38.c,v 1.54 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: a6_38.c,v 1.56 2009-12-04 22:06:37 tbox Exp $ */
/* RFC2874 */
@@ -458,4 +458,9 @@ checknames_in_a6(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_a6(ARGS_COMPARE) {
+ return (compare_in_a6(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_A6_38_C */
diff --git a/lib/dns/rdata/in_1/a_1.c b/lib/dns/rdata/in_1/a_1.c
index 1181e4490e58..b4c1e945b16d 100644
--- a/lib/dns/rdata/in_1/a_1.c
+++ b/lib/dns/rdata/in_1/a_1.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: a_1.c,v 1.53 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: a_1.c,v 1.55 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */
@@ -233,4 +233,9 @@ checknames_in_a(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_a(ARGS_COMPARE) {
+ return (compare_in_a(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_A_1_C */
diff --git a/lib/dns/rdata/in_1/aaaa_28.c b/lib/dns/rdata/in_1/aaaa_28.c
index 119131c40f66..fe3954e4a094 100644
--- a/lib/dns/rdata/in_1/aaaa_28.c
+++ b/lib/dns/rdata/in_1/aaaa_28.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: aaaa_28.c,v 1.45 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: aaaa_28.c,v 1.47 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */
@@ -230,4 +230,8 @@ checknames_in_aaaa(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_aaaa(ARGS_COMPARE) {
+ return (compare_in_aaaa(rdata1, rdata2));
+}
#endif /* RDATA_IN_1_AAAA_28_C */
diff --git a/lib/dns/rdata/in_1/apl_42.c b/lib/dns/rdata/in_1/apl_42.c
index 70f6880ccd89..3f37880c436b 100644
--- a/lib/dns/rdata/in_1/apl_42.c
+++ b/lib/dns/rdata/in_1/apl_42.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: apl_42.c,v 1.14 2008-01-22 23:28:04 tbox Exp $ */
+/* $Id: apl_42.c,v 1.16 2009-12-04 22:06:37 tbox Exp $ */
/* RFC3123 */
@@ -450,4 +450,9 @@ checknames_in_apl(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_apl(ARGS_COMPARE) {
+ return (compare_in_apl(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_APL_42_C */
diff --git a/lib/dns/rdata/in_1/dhcid_49.c b/lib/dns/rdata/in_1/dhcid_49.c
index 5759a76df05a..9eca46f40783 100644
--- a/lib/dns/rdata/in_1/dhcid_49.c
+++ b/lib/dns/rdata/in_1/dhcid_49.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dhcid_49.c,v 1.5 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: dhcid_49.c,v 1.7 2009-12-04 22:06:37 tbox Exp $ */
/* RFC 4701 */
@@ -51,7 +51,7 @@ totext_in_dhcid(ARGS_TOTEXT) {
dns_rdata_toregion(rdata, &sr);
if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
- RETERR(str_totext("( " /*)*/, target));
+ RETERR(str_totext("( " /*)*/, target));
RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak,
target));
if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
@@ -226,4 +226,9 @@ checknames_in_dhcid(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_dhcid(ARGS_COMPARE) {
+ return (compare_in_dhcid(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_DHCID_49_C */
diff --git a/lib/dns/rdata/in_1/kx_36.c b/lib/dns/rdata/in_1/kx_36.c
index 795844dab3a7..dfc103b74eb4 100644
--- a/lib/dns/rdata/in_1/kx_36.c
+++ b/lib/dns/rdata/in_1/kx_36.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: kx_36.c,v 1.45 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: kx_36.c,v 1.47 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Thu Mar 16 17:24:54 PST 2000 by explorer */
@@ -85,7 +85,7 @@ totext_in_kx(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_in_kx(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
isc_region_t sregion;
REQUIRE(type == 36);
@@ -96,7 +96,7 @@ fromwire_in_kx(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
- dns_name_init(&name, NULL);
+ dns_name_init(&name, NULL);
isc_buffer_activeregion(source, &sregion);
if (sregion.length < 2)
@@ -285,4 +285,9 @@ checknames_in_kx(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_kx(ARGS_COMPARE) {
+ return (compare_in_kx(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_KX_36_C */
diff --git a/lib/dns/rdata/in_1/naptr_35.c b/lib/dns/rdata/in_1/naptr_35.c
index 51aadf781794..3d0975702c14 100644
--- a/lib/dns/rdata/in_1/naptr_35.c
+++ b/lib/dns/rdata/in_1/naptr_35.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: naptr_35.c,v 1.53 2008-02-15 23:46:51 tbox Exp $ */
+/* $Id: naptr_35.c,v 1.56 2009-12-04 21:09:34 marka Exp $ */
/* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */
@@ -25,12 +25,134 @@
#define RDATA_IN_1_NAPTR_35_C
#define RRTYPE_NAPTR_ATTRIBUTES (0)
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+
+/*
+ * Check the wire format of the Regexp field.
+ * Don't allow embeded NUL's.
+ */
+static inline isc_result_t
+txt_valid_regex(const unsigned char *txt) {
+#ifdef HAVE_REGEX_H
+ regex_t preg;
+ unsigned int regflags = REG_EXTENDED;
+ unsigned int nsub = 0;
+ char regex[256];
+ char *cp;
+#endif
+ isc_boolean_t flags = ISC_FALSE;
+ isc_boolean_t replace = ISC_FALSE;
+ unsigned char c;
+ unsigned char delim;
+ unsigned int len;
+
+ len = *txt++;
+ if (len == 0U)
+ return (ISC_R_SUCCESS);
+
+ delim = *txt++;
+ len--;
+
+ /*
+ * Digits, backslash and flags can't be delimiters.
+ */
+ switch (delim) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case '\\': case 'i': case 0:
+ return (DNS_R_SYNTAX);
+ }
+
+#ifdef HAVE_REGEX_H
+ memset(&preg, 0, sizeof(preg));
+ cp = regex;
+#endif
+
+ while (len-- > 0) {
+ c = *txt++;
+ if (c == 0)
+ return (DNS_R_SYNTAX);
+ if (c == delim && !replace) {
+ replace = ISC_TRUE;
+ continue;
+ } else if (c == delim && !flags) {
+ flags = ISC_TRUE;
+ continue;
+ } else if (c == delim)
+ return (DNS_R_SYNTAX);
+ /*
+ * Flags are not escaped.
+ */
+ if (flags) {
+ switch (c) {
+ case 'i':
+#ifdef HAVE_REGEX_H
+ regflags |= REG_ICASE;
+#endif
+ continue;
+ default:
+ return (DNS_R_SYNTAX);
+ }
+ }
+#ifdef HAVE_REGEX_H
+ if (!replace)
+ *cp++ = c;
+#endif
+ if (c == '\\') {
+ if (len == 0)
+ return (DNS_R_SYNTAX);
+ c = *txt++;
+ if (c == 0)
+ return (DNS_R_SYNTAX);
+ len--;
+ if (replace)
+ switch (c) {
+ case '0': return (DNS_R_SYNTAX);
+#ifdef HAVE_REGEX_H
+ case '1': if (nsub < 1) nsub = 1; break;
+ case '2': if (nsub < 2) nsub = 2; break;
+ case '3': if (nsub < 3) nsub = 3; break;
+ case '4': if (nsub < 4) nsub = 4; break;
+ case '5': if (nsub < 5) nsub = 5; break;
+ case '6': if (nsub < 6) nsub = 6; break;
+ case '7': if (nsub < 7) nsub = 7; break;
+ case '8': if (nsub < 8) nsub = 8; break;
+ case '9': if (nsub < 9) nsub = 9; break;
+#endif
+ }
+#ifdef HAVE_REGEX_H
+ if (!replace)
+ *cp++ = c;
+#endif
+ }
+ }
+ if (!flags)
+ return (DNS_R_SYNTAX);
+#ifdef HAVE_REGEX_H
+ *cp = '\0';
+ if (regcomp(&preg, regex, regflags))
+ return (DNS_R_SYNTAX);
+ /*
+ * Check that substitutions in the replacement string are consistant
+ * with the regular expression.
+ */
+ if (preg.re_nsub < nsub) {
+ regfree(&preg);
+ return (DNS_R_SYNTAX);
+ }
+ regfree(&preg);
+#endif
+ return (ISC_R_SUCCESS);
+}
static inline isc_result_t
fromtext_in_naptr(ARGS_FROMTEXT) {
isc_token_t token;
dns_name_t name;
isc_buffer_t buffer;
+ unsigned char *regex;
REQUIRE(type == 35);
REQUIRE(rdclass == 1);
@@ -74,9 +196,11 @@ fromtext_in_naptr(ARGS_FROMTEXT) {
/*
* Regexp.
*/
+ regex = isc_buffer_used(target);
RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
ISC_FALSE));
RETTOK(txt_fromtext(&token.value.as_textregion, target));
+ RETTOK(txt_valid_regex(regex));
/*
* Replacement.
@@ -156,6 +280,7 @@ static inline isc_result_t
fromwire_in_naptr(ARGS_FROMWIRE) {
dns_name_t name;
isc_region_t sr;
+ unsigned char *regex;
REQUIRE(type == 35);
REQUIRE(rdclass == 1);
@@ -189,7 +314,9 @@ fromwire_in_naptr(ARGS_FROMWIRE) {
/*
* Regexp.
*/
+ regex = isc_buffer_used(target);
RETERR(txt_fromwire(source, target));
+ RETERR(txt_valid_regex(regex));
/*
* Replacement.
@@ -575,4 +702,9 @@ checknames_in_naptr(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_naptr(ARGS_COMPARE) {
+ return (compare_in_naptr(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_NAPTR_35_C */
diff --git a/lib/dns/rdata/in_1/nsap-ptr_23.c b/lib/dns/rdata/in_1/nsap-ptr_23.c
index 615d24a98159..2554b074f2b5 100644
--- a/lib/dns/rdata/in_1/nsap-ptr_23.c
+++ b/lib/dns/rdata/in_1/nsap-ptr_23.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsap-ptr_23.c,v 1.38 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: nsap-ptr_23.c,v 1.40 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Fri Mar 17 10:16:02 PST 2000 by gson */
@@ -73,7 +73,7 @@ totext_in_nsap_ptr(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_in_nsap_ptr(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
REQUIRE(type == 23);
REQUIRE(rdclass == 1);
@@ -83,8 +83,8 @@ fromwire_in_nsap_ptr(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
- dns_name_init(&name, NULL);
- return (dns_name_fromwire(&name, source, dctx, options, target));
+ dns_name_init(&name, NULL);
+ return (dns_name_fromwire(&name, source, dctx, options, target));
}
static inline isc_result_t
@@ -242,4 +242,9 @@ checknames_in_nsap_ptr(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_nsap_ptr(ARGS_COMPARE) {
+ return (compare_in_nsap_ptr(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_NSAP_PTR_23_C */
diff --git a/lib/dns/rdata/in_1/nsap_22.c b/lib/dns/rdata/in_1/nsap_22.c
index 1aaf13f35c30..4a56c75b22db 100644
--- a/lib/dns/rdata/in_1/nsap_22.c
+++ b/lib/dns/rdata/in_1/nsap_22.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsap_22.c,v 1.42 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: nsap_22.c,v 1.44 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Fri Mar 17 10:41:07 PST 2000 by gson */
@@ -252,4 +252,9 @@ checknames_in_nsap(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_nsap(ARGS_COMPARE) {
+ return (compare_in_nsap(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_NSAP_22_C */
diff --git a/lib/dns/rdata/in_1/px_26.c b/lib/dns/rdata/in_1/px_26.c
index 517b87c0c1cf..50f68cdb7e92 100644
--- a/lib/dns/rdata/in_1/px_26.c
+++ b/lib/dns/rdata/in_1/px_26.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: px_26.c,v 1.43 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: px_26.c,v 1.45 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Mon Mar 20 10:44:27 PST 2000 */
@@ -115,7 +115,7 @@ totext_in_px(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_in_px(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
isc_region_t sregion;
REQUIRE(type == 26);
@@ -126,7 +126,7 @@ fromwire_in_px(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
- dns_name_init(&name, NULL);
+ dns_name_init(&name, NULL);
/*
* Preference.
@@ -371,4 +371,9 @@ checknames_in_px(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_px(ARGS_COMPARE) {
+ return (compare_in_px(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_PX_26_C */
diff --git a/lib/dns/rdata/in_1/srv_33.c b/lib/dns/rdata/in_1/srv_33.c
index ac9e57784d75..3dfd13e96a67 100644
--- a/lib/dns/rdata/in_1/srv_33.c
+++ b/lib/dns/rdata/in_1/srv_33.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: srv_33.c,v 1.45 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: srv_33.c,v 1.47 2009-12-04 22:06:37 tbox Exp $ */
/* Reviewed: Fri Mar 17 13:01:00 PST 2000 by bwelling */
@@ -140,7 +140,7 @@ totext_in_srv(ARGS_TOTEXT) {
static inline isc_result_t
fromwire_in_srv(ARGS_FROMWIRE) {
- dns_name_t name;
+ dns_name_t name;
isc_region_t sr;
REQUIRE(type == 33);
@@ -151,7 +151,7 @@ fromwire_in_srv(ARGS_FROMWIRE) {
dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
- dns_name_init(&name, NULL);
+ dns_name_init(&name, NULL);
/*
* Priority, weight, port.
@@ -370,4 +370,9 @@ checknames_in_srv(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_srv(ARGS_COMPARE) {
+ return (compare_in_srv(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_SRV_33_C */
diff --git a/lib/dns/rdata/in_1/wks_11.c b/lib/dns/rdata/in_1/wks_11.c
index b7d505773e16..29983ec150bd 100644
--- a/lib/dns/rdata/in_1/wks_11.c
+++ b/lib/dns/rdata/in_1/wks_11.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: wks_11.c,v 1.54.332.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: wks_11.c,v 1.57 2009-12-04 21:09:34 marka Exp $ */
/* Reviewed: Fri Mar 17 15:01:49 PST 2000 by explorer */
@@ -348,4 +348,9 @@ checknames_in_wks(ARGS_CHECKNAMES) {
return (ISC_TRUE);
}
+static inline int
+casecompare_in_wks(ARGS_COMPARE) {
+ return (compare_in_wks(rdata1, rdata2));
+}
+
#endif /* RDATA_IN_1_WKS_11_C */
diff --git a/lib/dns/rdatalist.c b/lib/dns/rdatalist.c
index e8178a767e55..d30aff966ade 100644
--- a/lib/dns/rdatalist.c
+++ b/lib/dns/rdatalist.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdatalist.c,v 1.36.50.2 2010-02-25 10:56:41 tbox Exp $ */
+/* $Id: rdatalist.c,v 1.40 2010-11-16 05:38:31 marka Exp $ */
/*! \file */
diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c
index 672e0011b158..fdd7669b2e87 100644
--- a/lib/dns/rdataset.c
+++ b/lib/dns/rdataset.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataset.c,v 1.82.50.4.6.3 2011-06-21 20:13:23 each Exp $ */
+/* $Id: rdataset.c,v 1.86.220.3 2011-06-21 20:15:53 each Exp $ */
/*! \file */
diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c
index d1a02a0cad6a..932f8de31df9 100644
--- a/lib/dns/rdataslab.c
+++ b/lib/dns/rdataslab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataslab.c,v 1.48.50.4 2010-02-25 10:56:41 tbox Exp $ */
+/* $Id: rdataslab.c,v 1.52.148.1.2.1 2011-06-02 23:47:35 tbox Exp $ */
/*! \file */
@@ -144,21 +144,25 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
nalloc = dns_rdataset_count(rdataset);
nitems = nalloc;
- if (nitems == 0)
+ if (nitems == 0 && rdataset->type != 0)
return (ISC_R_FAILURE);
if (nalloc > 0xffff)
return (ISC_R_NOSPACE);
- x = isc_mem_get(mctx, nalloc * sizeof(struct xrdata));
- if (x == NULL)
- return (ISC_R_NOMEMORY);
+
+ if (nalloc != 0) {
+ x = isc_mem_get(mctx, nalloc * sizeof(struct xrdata));
+ if (x == NULL)
+ return (ISC_R_NOMEMORY);
+ } else
+ x = NULL;
/*
* Save all of the rdata members into an array.
*/
result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE)
goto free_rdatas;
for (i = 0; i < nalloc && result == ISC_R_SUCCESS; i++) {
INSIST(result == ISC_R_SUCCESS);
@@ -223,11 +227,14 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
/*
* Don't forget the last item!
*/
+ if (nalloc != 0) {
#if DNS_RDATASET_FIXED
- buflen += (8 + x[i-1].rdata.length);
+ buflen += (8 + x[i-1].rdata.length);
#else
- buflen += (2 + x[i-1].rdata.length);
+ buflen += (2 + x[i-1].rdata.length);
#endif
+ }
+
/*
* Provide space to store the per RR meta data.
*/
@@ -316,7 +323,8 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
result = ISC_R_SUCCESS;
free_rdatas:
- isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata));
+ if (x != NULL)
+ isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata));
return (result);
}
diff --git a/lib/dns/request.c b/lib/dns/request.c
index c1cd235fc19b..b5d624824e83 100644
--- a/lib/dns/request.c
+++ b/lib/dns/request.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: request.c,v 1.82.72.2 2009-01-18 23:47:40 tbox Exp $ */
+/* $Id: request.c,v 1.87 2010-03-04 23:50:34 tbox Exp $ */
/*! \file */
@@ -449,7 +449,8 @@ req_send(dns_request_t *request, isc_task_t *task, isc_sockaddr_t *address) {
}
static isc_result_t
-new_request(isc_mem_t *mctx, dns_request_t **requestp) {
+new_request(isc_mem_t *mctx, dns_request_t **requestp)
+{
dns_request_t *request;
request = isc_mem_get(mctx, sizeof(*request));
@@ -1058,6 +1059,9 @@ req_render(dns_message_t *message, isc_buffer_t **bufferp,
return (result);
cleanup_cctx = ISC_TRUE;
+ if ((options & DNS_REQUESTOPT_CASE) != 0)
+ dns_compress_setsensitive(&cctx, ISC_TRUE);
+
/*
* Render message.
*/
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index f60eee945611..6d9ab700f174 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.384.14.30.4.1 2011-06-21 20:13:23 each Exp $ */
+/* $Id: resolver.c,v 1.428.6.5.2.1 2011-06-21 20:15:53 each Exp $ */
/*! \file */
@@ -105,6 +105,14 @@
#define QTRACE(m)
#endif
+#ifndef DEFAULT_QUERY_TIMEOUT
+#define DEFAULT_QUERY_TIMEOUT 30 /* The default time in seconds for the whole query to live. */
+#endif
+
+#ifndef MAXIMUM_QUERY_TIMEOUT
+#define MAXIMUM_QUERY_TIMEOUT 30 /* The maximum time in seconds for the whole query to live. */
+#endif
+
/*%
* Maximum EDNS0 input packet size.
*/
@@ -273,6 +281,8 @@ struct fetchctx {
unsigned int findfail;
unsigned int valfail;
isc_boolean_t timeout;
+ dns_adbaddrinfo_t *addrinfo;
+ isc_sockaddr_t *client;
};
#define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
@@ -384,6 +394,7 @@ struct dns_resolver {
unsigned int spillatmin;
isc_timer_t * spillattimer;
isc_boolean_t zero_no_soa_ttl;
+ unsigned int query_timeout;
/* Locked by lock. */
unsigned int references;
@@ -1035,6 +1046,7 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
ISC_LIST_UNLINK(fctx->events, event, ev_link);
task = event->ev_sender;
event->ev_sender = fctx;
+ event->vresult = fctx->vresult;
if (!HAVE_ANSWER(fctx))
event->result = result;
@@ -1742,9 +1754,8 @@ resquery_send(resquery_t *query) {
if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) {
fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
} else if (res->view->enablevalidation) {
- result = dns_keytable_issecuredomain(res->view->secroots,
- &fctx->name,
- &secure_domain);
+ result = dns_view_issecuredomain(res->view, &fctx->name,
+ &secure_domain);
if (result != ISC_R_SUCCESS)
secure_domain = ISC_FALSE;
if (res->view->dlv != NULL)
@@ -2285,7 +2296,7 @@ add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason,
char code[64];
isc_buffer_t b;
isc_sockaddr_t *sa;
- const char *sep1, *sep2;
+ const char *spc = "";
isc_sockaddr_t *address = &addrinfo->sockaddr;
if (reason == DNS_R_LAME)
@@ -2331,18 +2342,14 @@ add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason,
isc_buffer_init(&b, code, sizeof(code) - 1);
dns_rcode_totext(fctx->rmessage->rcode, &b);
code[isc_buffer_usedlength(&b)] = '\0';
- sep1 = "(";
- sep2 = ") ";
+ spc = " ";
} else if (reason == DNS_R_UNEXPECTEDOPCODE) {
isc_buffer_init(&b, code, sizeof(code) - 1);
dns_opcode_totext((dns_opcode_t)fctx->rmessage->opcode, &b);
code[isc_buffer_usedlength(&b)] = '\0';
- sep1 = "(";
- sep2 = ") ";
+ spc = " ";
} else {
code[0] = '\0';
- sep1 = "";
- sep2 = "";
}
dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
@@ -2350,83 +2357,19 @@ add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason,
isc_sockaddr_format(address, addrbuf, sizeof(addrbuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS,
DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
- "%s %s%s%sresolving '%s/%s/%s': %s",
- dns_result_totext(reason), sep1, code, sep2,
+ "error (%s%s%s) resolving '%s/%s/%s': %s",
+ dns_result_totext(reason), spc, code,
namebuf, typebuf, classbuf, addrbuf);
}
/*
- * Return 'bits' bits of random entropy from fctx->rand_buf,
- * refreshing it by calling isc_random_get() whenever the requested
- * number of bits is greater than the number in the buffer.
- */
-static inline isc_uint32_t
-random_bits(fetchctx_t *fctx, isc_uint32_t bits) {
- isc_uint32_t ret = 0;
-
- REQUIRE(VALID_FCTX(fctx));
- REQUIRE(bits <= 32);
- if (bits == 0)
- return (0);
-
- if (bits >= fctx->rand_bits) {
- /* if rand_bits == 0, this is unnecessary but harmless */
- bits -= fctx->rand_bits;
- ret = fctx->rand_buf << bits;
-
- /* refresh random buffer now */
- isc_random_get(&fctx->rand_buf);
- fctx->rand_bits = sizeof(fctx->rand_buf) * CHAR_BIT;
- }
-
- if (bits > 0) {
- isc_uint32_t mask = 0xffffffff;
- if (bits < 32) {
- mask = (1 << bits) - 1;
- }
-
- ret |= fctx->rand_buf & mask;
- fctx->rand_buf >>= bits;
- fctx->rand_bits -= bits;
- }
-
- return (ret);
-}
-
-/*
- * Add some random jitter to a server's RTT value so that the
- * order of queries will be unpredictable.
- *
- * RTT values of servers which have been tried are fuzzed by 128 ms.
- * Servers that haven't been tried yet have their RTT set to a random
- * value between 0 ms and 7 ms; they should get to go first, but in
- * unpredictable order.
- */
-static inline void
-randomize_srtt(fetchctx_t *fctx, dns_adbaddrinfo_t *ai) {
- if (TRIED(ai)) {
- ai->srtt >>= 10; /* convert to milliseconds, near enough */
- ai->srtt |= (ai->srtt & 0x80) | random_bits(fctx, 7);
- ai->srtt <<= 10; /* now back to microseconds */
- } else
- ai->srtt = random_bits(fctx, 3) << 10;
-}
-
-/*
- * Sort addrinfo list by RTT (with random jitter)
+ * Sort addrinfo list by RTT.
*/
static void
-sort_adbfind(fetchctx_t *fctx, dns_adbfind_t *find) {
+sort_adbfind(dns_adbfind_t *find) {
dns_adbaddrinfo_t *best, *curr;
dns_adbaddrinfolist_t sorted;
- /* Add jitter to SRTT values */
- curr = ISC_LIST_HEAD(find->list);
- while (curr != NULL) {
- randomize_srtt(fctx, curr);
- curr = ISC_LIST_NEXT(curr, publink);
- }
-
/* Lame N^2 bubble sort. */
ISC_LIST_INIT(sorted);
while (!ISC_LIST_EMPTY(find->list)) {
@@ -2444,19 +2387,19 @@ sort_adbfind(fetchctx_t *fctx, dns_adbfind_t *find) {
}
/*
- * Sort a list of finds by server RTT (with random jitter)
+ * Sort a list of finds by server RTT.
*/
static void
-sort_finds(fetchctx_t *fctx, dns_adbfindlist_t *findlist) {
+sort_finds(dns_adbfindlist_t *findlist) {
dns_adbfind_t *best, *curr;
dns_adbfindlist_t sorted;
dns_adbaddrinfo_t *addrinfo, *bestaddrinfo;
- /* Sort each find's addrinfo list by SRTT (after adding jitter) */
+ /* Sort each find's addrinfo list by SRTT. */
for (curr = ISC_LIST_HEAD(*findlist);
curr != NULL;
curr = ISC_LIST_NEXT(curr, publink))
- sort_adbfind(fctx, curr);
+ sort_adbfind(curr);
/* Lame N^2 bubble sort. */
ISC_LIST_INIT(sorted);
@@ -2841,8 +2784,8 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
* We've found some addresses. We might still be looking
* for more addresses.
*/
- sort_finds(fctx, &fctx->finds);
- sort_finds(fctx, &fctx->altfinds);
+ sort_finds(&fctx->finds);
+ sort_finds(&fctx->altfinds);
result = ISC_R_SUCCESS;
}
@@ -3471,6 +3414,7 @@ fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client,
else
ISC_LIST_APPEND(fctx->events, event, ev_link);
fctx->references++;
+ fctx->client = client;
fetch->magic = DNS_FETCH_MAGIC;
fetch->private = fctx;
@@ -3569,6 +3513,8 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
fctx->rand_buf = 0;
fctx->rand_bits = 0;
fctx->timeout = ISC_FALSE;
+ fctx->addrinfo = NULL;
+ fctx->client = NULL;
dns_name_init(&fctx->nsname, NULL);
fctx->nsfetch = NULL;
@@ -3658,7 +3604,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
/*
* Compute an expiration time for the entire fetch.
*/
- isc_interval_set(&interval, 30, 0); /* XXXRTH constant */
+ isc_interval_set(&interval, res->query_timeout, 0);
iresult = isc_time_nowplusinterval(&fctx->expires, &interval);
if (iresult != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
@@ -3800,6 +3746,33 @@ log_lame(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo) {
namebuf, domainbuf, addrbuf);
}
+static inline void
+log_formerr(fetchctx_t *fctx, const char *format, ...) {
+ char nsbuf[ISC_SOCKADDR_FORMATSIZE];
+ char clbuf[ISC_SOCKADDR_FORMATSIZE];
+ const char *clmsg = "";
+ char msgbuf[2048];
+ va_list args;
+
+ va_start(args, format);
+ vsnprintf(msgbuf, sizeof(msgbuf), format, args);
+ va_end(args);
+
+ isc_sockaddr_format(&fctx->addrinfo->sockaddr, nsbuf, sizeof(nsbuf));
+
+ if (fctx->client != NULL) {
+ clmsg = " for client ";
+ isc_sockaddr_format(fctx->client, clbuf, sizeof(clbuf));
+ } else {
+ clbuf[0] = '\0';
+ }
+
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
+ "DNS format error from %s resolving %s%s%s: %s",
+ nsbuf, fctx->info, clmsg, clbuf, msgbuf);
+}
+
static inline isc_result_t
same_question(fetchctx_t *fctx) {
isc_result_t result;
@@ -3814,8 +3787,10 @@ same_question(fetchctx_t *fctx) {
/*
* XXXRTH Currently we support only one question.
*/
- if (message->counts[DNS_SECTION_QUESTION] != 1)
+ if (message->counts[DNS_SECTION_QUESTION] != 1) {
+ log_formerr(fctx, "too many questions");
return (DNS_R_FORMERR);
+ }
result = dns_message_firstname(message, DNS_SECTION_QUESTION);
if (result != ISC_R_SUCCESS)
@@ -3825,10 +3800,21 @@ same_question(fetchctx_t *fctx) {
rdataset = ISC_LIST_HEAD(name->list);
INSIST(rdataset != NULL);
INSIST(ISC_LIST_NEXT(rdataset, link) == NULL);
+
if (fctx->type != rdataset->type ||
fctx->res->rdclass != rdataset->rdclass ||
- !dns_name_equal(&fctx->name, name))
+ !dns_name_equal(&fctx->name, name)) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char class[DNS_RDATACLASS_FORMATSIZE];
+ char type[DNS_RDATATYPE_FORMATSIZE];
+
+ dns_name_format(name, namebuf, sizeof(namebuf));
+ dns_rdataclass_format(rdataset->rdclass, class, sizeof(class));
+ dns_rdatatype_format(rdataset->type, type, sizeof(type));
+ log_formerr(fctx, "question section mismatch: got %s/%s/%s",
+ namebuf, class, type);
return (DNS_R_FORMERR);
+ }
return (ISC_R_SUCCESS);
}
@@ -3958,6 +3944,7 @@ validated(isc_task_t *task, isc_event_t *event) {
REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
vevent = (dns_validatorevent_t *)event;
+ fctx->vresult = vevent->result;
FCTXTRACE("received validation completion event");
@@ -4331,8 +4318,8 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
* Is DNSSEC validation required for this name?
*/
if (res->view->enablevalidation) {
- result = dns_keytable_issecuredomain(res->view->secroots, name,
- &secure_domain);
+ result = dns_view_issecuredomain(res->view, name,
+ &secure_domain);
if (result != ISC_R_SUCCESS)
return (result);
@@ -4804,8 +4791,8 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
* Is DNSSEC validation required for this name?
*/
if (fctx->res->view->enablevalidation) {
- result = dns_keytable_issecuredomain(res->view->secroots, name,
- &secure_domain);
+ result = dns_view_issecuredomain(res->view, name,
+ &secure_domain);
if (result != ISC_R_SUCCESS)
return (result);
@@ -4949,7 +4936,9 @@ mark_related(dns_name_t *name, dns_rdataset_t *rdataset,
}
static isc_result_t
-check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
+check_section(void *arg, dns_name_t *addname, dns_rdatatype_t type,
+ dns_section_t section)
+{
fetchctx_t *fctx = arg;
isc_result_t result;
dns_name_t *name;
@@ -4960,15 +4949,19 @@ check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
REQUIRE(VALID_FCTX(fctx));
+#if CHECK_FOR_GLUE_IN_ANSWER
+ if (section == DNS_SECTION_ANSWER && type != dns_rdatatype_a)
+ return (ISC_R_SUCCESS);
+#endif
+
if (GLUING(fctx))
gluing = ISC_TRUE;
else
gluing = ISC_FALSE;
name = NULL;
rdataset = NULL;
- result = dns_message_findname(fctx->rmessage, DNS_SECTION_ADDITIONAL,
- addname, dns_rdatatype_any, 0, &name,
- NULL);
+ result = dns_message_findname(fctx->rmessage, section, addname,
+ dns_rdatatype_any, 0, &name, NULL);
if (result == ISC_R_SUCCESS) {
external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
if (type == dns_rdatatype_a) {
@@ -5006,6 +4999,21 @@ check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
return (ISC_R_SUCCESS);
}
+static isc_result_t
+check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
+ return (check_section(arg, addname, type, DNS_SECTION_ADDITIONAL));
+}
+
+#ifndef CHECK_FOR_GLUE_IN_ANSWER
+#define CHECK_FOR_GLUE_IN_ANSWER 0
+#endif
+#if CHECK_FOR_GLUE_IN_ANSWER
+static isc_result_t
+check_answer(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
+ return (check_section(arg, addname, type, DNS_SECTION_ANSWER));
+}
+#endif
+
static void
chase_additional(fetchctx_t *fctx) {
isc_boolean_t rescan;
@@ -5062,8 +5070,8 @@ cname_target(dns_rdataset_t *rdataset, dns_name_t *tname) {
}
static inline isc_result_t
-dname_target(dns_rdataset_t *rdataset, dns_name_t *qname, dns_name_t *oname,
- dns_fixedname_t *fixeddname)
+dname_target(fetchctx_t *fctx, dns_rdataset_t *rdataset, dns_name_t *qname,
+ dns_name_t *oname, dns_fixedname_t *fixeddname)
{
isc_result_t result;
dns_rdata_t rdata = DNS_RDATA_INIT;
@@ -5076,7 +5084,6 @@ dname_target(dns_rdataset_t *rdataset, dns_name_t *qname, dns_name_t *oname,
/*
* Get the target name of the DNAME.
*/
-
result = dns_rdataset_first(rdataset);
if (result != ISC_R_SUCCESS)
return (result);
@@ -5090,7 +5097,14 @@ dname_target(dns_rdataset_t *rdataset, dns_name_t *qname, dns_name_t *oname,
*/
namereln = dns_name_fullcompare(qname, oname, &order, &nlabels);
if (namereln != dns_namereln_subdomain) {
+ char qbuf[DNS_NAME_FORMATSIZE];
+ char obuf[DNS_NAME_FORMATSIZE];
+
dns_rdata_freestruct(&dname);
+ dns_name_format(qname, qbuf, sizeof(qbuf));
+ dns_name_format(oname, obuf, sizeof(obuf));
+ log_formerr(fctx, "unrelated DNAME in answer: "
+ "%s is not in %s", qbuf, obuf);
return (DNS_R_FORMERR);
}
dns_fixedname_init(&prefix);
@@ -5103,16 +5117,147 @@ dname_target(dns_rdataset_t *rdataset, dns_name_t *qname, dns_name_t *oname,
return (result);
}
+static isc_boolean_t
+is_answeraddress_allowed(dns_view_t *view, dns_name_t *name,
+ dns_rdataset_t *rdataset)
+{
+ isc_result_t result;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ struct in_addr ina;
+ struct in6_addr in6a;
+ isc_netaddr_t netaddr;
+ char addrbuf[ISC_NETADDR_FORMATSIZE];
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char classbuf[64];
+ char typebuf[64];
+ int match;
+
+ /* By default, we allow any addresses. */
+ if (view->denyansweracl == NULL)
+ return (ISC_TRUE);
+
+ /*
+ * If the owner name matches one in the exclusion list, either exactly
+ * or partially, allow it.
+ */
+ if (view->answeracl_exclude != NULL) {
+ dns_rbtnode_t *node = NULL;
+
+ result = dns_rbt_findnode(view->answeracl_exclude, name, NULL,
+ &node, NULL, 0, NULL, NULL);
+
+ if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
+ return (ISC_TRUE);
+ }
+
+ /*
+ * Otherwise, search the filter list for a match for each address
+ * record. If a match is found, the address should be filtered,
+ * so should the entire answer.
+ */
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_reset(&rdata);
+ dns_rdataset_current(rdataset, &rdata);
+ if (rdataset->type == dns_rdatatype_a) {
+ INSIST(rdata.length == sizeof(ina.s_addr));
+ memcpy(&ina.s_addr, rdata.data, sizeof(ina.s_addr));
+ isc_netaddr_fromin(&netaddr, &ina);
+ } else {
+ INSIST(rdata.length == sizeof(in6a.s6_addr));
+ memcpy(in6a.s6_addr, rdata.data, sizeof(in6a.s6_addr));
+ isc_netaddr_fromin6(&netaddr, &in6a);
+ }
+
+ result = dns_acl_match(&netaddr, NULL, view->denyansweracl,
+ &view->aclenv, &match, NULL);
+
+ if (result == ISC_R_SUCCESS && match > 0) {
+ isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
+ dns_name_format(name, namebuf, sizeof(namebuf));
+ dns_rdatatype_format(rdataset->type, typebuf,
+ sizeof(typebuf));
+ dns_rdataclass_format(rdataset->rdclass, classbuf,
+ sizeof(classbuf));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
+ "answer address %s denied for %s/%s/%s",
+ addrbuf, namebuf, typebuf, classbuf);
+ return (ISC_FALSE);
+ }
+ }
+
+ return (ISC_TRUE);
+}
+
+static isc_boolean_t
+is_answertarget_allowed(dns_view_t *view, dns_name_t *name,
+ dns_rdatatype_t type, dns_name_t *tname,
+ dns_name_t *domain)
+{
+ isc_result_t result;
+ dns_rbtnode_t *node = NULL;
+ char qnamebuf[DNS_NAME_FORMATSIZE];
+ char tnamebuf[DNS_NAME_FORMATSIZE];
+ char classbuf[64];
+ char typebuf[64];
+
+ /* By default, we allow any target name. */
+ if (view->denyanswernames == NULL)
+ return (ISC_TRUE);
+
+ /*
+ * If the owner name matches one in the exclusion list, either exactly
+ * or partially, allow it.
+ */
+ if (view->answernames_exclude != NULL) {
+ result = dns_rbt_findnode(view->answernames_exclude, name, NULL,
+ &node, NULL, 0, NULL, NULL);
+ if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
+ return (ISC_TRUE);
+ }
+
+ /*
+ * If the target name is a subdomain of the search domain, allow it.
+ */
+ if (dns_name_issubdomain(tname, domain))
+ return (ISC_TRUE);
+
+ /*
+ * Otherwise, apply filters.
+ */
+ result = dns_rbt_findnode(view->denyanswernames, tname, NULL, &node,
+ NULL, 0, NULL, NULL);
+ if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
+ dns_name_format(name, qnamebuf, sizeof(qnamebuf));
+ dns_name_format(tname, tnamebuf, sizeof(tnamebuf));
+ dns_rdatatype_format(type, typebuf, sizeof(typebuf));
+ dns_rdataclass_format(view->rdclass, classbuf,
+ sizeof(classbuf));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
+ "%s target %s denied for %s/%s",
+ typebuf, tnamebuf, qnamebuf, classbuf);
+ return (ISC_FALSE);
+ }
+
+ return (ISC_TRUE);
+}
+
/*
* Handle a no-answer response (NXDOMAIN, NXRRSET, or referral).
- * If bind8_ns_resp is ISC_TRUE, this is a suspected BIND 8
- * response to an NS query that should be treated as a referral
- * even though the NS records occur in the answer section
- * rather than the authority section.
+ * If look_in_options has LOOK_FOR_NS_IN_ANSWER then we look in the answer
+ * section for the NS RRset if the query type is NS; if it has
+ * LOOK_FOR_GLUE_IN_ANSWER we look for glue incorrectly returned in the answer
+ * section for A and AAAA queries.
*/
+#define LOOK_FOR_NS_IN_ANSWER 0x1
+#define LOOK_FOR_GLUE_IN_ANSWER 0x2
+
static isc_result_t
noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
- isc_boolean_t bind8_ns_resp)
+ unsigned int look_in_options)
{
isc_result_t result;
dns_message_t *message;
@@ -5120,11 +5265,16 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
dns_rdataset_t *rdataset, *ns_rdataset;
isc_boolean_t aa, negative_response;
dns_rdatatype_t type;
- dns_section_t section =
- bind8_ns_resp ? DNS_SECTION_ANSWER : DNS_SECTION_AUTHORITY;
+ dns_section_t section;
FCTXTRACE("noanswer_response");
+ if ((look_in_options & LOOK_FOR_NS_IN_ANSWER) != 0) {
+ INSIST(fctx->type == dns_rdatatype_ns);
+ section = DNS_SECTION_ANSWER;
+ } else
+ section = DNS_SECTION_AUTHORITY;
+
message = fctx->rmessage;
/*
@@ -5197,8 +5347,22 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
type = rdataset->covers;
if (((type == dns_rdatatype_ns ||
type == dns_rdatatype_soa) &&
- !dns_name_issubdomain(qname, name)))
+ !dns_name_issubdomain(qname, name))) {
+ char qbuf[DNS_NAME_FORMATSIZE];
+ char nbuf[DNS_NAME_FORMATSIZE];
+ char tbuf[DNS_RDATATYPE_FORMATSIZE];
+ dns_rdatatype_format(fctx->type, tbuf,
+ sizeof(tbuf));
+ dns_name_format(name, nbuf,
+ sizeof(nbuf));
+ dns_name_format(qname, qbuf,
+ sizeof(qbuf));
+ log_formerr(fctx,
+ "unrelated %s %s in "
+ "%s authority section",
+ tbuf, qbuf, nbuf);
return (DNS_R_FORMERR);
+ }
if (type == dns_rdatatype_ns) {
/*
* NS or RRSIG NS.
@@ -5208,8 +5372,14 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
if (rdataset->type ==
dns_rdatatype_ns) {
if (ns_name != NULL &&
- name != ns_name)
+ name != ns_name) {
+ log_formerr(fctx,
+ "multiple NS "
+ "RRsets in "
+ "authority "
+ "section");
return (DNS_R_FORMERR);
+ }
ns_name = name;
ns_rdataset = rdataset;
}
@@ -5228,8 +5398,14 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
if (rdataset->type ==
dns_rdatatype_soa) {
if (soa_name != NULL &&
- name != soa_name)
+ name != soa_name) {
+ log_formerr(fctx,
+ "multiple SOA "
+ "RRs in "
+ "authority "
+ "section");
return (DNS_R_FORMERR);
+ }
soa_name = name;
}
name->attributes |=
@@ -5305,15 +5481,25 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
*
* These should only be here if
* this is a referral, and there
- * should only be one DS.
+ * should only be one DS RRset.
*/
- if (ns_name == NULL)
+ if (ns_name == NULL) {
+ log_formerr(fctx,
+ "DS with no "
+ "referral");
return (DNS_R_FORMERR);
+ }
if (rdataset->type ==
dns_rdatatype_ds) {
if (ds_name != NULL &&
- name != ds_name)
+ name != ds_name) {
+ log_formerr(fctx,
+ "DS doesn't "
+ "match "
+ "referral "
+ "(NS)");
return (DNS_R_FORMERR);
+ }
ds_name = name;
}
name->attributes |=
@@ -5363,6 +5549,7 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
/*
* The responder is insane.
*/
+ log_formerr(fctx, "invalid response");
return (DNS_R_FORMERR);
}
}
@@ -5370,8 +5557,10 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
/*
* If we found both NS and SOA, they should be the same name.
*/
- if (ns_name != NULL && soa_name != NULL && ns_name != soa_name)
+ if (ns_name != NULL && soa_name != NULL && ns_name != soa_name) {
+ log_formerr(fctx, "NS/SOA mismatch");
return (DNS_R_FORMERR);
+ }
/*
* Do we have a referral? (We only want to follow a referral if
@@ -5384,14 +5573,18 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
* progress. We return DNS_R_FORMERR so that we'll keep
* trying other servers.
*/
- if (dns_name_equal(ns_name, &fctx->domain))
+ if (dns_name_equal(ns_name, &fctx->domain)) {
+ log_formerr(fctx, "non-improving referral");
return (DNS_R_FORMERR);
+ }
/*
* If the referral name is not a parent of the query
* name, consider the responder insane.
*/
if (! dns_name_issubdomain(&fctx->name, ns_name)) {
+ /* Logged twice */
+ log_formerr(fctx, "referral to non-parent");
FCTXTRACE("referral to non-parent");
return (DNS_R_FORMERR);
}
@@ -5405,6 +5598,20 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
fctx->attributes |= FCTX_ATTR_GLUING;
(void)dns_rdataset_additionaldata(ns_rdataset, check_related,
fctx);
+#if CHECK_FOR_GLUE_IN_ANSWER
+ /*
+ * Look in the answer section for "glue" that is incorrectly
+ * returned as a answer. This is needed if the server also
+ * minimizes the response size by not adding records to the
+ * additional section that are in the answer section or if
+ * the record gets dropped due to message size constraints.
+ */
+ if ((look_in_options & LOOK_FOR_GLUE_IN_ANSWER) != 0 &&
+ (fctx->type == dns_rdatatype_aaaa ||
+ fctx->type == dns_rdatatype_a))
+ (void)dns_rdataset_additionaldata(ns_rdataset,
+ check_answer, fctx);
+#endif
fctx->attributes &= ~FCTX_ATTR_GLUING;
/*
* NS rdatasets with 0 TTL cause problems.
@@ -5460,6 +5667,7 @@ answer_response(fetchctx_t *fctx) {
unsigned int aflag;
dns_rdatatype_t type;
dns_fixedname_t dname, fqname;
+ dns_view_t *view;
FCTXTRACE("answer_response");
@@ -5482,6 +5690,7 @@ answer_response(fetchctx_t *fctx) {
aa = ISC_FALSE;
qname = &fctx->name;
type = fctx->type;
+ view = fctx->res->view;
result = dns_message_firstname(message, DNS_SECTION_ANSWER);
while (!done && result == ISC_R_SUCCESS) {
name = NULL;
@@ -5500,8 +5709,21 @@ answer_response(fetchctx_t *fctx) {
* NSEC3 records are not allowed to
* appear in the answer section.
*/
+ log_formerr(fctx, "NSEC3 in answer");
return (DNS_R_FORMERR);
}
+
+ /*
+ * Apply filters, if given, on answers to reject
+ * a malicious attempt of rebinding.
+ */
+ if ((rdataset->type == dns_rdatatype_a ||
+ rdataset->type == dns_rdatatype_aaaa) &&
+ !is_answeraddress_allowed(view, name,
+ rdataset)) {
+ return (DNS_R_SERVFAIL);
+ }
+
if (rdataset->type == type && !found_cname) {
/*
* We've found an ordinary answer.
@@ -5540,8 +5762,16 @@ answer_response(fetchctx_t *fctx) {
*/
if (type == dns_rdatatype_rrsig ||
type == dns_rdatatype_dnskey ||
- type == dns_rdatatype_nsec)
+ type == dns_rdatatype_nsec ||
+ type == dns_rdatatype_nsec3) {
+ char buf[DNS_RDATATYPE_FORMATSIZE];
+ dns_rdatatype_format(fctx->type,
+ buf, sizeof(buf));
+ log_formerr(fctx,
+ "CNAME response "
+ "for %s RR", buf);
return (DNS_R_FORMERR);
+ }
found = ISC_TRUE;
found_cname = ISC_TRUE;
want_chaining = ISC_TRUE;
@@ -5550,6 +5780,14 @@ answer_response(fetchctx_t *fctx) {
&tname);
if (result != ISC_R_SUCCESS)
return (result);
+ /* Apply filters on the target name. */
+ if (!is_answertarget_allowed(view,
+ name,
+ rdataset->type,
+ &tname,
+ &fctx->domain)) {
+ return (DNS_R_SERVFAIL);
+ }
} else if (rdataset->type == dns_rdatatype_rrsig
&& rdataset->covers ==
dns_rdatatype_cname
@@ -5650,6 +5888,8 @@ answer_response(fetchctx_t *fctx) {
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
isc_boolean_t found_dname = ISC_FALSE;
+ dns_name_t *dname_name;
+
found = ISC_FALSE;
aflag = 0;
if (rdataset->type == dns_rdatatype_dname) {
@@ -5660,12 +5900,15 @@ answer_response(fetchctx_t *fctx) {
* If we're not chaining, then the
* DNAME should not be external.
*/
- if (!chaining && external)
+ if (!chaining && external) {
+ log_formerr(fctx,
+ "external DNAME");
return (DNS_R_FORMERR);
+ }
found = ISC_TRUE;
want_chaining = ISC_TRUE;
aflag = DNS_RDATASETATTR_ANSWER;
- result = dname_target(rdataset,
+ result = dname_target(fctx, rdataset,
qname, name,
&dname);
if (result == ISC_R_NOSPACE) {
@@ -5679,6 +5922,15 @@ answer_response(fetchctx_t *fctx) {
return (result);
else
found_dname = ISC_TRUE;
+
+ dname_name = dns_fixedname_name(&dname);
+ if (!is_answertarget_allowed(view,
+ qname,
+ rdataset->type,
+ dname_name,
+ &fctx->domain)) {
+ return (DNS_R_SERVFAIL);
+ }
} else if (rdataset->type == dns_rdatatype_rrsig
&& rdataset->covers ==
dns_rdatatype_dname) {
@@ -5766,8 +6018,10 @@ answer_response(fetchctx_t *fctx) {
/*
* We should have found an answer.
*/
- if (!have_answer)
+ if (!have_answer) {
+ log_formerr(fctx, "reply has no answer");
return (DNS_R_FORMERR);
+ }
/*
* This response is now potentially cacheable.
@@ -5784,15 +6038,18 @@ answer_response(fetchctx_t *fctx) {
* If it isn't a noanswer response, no harm will be
* done.
*/
- return (noanswer_response(fctx, qname, ISC_FALSE));
+ return (noanswer_response(fctx, qname, 0));
}
/*
* We didn't end with an incomplete chain, so the rcode should be
* "no error".
*/
- if (message->rcode != dns_rcode_noerror)
+ if (message->rcode != dns_rcode_noerror) {
+ log_formerr(fctx, "CNAME/DNAME chain complete, but RCODE "
+ "indicates error");
return (DNS_R_FORMERR);
+ }
/*
* Examine the authority section (if there is one).
@@ -6129,6 +6386,39 @@ log_packet(dns_message_t *message, int level, isc_mem_t *mctx) {
isc_mem_put(mctx, buf, len);
}
+static isc_boolean_t
+iscname(fetchctx_t *fctx) {
+ isc_result_t result;
+
+ result = dns_message_findname(fctx->rmessage, DNS_SECTION_ANSWER,
+ &fctx->name, dns_rdatatype_cname, 0,
+ NULL, NULL);
+ return (result == ISC_R_SUCCESS ? ISC_TRUE : ISC_FALSE);
+}
+
+static isc_boolean_t
+betterreferral(fetchctx_t *fctx) {
+ isc_result_t result;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ dns_message_t *message = fctx->rmessage;
+
+ for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
+ result == ISC_R_SUCCESS;
+ result = dns_message_nextname(message, DNS_SECTION_AUTHORITY)) {
+ name = NULL;
+ dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
+ if (!isstrictsubdomain(name, &fctx->domain))
+ continue;
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link))
+ if (rdataset->type == dns_rdatatype_ns)
+ return (ISC_TRUE);
+ }
+ return (ISC_FALSE);
+}
+
static void
resquery_response(isc_task_t *task, isc_event_t *event) {
isc_result_t result = ISC_R_SUCCESS;
@@ -6180,6 +6470,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
fctx->timeouts = 0;
fctx->timeout = ISC_FALSE;
+ fctx->addrinfo = query->addrinfo;
/*
* XXXRTH We should really get the current time just once. We
@@ -6476,6 +6767,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
* cannot make any more progress with this
* fetch.
*/
+ log_formerr(fctx, "server sent FORMERR");
result = DNS_R_FORMERR;
}
} else if (message->rcode == dns_rcode_yxdomain) {
@@ -6590,27 +6882,62 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
(message->rcode == dns_rcode_noerror ||
message->rcode == dns_rcode_nxdomain)) {
/*
- * We've got answers. However, if we sent
- * a BIND 8 server an NS query, it may have
- * incorrectly responded with a non-authoritative
- * answer instead of a referral. Since this
- * answer lacks the SIGs necessary to do DNSSEC
- * validation, we must invoke the following special
- * kludge to treat it as a referral.
+ * [normal case]
+ * We've got answers. If it has an authoritative answer or an
+ * answer from a forwarder, we're done.
*/
- if (fctx->type == dns_rdatatype_ns &&
- (message->flags & DNS_MESSAGEFLAG_AA) == 0 &&
- !ISFORWARDER(query->addrinfo))
- {
- result = noanswer_response(fctx, NULL, ISC_TRUE);
+ if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 ||
+ ISFORWARDER(query->addrinfo))
+ result = answer_response(fctx);
+ else if (iscname(fctx) &&
+ fctx->type != dns_rdatatype_any &&
+ fctx->type != dns_rdatatype_cname) {
+ /*
+ * A BIND8 server could return a non-authoritative
+ * answer when a CNAME is followed. We should treat
+ * it as a valid answer.
+ */
+ result = answer_response(fctx);
+ } else if (fctx->type != dns_rdatatype_ns &&
+ !betterreferral(fctx)) {
+ /*
+ * Lame response !!!.
+ */
+ result = answer_response(fctx);
+ } else {
+ if (fctx->type == dns_rdatatype_ns) {
+ /*
+ * A BIND 8 server could incorrectly return a
+ * non-authoritative answer to an NS query
+ * instead of a referral. Since this answer
+ * lacks the SIGs necessary to do DNSSEC
+ * validation, we must invoke the following
+ * special kludge to treat it as a referral.
+ */
+ result = noanswer_response(fctx, NULL,
+ LOOK_FOR_NS_IN_ANSWER);
+ } else {
+ /*
+ * Some other servers may still somehow include
+ * an answer when it should return a referral
+ * with an empty answer. Check to see if we can
+ * treat this as a referral by ignoring the
+ * answer. Further more, there may be an
+ * implementation that moves A/AAAA glue records
+ * to the answer section for that type of
+ * delegation when the query is for that glue
+ * record. LOOK_FOR_GLUE_IN_ANSWER will handle
+ * such a corner case.
+ */
+ result = noanswer_response(fctx, NULL,
+ LOOK_FOR_GLUE_IN_ANSWER);
+ }
if (result != DNS_R_DELEGATION) {
/*
- * The answer section must have contained
- * something other than the NS records
- * we asked for. Since AA is not set
- * and the server is not a forwarder,
- * it is technically lame and it's easier
- * to treat it as such than to figure out
+ * At this point, AA is not set, the response
+ * is not a referral, and the server is not a
+ * forwarder. It is technically lame and it's
+ * easier to treat it as such than to figure out
* some more elaborate course of action.
*/
broken_server = DNS_R_LAME;
@@ -6619,7 +6946,6 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
}
goto force_referral;
}
- result = answer_response(fctx);
if (result != ISC_R_SUCCESS) {
if (result == DNS_R_FORMERR)
keep_trying = ISC_TRUE;
@@ -6631,7 +6957,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
/*
* NXDOMAIN, NXRDATASET, or referral.
*/
- result = noanswer_response(fctx, NULL, ISC_FALSE);
+ result = noanswer_response(fctx, NULL, 0);
if (result == DNS_R_CHASEDSSERVERS) {
} else if (result == DNS_R_DELEGATION) {
force_referral:
@@ -7043,6 +7369,7 @@ dns_resolver_create(dns_view_t *view,
res->spillatmax = 100;
res->spillattimer = NULL;
res->zero_no_soa_ttl = ISC_FALSE;
+ res->query_timeout = DEFAULT_QUERY_TIMEOUT;
res->ndisps = 0;
res->nextdisp = 0; /* meaningless at this point, but init it */
res->nbuckets = ntasks;
@@ -7194,6 +7521,7 @@ dns_resolver_create(dns_view_t *view,
return (result);
}
+#ifdef BIND9
static void
prime_done(isc_task_t *task, isc_event_t *event) {
dns_resolver_t *res;
@@ -7299,16 +7627,15 @@ dns_resolver_prime(dns_resolver_t *res) {
}
}
}
+#endif /* BIND9 */
void
dns_resolver_freeze(dns_resolver_t *res) {
-
/*
* Freeze resolver.
*/
REQUIRE(VALID_RESOLVER(res));
- REQUIRE(!res->frozen);
res->frozen = ISC_TRUE;
}
@@ -8341,3 +8668,22 @@ dns_resolver_getoptions(dns_resolver_t *resolver) {
return (resolver->options);
}
+
+unsigned int
+dns_resolver_gettimeout(dns_resolver_t *resolver) {
+ REQUIRE(VALID_RESOLVER(resolver));
+
+ return (resolver->query_timeout);
+}
+
+void
+dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int seconds) {
+ REQUIRE(VALID_RESOLVER(resolver));
+
+ if (seconds == 0)
+ seconds = DEFAULT_QUERY_TIMEOUT;
+ if (seconds > MAXIMUM_QUERY_TIMEOUT)
+ seconds = MAXIMUM_QUERY_TIMEOUT;
+
+ resolver->query_timeout = seconds;
+}
diff --git a/lib/dns/result.c b/lib/dns/result.c
index 2b0457c931a5..4cc194dc70c8 100644
--- a/lib/dns/result.c
+++ b/lib/dns/result.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.c,v 1.125.48.2 2010-02-25 10:56:41 tbox Exp $ */
+/* $Id: result.c,v 1.132 2011-01-11 23:47:13 tbox Exp $ */
/*! \file */
@@ -105,7 +105,7 @@ static const char *text[DNS_R_NRESULTS] = {
"no valid RRSIG", /*%< 59 DNS_R_NOVALIDSIG */
"no valid NSEC", /*%< 60 DNS_R_NOVALIDNSEC */
- "not insecure", /*%< 61 DNS_R_NOTINSECURE */
+ "insecurity proof failed", /*%< 61 DNS_R_NOTINSECURE */
"unknown service", /*%< 62 DNS_R_UNKNOWNSERVICE */
"recoverable error occurred", /*%< 63 DNS_R_RECOVERABLE */
"unknown opt attribute record", /*%< 64 DNS_R_UNKNOWNOPT */
@@ -160,6 +160,7 @@ static const char *text[DNS_R_NRESULTS] = {
"not master", /*%< 105 DNS_R_NOTMASTER */
"broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */
+ "expired", /*%< 106 DNS_R_EXPIRED */
};
static const char *rcode_text[DNS_R_NRCODERESULTS] = {
diff --git a/lib/dns/rootns.c b/lib/dns/rootns.c
index d51a0d6883ab..40e2244b4668 100644
--- a/lib/dns/rootns.c
+++ b/lib/dns/rootns.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rootns.c,v 1.36.50.4 2010-06-18 05:37:50 marka Exp $ */
+/* $Id: rootns.c,v 1.40 2010-06-18 05:36:24 marka Exp $ */
/*! \file */
diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c
new file mode 100644
index 000000000000..f809e7b06485
--- /dev/null
+++ b/lib/dns/rpz.c
@@ -0,0 +1,1168 @@
+/*
+ * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: rpz.c,v 1.7 2011-01-17 04:27:23 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <isc/buffer.h>
+#include <isc/mem.h>
+#include <isc/net.h>
+#include <isc/netaddr.h>
+#include <isc/print.h>
+#include <isc/stdlib.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/db.h>
+#include <dns/fixedname.h>
+#include <dns/log.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/result.h>
+#include <dns/rpz.h>
+#include <dns/view.h>
+
+
+/*
+ * Parallel radix trees for databases of response policy IP addresses
+ *
+ * The radix or Patricia trees are somewhat specialized to handle response
+ * policy addresses by representing the two test of IP IP addresses and name
+ * server IP addresses in a single tree.
+ *
+ * Each leaf indicates that an IP address is listed in the IP address or the
+ * name server IP address policy sub-zone (or both) of the corresponding
+ * response response zone. The policy data such as a CNAME or an A record
+ * is kept in the policy zone. After an IP address has been found in a radix
+ * tree, the node in the policy zone's database is found by converting
+ * the IP address to a domain name in a canonical form.
+ *
+ * The response policy zone canonical form of IPv6 addresses is one of:
+ * prefix.W.W.W.W.W.W.W.W
+ * prefix.WORDS.zz
+ * prefix.WORDS.zz.WORDS
+ * prefix.zz.WORDS
+ * where
+ * prefix is the prefix length of the IPv6 address between 1 and 128
+ * W is a number between 0 and 65535
+ * WORDS is one or more numbers W separated with "."
+ * zz corresponds to :: in the standard IPv6 text representation
+ *
+ * The canonical form of IPv4 addresses is:
+ * prefix.B.B.B.B
+ * where
+ * prefix is the prefix length of the address between 1 and 32
+ * B is a number between 0 and 255
+ *
+ * IPv4 addresses are distinguished from IPv6 addresses by having
+ * 5 labels all of which are numbers, and a prefix between 1 and 32.
+ */
+
+
+/*
+ * Use a private definition of IPv6 addresses because s6_addr32 is not
+ * always defined and our IPv6 addresses are in non-standard byte order
+ */
+typedef isc_uint32_t dns_rpz_cidr_word_t;
+#define DNS_RPZ_CIDR_WORD_BITS ((int)sizeof(dns_rpz_cidr_word_t)*8)
+#define DNS_RPZ_CIDR_KEY_BITS ((int)sizeof(dns_rpz_cidr_key_t)*8)
+#define DNS_RPZ_CIDR_WORDS (128/DNS_RPZ_CIDR_WORD_BITS)
+typedef struct {
+ dns_rpz_cidr_word_t w[DNS_RPZ_CIDR_WORDS];
+} dns_rpz_cidr_key_t;
+
+#define ADDR_V4MAPPED 0xffff
+
+#define DNS_RPZ_WORD_MASK(b) \
+ ((b) == 0 ? (dns_rpz_cidr_word_t)(-1) \
+ : ((dns_rpz_cidr_word_t)(-1) \
+ << (DNS_RPZ_CIDR_WORD_BITS - (b))))
+
+#define DNS_RPZ_IP_BIT(ip, bitno) \
+ (1 & ((ip)->w[(bitno)/DNS_RPZ_CIDR_WORD_BITS] >> \
+ (DNS_RPZ_CIDR_WORD_BITS - 1 - ((bitno) % DNS_RPZ_CIDR_WORD_BITS))))
+
+typedef struct dns_rpz_cidr_node dns_rpz_cidr_node_t;
+typedef isc_uint8_t dns_rpz_cidr_flags_t;
+struct dns_rpz_cidr_node {
+ dns_rpz_cidr_node_t *parent;
+ dns_rpz_cidr_node_t *child[2];
+ dns_rpz_cidr_key_t ip;
+ dns_rpz_cidr_bits_t bits;
+ dns_rpz_cidr_flags_t flags;
+#define DNS_RPZ_CIDR_FG_IP 0x01 /* has IP data or is parent of IP */
+#define DNS_RPZ_CIDR_FG_IP_DATA 0x02 /* has IP data */
+#define DNS_RPZ_CIDR_FG_NSIPv4 0x04 /* has or is parent of NSIPv4 data */
+#define DNS_RPZ_CIDR_FG_NSIPv6 0x08 /* has or is parent of NSIPv6 data */
+#define DNS_RPZ_CIDR_FG_NSIP_DATA 0x10 /* has NSIP data */
+};
+
+struct dns_rpz_cidr {
+ isc_mem_t *mctx;
+ isc_boolean_t had_nsdname;
+ dns_rpz_cidr_node_t *root;
+ dns_name_t ip_name; /* RPZ_IP_ZONE.LOCALHOST. */
+ dns_name_t nsip_name; /* RPZ_NSIP_ZONE.LOCALHOST. */
+ dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.LOCALHOST */
+};
+
+
+static isc_boolean_t have_rpz_zones = ISC_FALSE;
+
+
+const char *
+dns_rpz_type2str(dns_rpz_type_t type)
+{
+ switch (type) {
+ case DNS_RPZ_TYPE_QNAME:
+ return ("QNAME");
+ case DNS_RPZ_TYPE_IP:
+ return ("IP");
+ case DNS_RPZ_TYPE_NSIP:
+ return ("NSIP");
+ case DNS_RPZ_TYPE_NSDNAME:
+ return ("NSDNAME");
+ case DNS_RPZ_TYPE_BAD:
+ break;
+ }
+ FATAL_ERROR(__FILE__, __LINE__,
+ "impossible response policy zone type %d", type);
+ return ("impossible");
+}
+
+
+
+dns_rpz_policy_t
+dns_rpz_str2policy(const char *str)
+{
+ if (str == NULL)
+ return (DNS_RPZ_POLICY_ERROR);
+ if (!strcasecmp(str, "given"))
+ return (DNS_RPZ_POLICY_GIVEN);
+ if (!strcasecmp(str, "no-op"))
+ return (DNS_RPZ_POLICY_NO_OP);
+ if (!strcasecmp(str, "nxdomain"))
+ return (DNS_RPZ_POLICY_NXDOMAIN);
+ if (!strcasecmp(str, "nodata"))
+ return (DNS_RPZ_POLICY_NODATA);
+ if (!strcasecmp(str, "cname"))
+ return (DNS_RPZ_POLICY_CNAME);
+ return (DNS_RPZ_POLICY_ERROR);
+}
+
+
+
+/*
+ * Free the radix tree of a response policy database.
+ */
+void
+dns_rpz_cidr_free(dns_rpz_cidr_t **cidrp) {
+ dns_rpz_cidr_node_t *cur, *child, *parent;
+ dns_rpz_cidr_t *cidr;
+
+ REQUIRE(cidrp != NULL);
+
+ cidr = *cidrp;
+ if (cidr == NULL)
+ return;
+
+ cur = cidr->root;
+ while (cur != NULL) {
+ /* Depth first. */
+ child = cur->child[0];
+ if (child != NULL) {
+ cur = child;
+ continue;
+ }
+ child = cur->child[1];
+ if (child != NULL) {
+ cur = child;
+ continue;
+ }
+
+ /* Delete this leaf and go up. */
+ parent = cur->parent;
+ if (parent == NULL)
+ cidr->root = NULL;
+ else
+ parent->child[parent->child[1] == cur] = NULL;
+ isc_mem_put(cidr->mctx, cur, sizeof(*cur));
+ cur = parent;
+ }
+
+ dns_name_free(&cidr->ip_name, cidr->mctx);
+ dns_name_free(&cidr->nsip_name, cidr->mctx);
+ dns_name_free(&cidr->nsdname_name, cidr->mctx);
+ isc_mem_put(cidr->mctx, cidr, sizeof(*cidr));
+ *cidrp = NULL;
+}
+
+
+
+/*
+ * Forget a view's list of policy zones.
+ */
+void
+dns_rpz_view_destroy(dns_view_t *view) {
+ dns_rpz_zone_t *zone;
+
+ REQUIRE(view != NULL);
+
+ while (!ISC_LIST_EMPTY(view->rpz_zones)) {
+ zone = ISC_LIST_HEAD(view->rpz_zones);
+ ISC_LIST_UNLINK(view->rpz_zones, zone, link);
+ if (dns_name_dynamic(&zone->origin))
+ dns_name_free(&zone->origin, view->mctx);
+ if (dns_name_dynamic(&zone->nsdname))
+ dns_name_free(&zone->nsdname, view->mctx);
+ if (dns_name_dynamic(&zone->cname))
+ dns_name_free(&zone->cname, view->mctx);
+ isc_mem_put(view->mctx, zone, sizeof(*zone));
+ }
+}
+
+/*
+ * Note that we have at least one response policy zone.
+ * It would be better for something to tell the rbtdb code that the
+ * zone is in at least one view's list of policy zones.
+ */
+void
+dns_rpz_set_need(isc_boolean_t need)
+{
+ have_rpz_zones = need;
+}
+
+
+isc_boolean_t
+dns_rpz_needed(void)
+{
+ return (have_rpz_zones);
+}
+
+
+
+/*
+ * Start a new radix tree for a response policy zone.
+ */
+isc_result_t
+dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin,
+ dns_rpz_cidr_t **rbtdb_cidr)
+{
+ isc_result_t result;
+ dns_rpz_cidr_t *cidr;
+
+ REQUIRE(rbtdb_cidr != NULL && *rbtdb_cidr == NULL);
+
+ /*
+ * Only if there is at least one response policy zone.
+ */
+ if (!have_rpz_zones)
+ return (ISC_R_SUCCESS);
+
+ cidr = isc_mem_get(mctx, sizeof(*cidr));
+ if (cidr == NULL)
+ return (ISC_R_NOMEMORY);
+ memset(cidr, 0, sizeof(*cidr));
+ cidr->mctx = mctx;
+
+ dns_name_init(&cidr->ip_name, NULL);
+ result = dns_name_fromstring2(&cidr->ip_name, DNS_RPZ_IP_ZONE, origin,
+ DNS_NAME_DOWNCASE, mctx);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, cidr, sizeof(*cidr));
+ return (result);
+ }
+
+ dns_name_init(&cidr->nsip_name, NULL);
+ result = dns_name_fromstring2(&cidr->nsip_name, DNS_RPZ_NSIP_ZONE,
+ origin, DNS_NAME_DOWNCASE, mctx);
+ if (result != ISC_R_SUCCESS) {
+ dns_name_free(&cidr->ip_name, mctx);
+ isc_mem_put(mctx, cidr, sizeof(*cidr));
+ return (result);
+ }
+
+ dns_name_init(&cidr->nsdname_name, NULL);
+ result = dns_name_fromstring2(&cidr->nsdname_name, DNS_RPZ_NSDNAME_ZONE,
+ origin, DNS_NAME_DOWNCASE, mctx);
+ if (result != ISC_R_SUCCESS) {
+ dns_name_free(&cidr->nsip_name, mctx);
+ dns_name_free(&cidr->ip_name, mctx);
+ isc_mem_put(mctx, cidr, sizeof(*cidr));
+ return (result);
+ }
+
+ *rbtdb_cidr = cidr;
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * See if a policy zone has IP, NSIP, or NSDNAME rules or records.
+ */
+void
+dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) {
+ if (cidr->root != NULL &&
+ (cidr->root->flags & DNS_RPZ_CIDR_FG_IP) != 0)
+ st->state |= DNS_RPZ_HAVE_IP;
+ if (cidr->root != NULL &&
+ (cidr->root->flags & DNS_RPZ_CIDR_FG_NSIPv4) != 0)
+ st->state |= DNS_RPZ_HAVE_NSIPv4;
+ if (cidr->root != NULL &&
+ (cidr->root->flags & DNS_RPZ_CIDR_FG_NSIPv6) != 0)
+ st->state |= DNS_RPZ_HAVE_NSIPv6;
+ if (cidr->had_nsdname)
+ st->state |= DNS_RPZ_HAD_NSDNAME;
+}
+
+static inline dns_rpz_cidr_flags_t
+get_flags(const dns_rpz_cidr_key_t *ip, dns_rpz_cidr_bits_t prefix,
+ dns_rpz_type_t rpz_type)
+{
+ if (rpz_type == DNS_RPZ_TYPE_NSIP) {
+ if (prefix >= 96 &&
+ ip->w[0] == 0 && ip->w[1] == 0 &&
+ ip->w[2] == ADDR_V4MAPPED)
+ return (DNS_RPZ_CIDR_FG_NSIP_DATA |
+ DNS_RPZ_CIDR_FG_NSIPv4);
+ else
+ return (DNS_RPZ_CIDR_FG_NSIP_DATA |
+ DNS_RPZ_CIDR_FG_NSIPv6);
+ } else {
+ return (DNS_RPZ_CIDR_FG_IP | DNS_RPZ_CIDR_FG_IP_DATA);
+ }
+}
+
+
+
+/*
+ * Mark a node as having IP or NSIP data and all of its parents
+ * as members of the IP or NSIP tree.
+ */
+static void
+set_node_flags(dns_rpz_cidr_node_t *node, dns_rpz_type_t rpz_type) {
+ dns_rpz_cidr_flags_t flags;
+
+ flags = get_flags(&node->ip, node->bits, rpz_type);
+ node->flags |= flags;
+ flags &= ~(DNS_RPZ_CIDR_FG_NSIP_DATA | DNS_RPZ_CIDR_FG_IP_DATA);
+ for (;;) {
+ node = node->parent;
+ if (node == NULL)
+ return;
+ node->flags |= flags;
+ }
+}
+
+
+
+/*
+ * Make a radix tree node.
+ */
+static dns_rpz_cidr_node_t *
+new_node(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *ip,
+ dns_rpz_cidr_bits_t bits, dns_rpz_cidr_flags_t flags)
+{
+ dns_rpz_cidr_node_t *node;
+ int i, words, wlen;
+
+ node = isc_mem_get(cidr->mctx, sizeof(*node));
+ if (node == NULL)
+ return (NULL);
+ memset(node, 0, sizeof(*node));
+
+ node->flags = flags & ~(DNS_RPZ_CIDR_FG_IP_DATA |
+ DNS_RPZ_CIDR_FG_NSIP_DATA);
+
+ node->bits = bits;
+ words = bits / DNS_RPZ_CIDR_WORD_BITS;
+ wlen = bits % DNS_RPZ_CIDR_WORD_BITS;
+ i = 0;
+ while (i < words) {
+ node->ip.w[i] = ip->w[i];
+ ++i;
+ }
+ if (wlen != 0) {
+ node->ip.w[i] = ip->w[i] & DNS_RPZ_WORD_MASK(wlen);
+ ++i;
+ }
+ while (i < DNS_RPZ_CIDR_WORDS)
+ node->ip.w[i++] = 0;
+
+ return (node);
+}
+
+
+
+static void
+badname(int level, dns_name_t *name, const char *comment)
+{
+ char printname[DNS_NAME_FORMATSIZE];
+
+ if (isc_log_wouldlog(dns_lctx, level)) {
+ dns_name_format(name, printname, sizeof(printname));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_RBTDB, level,
+ "invalid response policy name \"%s\"%s",
+ printname, comment);
+ }
+}
+
+
+
+/*
+ * Convert an IP address from radix tree binary (host byte order) to
+ * to its canonical response policy domain name and its name in the
+ * policy zone.
+ */
+static isc_result_t
+ip2name(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip,
+ dns_rpz_cidr_bits_t tgt_prefix, dns_rpz_type_t type,
+ dns_name_t *canon_name, dns_name_t *search_name)
+{
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+ int w[DNS_RPZ_CIDR_WORDS*2];
+ char str[1+8+1+INET6_ADDRSTRLEN+1];
+ isc_buffer_t buffer;
+ dns_name_t *name;
+ isc_result_t result;
+ isc_boolean_t zeros;
+ int i, n, len;
+
+ if (tgt_prefix > 96 &&
+ tgt_ip->w[0] == 0 &&
+ tgt_ip->w[1] == 0 &&
+ tgt_ip->w[2] == ADDR_V4MAPPED) {
+ len = snprintf(str, sizeof(str), "%d.%d.%d.%d.%d",
+ tgt_prefix - 96,
+ tgt_ip->w[3] & 0xff,
+ (tgt_ip->w[3]>>8) & 0xff,
+ (tgt_ip->w[3]>>16) & 0xff,
+ (tgt_ip->w[3]>>24) & 0xff);
+ if (len == -1 || len > (int)sizeof(str))
+ return (ISC_R_FAILURE);
+ } else {
+ for (i = 0; i < DNS_RPZ_CIDR_WORDS; i++) {
+ w[i*2+1] = ((tgt_ip->w[DNS_RPZ_CIDR_WORDS-1-i] >> 16)
+ & 0xffff);
+ w[i*2] = tgt_ip->w[DNS_RPZ_CIDR_WORDS-1-i] & 0xffff;
+ }
+ zeros = ISC_FALSE;
+ len = snprintf(str, sizeof(str), "%d", tgt_prefix);
+ if (len == -1)
+ return (ISC_R_FAILURE);
+ i = 0;
+ while (i < DNS_RPZ_CIDR_WORDS * 2) {
+ if (w[i] != 0 || zeros
+ || i >= DNS_RPZ_CIDR_WORDS * 2 - 1
+ || w[i+1] != 0) {
+ INSIST((size_t)len <= sizeof(str));
+ n = snprintf(&str[len], sizeof(str) - len,
+ ".%x", w[i++]);
+ if (n < 0)
+ return (ISC_R_FAILURE);
+ len += n;
+ } else {
+ zeros = ISC_TRUE;
+ INSIST((size_t)len <= sizeof(str));
+ n = snprintf(&str[len], sizeof(str) - len,
+ ".zz");
+ if (n < 0)
+ return (ISC_R_FAILURE);
+ len += n;
+ i += 2;
+ while (i < DNS_RPZ_CIDR_WORDS * 2 && w[i] == 0)
+ ++i;
+ }
+ if (len > (int)sizeof(str))
+ return (ISC_R_FAILURE);
+ }
+ }
+
+ if (canon_name != NULL) {
+ isc__buffer_init(&buffer, str, sizeof(str));
+ isc__buffer_add(&buffer, len);
+ result = dns_name_fromtext(canon_name, &buffer,
+ dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+ if (search_name != NULL) {
+ isc__buffer_init(&buffer, str, sizeof(str));
+ isc__buffer_add(&buffer, len);
+ if (type == DNS_RPZ_TYPE_NSIP)
+ name = &cidr->nsip_name;
+ else
+ name = &cidr->ip_name;
+ result = dns_name_fromtext(search_name, &buffer, name, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+
+
+/*
+ * Decide which kind of IP address response policy zone a name is in.
+ */
+static dns_rpz_type_t
+set_type(dns_rpz_cidr_t *cidr, dns_name_t *name) {
+
+ if (dns_name_issubdomain(name, &cidr->ip_name))
+ return (DNS_RPZ_TYPE_IP);
+
+ /*
+ * Require `./configure --enable-rpz-nsip` and nsdname
+ * until consistency problems are resolved.
+ */
+#ifdef ENABLE_RPZ_NSIP
+ if (dns_name_issubdomain(name, &cidr->nsip_name))
+ return (DNS_RPZ_TYPE_NSIP);
+#endif
+
+#ifdef ENABLE_RPZ_NSDNAME
+ if (dns_name_issubdomain(name, &cidr->nsdname_name))
+ return (DNS_RPZ_TYPE_NSDNAME);
+#endif
+
+ return (DNS_RPZ_TYPE_QNAME);
+}
+
+
+
+/*
+ * Convert an IP address from canonical response policy domain name form
+ * to radix tree binary (host byte order).
+ */
+static isc_result_t
+name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
+ dns_rpz_type_t type, dns_rpz_cidr_key_t *tgt_ip,
+ dns_rpz_cidr_bits_t *tgt_prefix)
+{
+ isc_buffer_t buffer;
+ unsigned char data[DNS_NAME_MAXWIRE+1];
+ dns_fixedname_t fname;
+ dns_name_t *name;
+ const char *cp, *end;
+ char *cp2;
+ int ip_labels;
+ dns_rpz_cidr_bits_t bits;
+ unsigned long prefix, l;
+ int i;
+
+ /*
+ * Need at least enough labels for the shortest name,
+ * :: or 128.*.RPZ_x_ZONE.rpz.LOCALHOST.
+ */
+ ip_labels = dns_name_countlabels(src_name);
+ ip_labels -= dns_name_countlabels(&cidr->ip_name);
+ ip_labels--;
+ if (ip_labels < 1) {
+ badname(level, src_name, ", too short");
+ return (ISC_R_FAILURE);
+ }
+
+ /*
+ * Get text for the IP address without RPZ_x_ZONE.rpz.LOCALHOST.
+ */
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_name_split(src_name, dns_name_countlabels(&cidr->ip_name),
+ name, NULL);
+ isc_buffer_init(&buffer, data, sizeof(data));
+ dns_name_totext(name, ISC_TRUE, &buffer);
+ isc_buffer_putuint8(&buffer, '\0');
+ cp = isc_buffer_base(&buffer);
+
+ prefix = strtoul(cp, &cp2, 10);
+ if (prefix < 1U || prefix > 128U || *cp2 != '.') {
+ badname(level, src_name, ", bad prefix length");
+ return (ISC_R_FAILURE);
+ }
+ cp = cp2+1;
+
+ end = isc_buffer_used(&buffer);
+ if (ip_labels == 4 && !strchr(cp, 'z')) {
+ /*
+ * Convert an IPv4 address
+ * from the form "prefix.w.z.y.x"
+ */
+ if (prefix > 32U) {
+ badname(level, src_name, "; bad IPv4 prefix length");
+ return (ISC_R_FAILURE);
+ }
+ prefix += 96;
+ *tgt_prefix = (dns_rpz_cidr_bits_t)prefix;
+ tgt_ip->w[0] = 0;
+ tgt_ip->w[1] = 0;
+ tgt_ip->w[2] = ADDR_V4MAPPED;
+ tgt_ip->w[3] = 0;
+ for (i = 0; i < 32; i += 8) {
+ l = strtoul(cp, &cp2, 10);
+ if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) {
+ badname(level, src_name, "; bad IPv4 address");
+ return (ISC_R_FAILURE);
+ }
+ tgt_ip->w[3] |= l << i;
+ cp = cp2 + 1;
+ }
+ } else {
+ /*
+ * Convert a text IPv6 address.
+ */
+ *tgt_prefix = (dns_rpz_cidr_bits_t)prefix;
+ for (i = 0;
+ ip_labels > 0 && i < DNS_RPZ_CIDR_WORDS * 2;
+ ip_labels--) {
+ if (cp[0] == 'z' && cp[1] == 'z' &&
+ (cp[2] == '.' || cp[2] == '\0') &&
+ i <= 6) {
+ do {
+ if ((i & 1) == 0)
+ tgt_ip->w[3-i/2] = 0;
+ ++i;
+ } while (ip_labels + i <= 8);
+ cp += 3;
+ } else {
+ l = strtoul(cp, &cp2, 16);
+ if (l > 0xffffu ||
+ (*cp2 != '.' && *cp2 != '\0')) {
+ badname(level, src_name, "");
+ return (ISC_R_FAILURE);
+ }
+ if ((i & 1) == 0)
+ tgt_ip->w[3-i/2] = l;
+ else
+ tgt_ip->w[3-i/2] |= l << 16;
+ i++;
+ cp = cp2 + 1;
+ }
+ }
+ }
+ if (cp != end) {
+ badname(level, src_name, "");
+ return (ISC_R_FAILURE);
+ }
+
+ /*
+ * Check for 1s after the prefix length.
+ */
+ bits = (dns_rpz_cidr_bits_t)prefix;
+ while (bits < DNS_RPZ_CIDR_KEY_BITS) {
+ dns_rpz_cidr_word_t aword;
+
+ i = bits % DNS_RPZ_CIDR_WORD_BITS;
+ aword = tgt_ip->w[bits / DNS_RPZ_CIDR_WORD_BITS];
+ if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) {
+ badname(level, src_name, "; wrong prefix length");
+ return (ISC_R_FAILURE);
+ }
+ bits -= i;
+ bits += DNS_RPZ_CIDR_WORD_BITS;
+ }
+
+ /*
+ * Convert the IPv6 address back to a canonical policy domain name
+ * to ensure that it is in canonical form.
+ */
+ if (ISC_R_SUCCESS != ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t)prefix,
+ type, NULL, name) ||
+ !dns_name_equal(src_name, name)) {
+ badname(level, src_name, "; not canonical");
+ return (ISC_R_FAILURE);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+/*
+ * find first differing bit
+ */
+static int
+ffbit(dns_rpz_cidr_word_t w) {
+ int bit;
+
+ if (w == 0)
+ return (DNS_RPZ_CIDR_WORD_BITS);
+ for (bit = 0; (w & (1U << (DNS_RPZ_CIDR_WORD_BITS-1))) == 0; bit++)
+ w <<= 1;
+ return (bit);
+}
+
+
+
+/*
+ * find the first differing bit in two keys
+ */
+static int
+diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_cidr_bits_t bits1,
+ const dns_rpz_cidr_key_t *key2, dns_rpz_cidr_bits_t bits2)
+{
+ dns_rpz_cidr_word_t delta;
+ dns_rpz_cidr_bits_t maxbit, bit;
+ int i;
+
+ maxbit = ISC_MIN(bits1, bits2);
+
+ /*
+ * find the first differing words
+ */
+ for (i = 0, bit = 0;
+ bit <= maxbit;
+ i++, bit += DNS_RPZ_CIDR_WORD_BITS) {
+ delta = key1->w[i] ^ key2->w[i];
+ if (delta != 0) {
+ bit += ffbit(delta);
+ break;
+ }
+ }
+ return (ISC_MIN(bit, maxbit));
+}
+
+
+
+/*
+ * Search a radix tree for an IP address for ordinary lookup
+ * or for a CIDR block adding or deleting an entry
+ * The tree read (for simple search) or write lock must be held by the caller.
+ *
+ * return ISC_R_SUCCESS, ISC_R_NOTFOUND, DNS_R_PARTIALMATCH, ISC_R_EXISTS,
+ * ISC_R_NOMEMORY
+ */
+static isc_result_t
+search(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip,
+ dns_rpz_cidr_bits_t tgt_prefix, dns_rpz_type_t type,
+ isc_boolean_t create,
+ dns_rpz_cidr_node_t **found) /* NULL or longest match node */
+{
+ dns_rpz_cidr_node_t *cur, *parent, *child, *new_parent, *sibling;
+ int cur_num, child_num;
+ dns_rpz_cidr_bits_t dbit;
+ dns_rpz_cidr_flags_t flags, data_flag;
+ isc_result_t find_result;
+
+ flags = get_flags(tgt_ip, tgt_prefix, type);
+ data_flag = flags & (DNS_RPZ_CIDR_FG_IP_DATA |
+ DNS_RPZ_CIDR_FG_NSIP_DATA);
+
+ find_result = ISC_R_NOTFOUND;
+ if (found != NULL)
+ *found = NULL;
+ cur = cidr->root;
+ parent = NULL;
+ cur_num = 0;
+ for (;;) {
+ if (cur == NULL) {
+ /*
+ * No child so we cannot go down. Fail or
+ * add the target as a child of the current parent.
+ */
+ if (!create)
+ return (find_result);
+ child = new_node(cidr, tgt_ip, tgt_prefix, 0);
+ if (child == NULL)
+ return (ISC_R_NOMEMORY);
+ if (parent == NULL)
+ cidr->root = child;
+ else
+ parent->child[cur_num] = child;
+ child->parent = parent;
+ set_node_flags(child, type);
+ if (found != NULL)
+ *found = cur;
+ return (ISC_R_SUCCESS);
+ }
+
+ /*
+ * Pretend a node not in the correct tree does not exist
+ * if we are not adding to the tree,
+ * If we are adding, then continue down to eventually
+ * add a node and mark/put this node in the correct tree.
+ */
+ if ((cur->flags & flags) == 0 && !create)
+ return (find_result);
+
+ dbit = diff_keys(tgt_ip, tgt_prefix, &cur->ip, cur->bits);
+ /*
+ * dbit <= tgt_prefix and dbit <= cur->bits always.
+ * We are finished searching if we matched all of the target.
+ */
+ if (dbit == tgt_prefix) {
+ if (tgt_prefix == cur->bits) {
+ /*
+ * The current node matches the target exactly.
+ * It is the answer if it has data.
+ */
+ if ((cur->flags & data_flag) != 0) {
+ if (create)
+ return (ISC_R_EXISTS);
+ if (found != NULL)
+ *found = cur;
+ return (ISC_R_SUCCESS);
+ } else if (create) {
+ /*
+ * The node had no data but does now.
+ */
+ set_node_flags(cur, type);
+ if (found != NULL)
+ *found = cur;
+ return (ISC_R_SUCCESS);
+ }
+ return (find_result);
+ }
+
+ /*
+ * We know tgt_prefix < cur_bits which means that
+ * the target is shorter than the current node.
+ * Add the target as the current node's parent.
+ */
+ if (!create)
+ return (find_result);
+
+ new_parent = new_node(cidr, tgt_ip, tgt_prefix,
+ cur->flags);
+ if (new_parent == NULL)
+ return (ISC_R_NOMEMORY);
+ new_parent->parent = parent;
+ if (parent == NULL)
+ cidr->root = new_parent;
+ else
+ parent->child[cur_num] = new_parent;
+ child_num = DNS_RPZ_IP_BIT(&cur->ip, tgt_prefix+1);
+ new_parent->child[child_num] = cur;
+ cur->parent = new_parent;
+ set_node_flags(new_parent, type);
+ if (found != NULL)
+ *found = new_parent;
+ return (ISC_R_SUCCESS);
+ }
+
+ if (dbit == cur->bits) {
+ /*
+ * We have a partial match by matching of all of the
+ * current node but only part of the target.
+ * Try to go down.
+ */
+ if ((cur->flags & data_flag) != 0) {
+ find_result = DNS_R_PARTIALMATCH;
+ if (found != NULL)
+ *found = cur;
+ }
+
+ parent = cur;
+ cur_num = DNS_RPZ_IP_BIT(tgt_ip, dbit);
+ cur = cur->child[cur_num];
+ continue;
+ }
+
+
+ /*
+ * dbit < tgt_prefix and dbit < cur->bits,
+ * so we failed to match both the target and the current node.
+ * Insert a fork of a parent above the current node and
+ * add the target as a sibling of the current node
+ */
+ if (!create)
+ return (find_result);
+
+ sibling = new_node(cidr, tgt_ip, tgt_prefix, 0);
+ if (sibling == NULL)
+ return (ISC_R_NOMEMORY);
+ new_parent = new_node(cidr, tgt_ip, dbit, cur->flags);
+ if (new_parent == NULL) {
+ isc_mem_put(cidr->mctx, sibling, sizeof(*sibling));
+ return (ISC_R_NOMEMORY);
+ }
+ new_parent->parent = parent;
+ if (parent == NULL)
+ cidr->root = new_parent;
+ else
+ parent->child[cur_num] = new_parent;
+ child_num = DNS_RPZ_IP_BIT(tgt_ip, dbit);
+ new_parent->child[child_num] = sibling;
+ new_parent->child[1-child_num] = cur;
+ cur->parent = new_parent;
+ sibling->parent = new_parent;
+ set_node_flags(sibling, type);
+ if (found != NULL)
+ *found = sibling;
+ return (ISC_R_SUCCESS);
+ }
+}
+
+
+
+/*
+ * Add an IP address to the radix tree of a response policy database.
+ * The tree write lock must be held by the caller.
+ */
+void
+dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name)
+{
+ dns_rpz_cidr_key_t tgt_ip;
+ dns_rpz_cidr_bits_t tgt_prefix;
+ dns_rpz_type_t type;
+
+ if (cidr == NULL)
+ return;
+
+ /*
+ * no worries if the new name is not an IP address
+ */
+ type = set_type(cidr, name);
+ switch (type) {
+ case DNS_RPZ_TYPE_IP:
+ case DNS_RPZ_TYPE_NSIP:
+ break;
+ case DNS_RPZ_TYPE_NSDNAME:
+ cidr->had_nsdname = ISC_TRUE;
+ return;
+ case DNS_RPZ_TYPE_QNAME:
+ case DNS_RPZ_TYPE_BAD:
+ return;
+ }
+ if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name,
+ type, &tgt_ip, &tgt_prefix))
+ return;
+
+ if (ISC_R_EXISTS == search(cidr, &tgt_ip, tgt_prefix, type,
+ ISC_TRUE, NULL) &&
+ isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) {
+ char printname[DNS_NAME_FORMATSIZE];
+
+ dns_name_format(name, printname, sizeof(printname));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
+ "duplicate response policy name \"%s\"",
+ printname);
+ }
+}
+
+
+
+/*
+ * Delete an IP address from the radix tree of a response policy database.
+ * The tree write lock must be held by the caller.
+ */
+void
+dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
+ dns_rpz_cidr_key_t tgt_ip;
+ dns_rpz_cidr_bits_t tgt_prefix;
+ dns_rpz_type_t type;
+ dns_rpz_cidr_node_t *tgt = NULL, *parent, *child;
+ dns_rpz_cidr_flags_t flags, data_flag;
+
+ if (cidr == NULL)
+ return;
+
+ /*
+ * Decide which kind of policy zone IP address it is, if either
+ * and then find its node.
+ */
+ type = set_type(cidr, name);
+ switch (type) {
+ case DNS_RPZ_TYPE_IP:
+ case DNS_RPZ_TYPE_NSIP:
+ break;
+ case DNS_RPZ_TYPE_NSDNAME:
+ /*
+ * We cannot easily count nsdnames because
+ * internal rbt nodes get deleted.
+ */
+ return;
+ case DNS_RPZ_TYPE_QNAME:
+ case DNS_RPZ_TYPE_BAD:
+ return;
+ }
+
+ /*
+ * Do not get excited about the deletion of interior rbt nodes.
+ */
+ if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_DEBUG_LEVEL2, name,
+ type, &tgt_ip, &tgt_prefix))
+ return;
+ if (ISC_R_SUCCESS != search(cidr, &tgt_ip, tgt_prefix, type,
+ ISC_FALSE, &tgt)) {
+ if (isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) {
+ char printname[DNS_NAME_FORMATSIZE];
+
+ dns_name_format(name, printname, sizeof(printname));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
+ "missing response policy node \"%s\"",
+ printname);
+ }
+ return;
+ }
+
+ /*
+ * Mark the node and its parents to reflect the deleted IP address.
+ */
+ flags = get_flags(&tgt_ip, tgt_prefix, type);
+ data_flag = flags & (DNS_RPZ_CIDR_FG_IP_DATA |
+ DNS_RPZ_CIDR_FG_NSIP_DATA);
+ tgt->flags &= ~data_flag;
+ for (parent = tgt; parent != NULL; parent = parent->parent) {
+ if ((parent->flags & data_flag) != 0 ||
+ (parent->child[0] != NULL &&
+ (parent->child[0]->flags & flags) != 0) ||
+ (parent->child[1] != NULL &&
+ (parent->child[1]->flags & flags) != 0))
+ break;
+ parent->flags &= ~flags;
+ }
+
+ /*
+ * We might need to delete 2 nodes.
+ */
+ do {
+ /*
+ * The node is now useless if it has no data of its own
+ * and 0 or 1 children. We are finished if it is not useless.
+ */
+ if ((child = tgt->child[0]) != NULL) {
+ if (tgt->child[1] != NULL)
+ return;
+ } else {
+ child = tgt->child[1];
+ }
+ if ((tgt->flags & (DNS_RPZ_CIDR_FG_IP_DATA |
+ DNS_RPZ_CIDR_FG_NSIP_DATA)) != 0)
+ return;
+
+ /*
+ * Replace the pointer to this node in the parent with
+ * the remaining child or NULL.
+ */
+ parent = tgt->parent;
+ if (parent == NULL) {
+ cidr->root = child;
+ } else {
+ parent->child[parent->child[1] == tgt] = child;
+ }
+ /*
+ * If the child exists fix up its parent pointer.
+ */
+ if (child != NULL)
+ child->parent = parent;
+ isc_mem_put(cidr->mctx, tgt, sizeof(*tgt));
+
+ tgt = parent;
+ } while (tgt != NULL);
+}
+
+
+
+/*
+ * Caller must hold tree lock.
+ * Return ISC_R_NOTFOUND
+ * or ISC_R_SUCCESS and the found entry's canonical and search names
+ * and its prefix length
+ */
+isc_result_t
+dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr,
+ dns_rpz_type_t type, dns_name_t *canon_name,
+ dns_name_t *search_name, dns_rpz_cidr_bits_t *prefix)
+{
+ dns_rpz_cidr_key_t tgt_ip;
+ isc_result_t result;
+ dns_rpz_cidr_node_t *found;
+ int i;
+
+ /*
+ * Convert IP address to CIDR tree key.
+ */
+ if (netaddr->family == AF_INET) {
+ tgt_ip.w[0] = 0;
+ tgt_ip.w[1] = 0;
+ tgt_ip.w[2] = ADDR_V4MAPPED;
+ tgt_ip.w[3] = ntohl(netaddr->type.in.s_addr);
+ } else if (netaddr->family == AF_INET6) {
+ dns_rpz_cidr_key_t src_ip6;
+
+ /*
+ * Given the int aligned struct in_addr member of netaddr->type
+ * one could cast netaddr->type.in6 to dns_rpz_cidr_key_t *,
+ * but there are objections.
+ */
+ memcpy(src_ip6.w, &netaddr->type.in6, sizeof(src_ip6.w));
+ for (i = 0; i < 4; i++) {
+ tgt_ip.w[i] = ntohl(src_ip6.w[i]);
+ }
+ } else {
+ return (ISC_R_NOTFOUND);
+ }
+
+ result = search(cidr, &tgt_ip, 128, type, ISC_FALSE, &found);
+ if (result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH)
+ return (result);
+
+ *prefix = found->bits;
+ return (ip2name(cidr, &found->ip, found->bits, type,
+ canon_name, search_name));
+}
+
+
+
+/*
+ * Translate CNAME rdata to a QNAME response policy action.
+ */
+dns_rpz_policy_t
+dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_cname_t cname;
+ isc_result_t result;
+
+ result = dns_rdataset_first(rdataset);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ dns_rdataset_current(rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &cname, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ dns_rdata_reset(&rdata);
+
+ /*
+ * CNAME . means NXDOMAIN
+ */
+ if (dns_name_equal(&cname.cname, dns_rootname))
+ return (DNS_RPZ_POLICY_NXDOMAIN);
+
+ /*
+ * CNAME *. means NODATA
+ */
+ if (dns_name_countlabels(&cname.cname) == 2
+ && dns_name_iswildcard(&cname.cname))
+ return (DNS_RPZ_POLICY_NODATA);
+
+ /*
+ * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. means "do not rewrite"
+ */
+ if (selfname != NULL && dns_name_equal(&cname.cname, selfname))
+ return (DNS_RPZ_POLICY_NO_OP);
+
+ /*
+ * evil.com CNAME garden.net rewrites www.evil.com to www.garden.net.
+ */
+ return (DNS_RPZ_POLICY_RECORD);
+}
diff --git a/lib/dns/rriterator.c b/lib/dns/rriterator.c
new file mode 100644
index 000000000000..31d67afd9311
--- /dev/null
+++ b/lib/dns/rriterator.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: rriterator.c,v 1.2 2009-06-30 02:52:32 each Exp $ */
+
+/*! \file */
+
+/***
+ *** Imports
+ ***/
+
+#include <config.h>
+
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/db.h>
+#include <dns/dbiterator.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatasetiter.h>
+#include <dns/result.h>
+#include <dns/rriterator.h>
+
+/***
+ *** RRiterator methods
+ ***/
+
+isc_result_t
+dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
+ isc_stdtime_t now)
+{
+ isc_result_t result;
+ it->magic = RRITERATOR_MAGIC;
+ it->db = db;
+ it->dbit = NULL;
+ it->ver = ver;
+ it->now = now;
+ it->node = NULL;
+ result = dns_db_createiterator(it->db, 0, &it->dbit);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ it->rdatasetit = NULL;
+ dns_rdata_init(&it->rdata);
+ dns_rdataset_init(&it->rdataset);
+ dns_fixedname_init(&it->fixedname);
+ INSIST(! dns_rdataset_isassociated(&it->rdataset));
+ it->result = ISC_R_SUCCESS;
+ return (it->result);
+}
+
+isc_result_t
+dns_rriterator_first(dns_rriterator_t *it) {
+ REQUIRE(VALID_RRITERATOR(it));
+ /* Reset state */
+ if (dns_rdataset_isassociated(&it->rdataset))
+ dns_rdataset_disassociate(&it->rdataset);
+ if (it->rdatasetit != NULL)
+ dns_rdatasetiter_destroy(&it->rdatasetit);
+ if (it->node != NULL)
+ dns_db_detachnode(it->db, &it->node);
+ it->result = dns_dbiterator_first(it->dbit);
+
+ /*
+ * The top node may be empty when out of zone glue exists.
+ * Walk the tree to find the first node with data.
+ */
+ while (it->result == ISC_R_SUCCESS) {
+ it->result = dns_dbiterator_current(it->dbit, &it->node,
+ dns_fixedname_name(&it->fixedname));
+ if (it->result != ISC_R_SUCCESS)
+ return (it->result);
+
+ it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
+ it->now, &it->rdatasetit);
+ if (it->result != ISC_R_SUCCESS)
+ return (it->result);
+
+ it->result = dns_rdatasetiter_first(it->rdatasetit);
+ if (it->result != ISC_R_SUCCESS) {
+ /*
+ * This node is empty. Try next node.
+ */
+ dns_rdatasetiter_destroy(&it->rdatasetit);
+ dns_db_detachnode(it->db, &it->node);
+ it->result = dns_dbiterator_next(it->dbit);
+ continue;
+ }
+ dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
+ it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
+ it->result = dns_rdataset_first(&it->rdataset);
+ return (it->result);
+ }
+ return (it->result);
+}
+
+isc_result_t
+dns_rriterator_nextrrset(dns_rriterator_t *it) {
+ REQUIRE(VALID_RRITERATOR(it));
+ if (dns_rdataset_isassociated(&it->rdataset))
+ dns_rdataset_disassociate(&it->rdataset);
+ it->result = dns_rdatasetiter_next(it->rdatasetit);
+ /*
+ * The while loop body is executed more than once
+ * only when an empty dbnode needs to be skipped.
+ */
+ while (it->result == ISC_R_NOMORE) {
+ dns_rdatasetiter_destroy(&it->rdatasetit);
+ dns_db_detachnode(it->db, &it->node);
+ it->result = dns_dbiterator_next(it->dbit);
+ if (it->result == ISC_R_NOMORE) {
+ /* We are at the end of the entire database. */
+ return (it->result);
+ }
+ if (it->result != ISC_R_SUCCESS)
+ return (it->result);
+ it->result = dns_dbiterator_current(it->dbit, &it->node,
+ dns_fixedname_name(&it->fixedname));
+ if (it->result != ISC_R_SUCCESS)
+ return (it->result);
+ it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
+ it->now, &it->rdatasetit);
+ if (it->result != ISC_R_SUCCESS)
+ return (it->result);
+ it->result = dns_rdatasetiter_first(it->rdatasetit);
+ }
+ if (it->result != ISC_R_SUCCESS)
+ return (it->result);
+ dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
+ it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
+ it->result = dns_rdataset_first(&it->rdataset);
+ return (it->result);
+}
+
+isc_result_t
+dns_rriterator_next(dns_rriterator_t *it) {
+ REQUIRE(VALID_RRITERATOR(it));
+ if (it->result != ISC_R_SUCCESS)
+ return (it->result);
+
+ INSIST(it->dbit != NULL);
+ INSIST(it->node != NULL);
+ INSIST(it->rdatasetit != NULL);
+
+ it->result = dns_rdataset_next(&it->rdataset);
+ if (it->result == ISC_R_NOMORE)
+ return (dns_rriterator_nextrrset(it));
+ return (it->result);
+}
+
+void
+dns_rriterator_pause(dns_rriterator_t *it) {
+ REQUIRE(VALID_RRITERATOR(it));
+ RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS);
+}
+
+void
+dns_rriterator_destroy(dns_rriterator_t *it) {
+ REQUIRE(VALID_RRITERATOR(it));
+ if (dns_rdataset_isassociated(&it->rdataset))
+ dns_rdataset_disassociate(&it->rdataset);
+ if (it->rdatasetit != NULL)
+ dns_rdatasetiter_destroy(&it->rdatasetit);
+ if (it->node != NULL)
+ dns_db_detachnode(it->db, &it->node);
+ dns_dbiterator_destroy(&it->dbit);
+}
+
+void
+dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name,
+ isc_uint32_t *ttl, dns_rdataset_t **rdataset,
+ dns_rdata_t **rdata)
+{
+ REQUIRE(name != NULL && *name == NULL);
+ REQUIRE(VALID_RRITERATOR(it));
+ REQUIRE(it->result == ISC_R_SUCCESS);
+
+ *name = dns_fixedname_name(&it->fixedname);
+ *ttl = it->rdataset.ttl;
+
+ dns_rdata_reset(&it->rdata);
+ dns_rdataset_current(&it->rdataset, &it->rdata);
+
+ if (rdataset)
+ *rdataset = &it->rdataset;
+
+ if (rdata)
+ *rdata = &it->rdata;
+}
diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c
index 49c6430152de..d27007d3e6b3 100644
--- a/lib/dns/sdb.c
+++ b/lib/dns/sdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdb.c,v 1.66.48.6 2010-08-16 05:21:42 marka Exp $ */
+/* $Id: sdb.c,v 1.76 2011-01-13 04:59:25 tbox Exp $ */
/*! \file */
@@ -450,7 +450,7 @@ getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) {
isc_buffer_init(&b, name, strlen(name));
isc_buffer_add(&b, strlen(name));
- result = dns_name_fromtext(newname, &b, origin, ISC_FALSE, NULL);
+ result = dns_name_fromtext(newname, &b, origin, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
@@ -1253,6 +1253,8 @@ static dns_dbmethods_t sdb_methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c
index 6be315a4e742..e684e1dacca3 100644
--- a/lib/dns/sdlz.c
+++ b/lib/dns/sdlz.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2005-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2005-2011 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdlz.c,v 1.18.50.6 2010-08-16 05:21:42 marka Exp $ */
+/* $Id: sdlz.c,v 1.31 2011-01-13 06:29:16 marka Exp $ */
/*! \file */
@@ -108,6 +108,8 @@ struct dns_sdlz_db {
isc_mutex_t refcnt_lock;
/* Locked */
unsigned int references;
+ dns_dbversion_t *future_version;
+ int dummy_version;
};
struct dns_sdlzlookup {
@@ -164,8 +166,6 @@ typedef struct sdlz_rdatasetiter {
/* This is a reasonable value */
#define SDLZ_DEFAULT_TTL (60 * 60 * 24)
-static int dummy;
-
#ifdef __COVERITY__
#define MAYBE_LOCK(imp) LOCK(&imp->driverlock)
#define MAYBE_UNLOCK(imp) UNLOCK(&imp->driverlock)
@@ -225,11 +225,22 @@ static dns_dbiteratormethods_t dbiterator_methods = {
* Utility functions
*/
-/*% Converts the input string to lowercase, in place. */
+/*
+ * Log a message at the given level
+ */
+static void
+sdlz_log(int level, const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level),
+ fmt, ap);
+ va_end(ap);
+}
+/*% Converts the input string to lowercase, in place. */
static void
dns_sdlz_tolower(char *str) {
-
unsigned int len = strlen(str);
unsigned int i;
@@ -237,7 +248,6 @@ dns_sdlz_tolower(char *str) {
if (str[i] >= 'A' && str[i] <= 'Z')
str[i] += 32;
}
-
}
static inline unsigned int
@@ -381,43 +391,79 @@ dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
static void
currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
+ REQUIRE(VALID_SDLZDB(sdlz));
REQUIRE(versionp != NULL && *versionp == NULL);
- UNUSED(db);
-
- *versionp = (void *) &dummy;
+ *versionp = (void *) &sdlz->dummy_version;
return;
}
static isc_result_t
newversion(dns_db_t *db, dns_dbversion_t **versionp) {
- UNUSED(db);
- UNUSED(versionp);
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
+ char origin[DNS_NAME_MAXTEXT + 1];
+ isc_result_t result;
- return (ISC_R_NOTIMPLEMENTED);
+ REQUIRE(VALID_SDLZDB(sdlz));
+
+ if (sdlz->dlzimp->methods->newversion == NULL)
+ return (ISC_R_NOTIMPLEMENTED);
+
+ dns_name_format(&sdlz->common.origin, origin, sizeof(origin));
+
+ result = sdlz->dlzimp->methods->newversion(origin,
+ sdlz->dlzimp->driverarg,
+ sdlz->dbdata, versionp);
+ if (result != ISC_R_SUCCESS) {
+ sdlz_log(ISC_LOG_ERROR,
+ "sdlz newversion on origin %s failed : %s",
+ origin, isc_result_totext(result));
+ return (result);
+ }
+
+ sdlz->future_version = *versionp;
+ return (ISC_R_SUCCESS);
}
static void
attachversion(dns_db_t *db, dns_dbversion_t *source,
dns_dbversion_t **targetp)
{
- REQUIRE(source != NULL && source == (void *) &dummy);
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
+
+ REQUIRE(VALID_SDLZDB(sdlz));
+ REQUIRE(source != NULL && source == (void *)&sdlz->dummy_version);
- UNUSED(db);
- UNUSED(source);
- UNUSED(targetp);
*targetp = source;
}
static void
closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
- REQUIRE(versionp != NULL && *versionp == (void *) &dummy);
- REQUIRE(commit == ISC_FALSE);
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
+ char origin[DNS_NAME_MAXTEXT + 1];
- UNUSED(db);
- UNUSED(commit);
+ REQUIRE(VALID_SDLZDB(sdlz));
+ REQUIRE(versionp != NULL);
+
+ if (*versionp == (void *)&sdlz->dummy_version) {
+ *versionp = NULL;
+ return;
+ }
+
+ REQUIRE(*versionp == sdlz->future_version);
+ REQUIRE(sdlz->dlzimp->methods->closeversion != NULL);
+
+ dns_name_format(&sdlz->common.origin, origin, sizeof(origin));
- *versionp = NULL;
+ sdlz->dlzimp->methods->closeversion(origin, commit,
+ sdlz->dlzimp->driverarg,
+ sdlz->dbdata, versionp);
+ if (*versionp != NULL)
+ sdlz_log(ISC_LOG_ERROR,
+ "sdlz closeversion on origin %s failed", origin);
+
+ sdlz->future_version = NULL;
}
static isc_result_t
@@ -506,11 +552,11 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
dns_sdlzauthorityfunc_t authority;
REQUIRE(VALID_SDLZDB(sdlz));
- REQUIRE(create == ISC_FALSE);
REQUIRE(nodep != NULL && *nodep == NULL);
- UNUSED(name);
- UNUSED(create);
+ if (sdlz->dlzimp->methods->newversion == NULL) {
+ REQUIRE(create == ISC_FALSE);
+ }
isc_buffer_init(&b, namestr, sizeof(namestr));
if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVEOWNER) != 0) {
@@ -558,7 +604,7 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
* if the host (namestr) was not found, try to lookup a
* "wildcard" host.
*/
- if (result != ISC_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS && !create) {
result = sdlz->dlzimp->methods->lookup(zonestr, "*",
sdlz->dlzimp->driverarg,
sdlz->dbdata, node);
@@ -566,7 +612,7 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
MAYBE_UNLOCK(sdlz->dlzimp);
- if (result != ISC_R_SUCCESS && !isorigin) {
+ if (result != ISC_R_SUCCESS && !isorigin && !create) {
destroynode(node);
return (result);
}
@@ -584,6 +630,23 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
}
}
+ if (node->name == NULL) {
+ node->name = isc_mem_get(sdlz->common.mctx,
+ sizeof(dns_name_t));
+ if (node->name == NULL) {
+ destroynode(node);
+ return (ISC_R_NOMEMORY);
+ }
+ dns_name_init(node->name, NULL);
+ result = dns_name_dup(name, sdlz->common.mctx, node->name);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(sdlz->common.mctx, node->name,
+ sizeof(dns_name_t));
+ destroynode(node);
+ return (result);
+ }
+ }
+
*nodep = node;
return (ISC_R_SUCCESS);
}
@@ -778,7 +841,7 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
REQUIRE(VALID_SDLZDB(sdlz));
REQUIRE(nodep == NULL || *nodep == NULL);
- REQUIRE(version == NULL || version == (void *) &dummy);
+ REQUIRE(version == NULL || version == (void*)&sdlz->dummy_version);
UNUSED(options);
UNUSED(sdlz);
@@ -920,9 +983,14 @@ static isc_result_t
allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
{
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) db;
sdlz_rdatasetiter_t *iterator;
- REQUIRE(version == NULL || version == &dummy);
+ REQUIRE(VALID_SDLZDB(sdlz));
+
+ REQUIRE(version == NULL ||
+ version == (void*)&sdlz->dummy_version ||
+ version == sdlz->future_version);
UNUSED(version);
UNUSED(now);
@@ -945,47 +1013,139 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
static isc_result_t
+modrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
+ dns_rdataset_t *rdataset, unsigned int options,
+ dns_sdlzmodrdataset_t mod_function)
+{
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
+ dns_master_style_t *style = NULL;
+ isc_result_t result;
+ isc_buffer_t *buffer = NULL;
+ isc_mem_t *mctx;
+ dns_sdlznode_t *sdlznode;
+ char *rdatastr = NULL;
+ char name[DNS_NAME_MAXTEXT + 1];
+
+ REQUIRE(VALID_SDLZDB(sdlz));
+
+ if (mod_function == NULL)
+ return (ISC_R_NOTIMPLEMENTED);
+
+ sdlznode = (dns_sdlznode_t *)node;
+
+ UNUSED(options);
+
+ dns_name_format(sdlznode->name, name, sizeof(name));
+
+ mctx = sdlz->common.mctx;
+
+ result = isc_buffer_allocate(mctx, &buffer, 1024);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = dns_master_stylecreate(&style, 0, 0, 0, 0, 0, 0, 1, mctx);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_master_rdatasettotext(sdlznode->name, rdataset,
+ style, buffer);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ if (isc_buffer_usedlength(buffer) < 1) {
+ result = ISC_R_BADADDRESSFORM;
+ goto cleanup;
+ }
+
+ rdatastr = isc_buffer_base(buffer);
+ if (rdatastr == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ rdatastr[isc_buffer_usedlength(buffer) - 1] = 0;
+
+ MAYBE_LOCK(sdlz->dlzimp);
+ result = mod_function(name, rdatastr, sdlz->dlzimp->driverarg,
+ sdlz->dbdata, version);
+ MAYBE_UNLOCK(sdlz->dlzimp);
+
+cleanup:
+ isc_buffer_free(&buffer);
+ if (style != NULL)
+ dns_master_styledestroy(&style, mctx);
+
+ return (result);
+}
+
+static isc_result_t
addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
dns_rdataset_t *addedrdataset)
{
- UNUSED(db);
- UNUSED(node);
- UNUSED(version);
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
+ isc_result_t result;
+
UNUSED(now);
- UNUSED(rdataset);
- UNUSED(options);
UNUSED(addedrdataset);
+ REQUIRE(VALID_SDLZDB(sdlz));
- return (ISC_R_NOTIMPLEMENTED);
+ if (sdlz->dlzimp->methods->addrdataset == NULL)
+ return (ISC_R_NOTIMPLEMENTED);
+
+ result = modrdataset(db, node, version, rdataset, options,
+ sdlz->dlzimp->methods->addrdataset);
+ return (result);
}
+
static isc_result_t
subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdataset_t *rdataset, unsigned int options,
dns_rdataset_t *newrdataset)
{
- UNUSED(db);
- UNUSED(node);
- UNUSED(version);
- UNUSED(rdataset);
- UNUSED(options);
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
+ isc_result_t result;
+
UNUSED(newrdataset);
+ REQUIRE(VALID_SDLZDB(sdlz));
- return (ISC_R_NOTIMPLEMENTED);
+ if (sdlz->dlzimp->methods->subtractrdataset == NULL) {
+ return (ISC_R_NOTIMPLEMENTED);
+ }
+
+ result = modrdataset(db, node, version, rdataset, options,
+ sdlz->dlzimp->methods->subtractrdataset);
+ return (result);
}
static isc_result_t
deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, dns_rdatatype_t covers)
{
- UNUSED(db);
- UNUSED(node);
- UNUSED(version);
- UNUSED(type);
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
+ char name[DNS_NAME_MAXTEXT + 1];
+ char b_type[DNS_RDATATYPE_FORMATSIZE];
+ dns_sdlznode_t *sdlznode;
+ isc_result_t result;
+
UNUSED(covers);
- return (ISC_R_NOTIMPLEMENTED);
+ REQUIRE(VALID_SDLZDB(sdlz));
+
+ if (sdlz->dlzimp->methods->delrdataset == NULL)
+ return (ISC_R_NOTIMPLEMENTED);
+
+ sdlznode = (dns_sdlznode_t *)node;
+ dns_name_format(sdlznode->name, name, sizeof(name));
+ dns_rdatatype_format(type, b_type, sizeof(b_type));
+
+ MAYBE_LOCK(sdlz->dlzimp);
+ result = sdlz->dlzimp->methods->delrdataset(name, b_type,
+ sdlz->dlzimp->driverarg,
+ sdlz->dbdata, version);
+ MAYBE_UNLOCK(sdlz->dlzimp);
+
+ return (result);
}
static isc_boolean_t
@@ -1021,6 +1181,26 @@ settask(dns_db_t *db, isc_task_t *task) {
}
+/*
+ * getoriginnode() is used by the update code to find the
+ * dns_rdatatype_dnskey record for a zone
+ */
+static isc_result_t
+getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
+ isc_result_t result;
+
+ REQUIRE(VALID_SDLZDB(sdlz));
+ if (sdlz->dlzimp->methods->newversion == NULL)
+ return (ISC_R_NOTIMPLEMENTED);
+
+ result = findnode(db, &sdlz->common.origin, ISC_FALSE, nodep);
+ if (result != ISC_R_SUCCESS)
+ sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed : %s",
+ isc_result_totext(result));
+ return (result);
+}
+
static dns_dbmethods_t sdlzdb_methods = {
attach,
detach,
@@ -1049,6 +1229,8 @@ static dns_dbmethods_t sdlzdb_methods = {
ispersistent,
overmem,
settask,
+ getoriginnode,
+ NULL,
NULL,
NULL,
NULL,
@@ -1371,9 +1553,7 @@ dns_sdlzcreate(isc_mem_t *mctx, const char *dlzname, unsigned int argc,
isc_result_t result = ISC_R_NOTFOUND;
/* Write debugging message to log */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
- "Loading SDLZ driver.");
+ sdlz_log(ISC_LOG_DEBUG(2), "Loading SDLZ driver.");
/*
* Performs checks to make sure data is as we expect it to be.
@@ -1395,13 +1575,9 @@ dns_sdlzcreate(isc_mem_t *mctx, const char *dlzname, unsigned int argc,
/* Write debugging message to log */
if (result == ISC_R_SUCCESS) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
- "SDLZ driver loaded successfully.");
+ sdlz_log(ISC_LOG_DEBUG(2), "SDLZ driver loaded successfully.");
} else {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
- "SDLZ driver failed to load.");
+ sdlz_log(ISC_LOG_ERROR, "SDLZ driver failed to load.");
}
return (result);
@@ -1414,9 +1590,7 @@ dns_sdlzdestroy(void *driverdata, void **dbdata)
dns_sdlzimplementation_t *imp;
/* Write debugging message to log */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
- "Unloading SDLZ driver.");
+ sdlz_log(ISC_LOG_DEBUG(2), "Unloading SDLZ driver.");
imp = driverdata;
@@ -1472,11 +1646,97 @@ dns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx,
return (result);
}
+
+static isc_result_t
+dns_sdlzconfigure(void *driverarg, void *dbdata, dns_view_t *view)
+{
+ isc_result_t result;
+ dns_sdlzimplementation_t *imp;
+
+ REQUIRE(driverarg != NULL);
+
+ imp = (dns_sdlzimplementation_t *) driverarg;
+
+ /* Call SDLZ driver's configure method */
+ if (imp->methods->configure != NULL) {
+ MAYBE_LOCK(imp);
+ result = imp->methods->configure(view, imp->driverarg, dbdata);
+ MAYBE_UNLOCK(imp);
+ } else {
+ result = ISC_R_SUCCESS;
+ }
+
+ return (result);
+}
+
+static isc_boolean_t
+dns_sdlzssumatch(dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr,
+ dns_rdatatype_t type, const dst_key_t *key, void *driverarg,
+ void *dbdata)
+{
+ dns_sdlzimplementation_t *imp;
+ char b_signer[DNS_NAME_FORMATSIZE];
+ char b_name[DNS_NAME_FORMATSIZE];
+ char b_addr[ISC_NETADDR_FORMATSIZE];
+ char b_type[DNS_RDATATYPE_FORMATSIZE];
+ char b_key[DST_KEY_FORMATSIZE];
+ isc_buffer_t *tkey_token;
+ isc_region_t token_region;
+ isc_uint32_t token_len = 0;
+ isc_boolean_t ret;
+
+ REQUIRE(driverarg != NULL);
+
+ imp = (dns_sdlzimplementation_t *) driverarg;
+ if (imp->methods->ssumatch == NULL)
+ return (ISC_FALSE);
+
+ /*
+ * Format the request elements. sdlz operates on strings, not
+ * structures
+ */
+ if (signer)
+ dns_name_format(signer, b_signer, sizeof(b_signer));
+ else
+ b_signer[0] = 0;
+
+ dns_name_format(name, b_name, sizeof(b_name));
+
+ if (tcpaddr)
+ isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr));
+ else
+ b_addr[0] = 0;
+
+ dns_rdatatype_format(type, b_type, sizeof(b_type));
+
+ if (key)
+ dst_key_format(key, b_key, sizeof(b_key));
+ else
+ b_key[0] = 0;
+
+ tkey_token = dst_key_tkeytoken(key);
+
+ if (tkey_token) {
+ isc_buffer_region(tkey_token, &token_region);
+ token_len = token_region.length;
+ }
+
+ MAYBE_LOCK(imp);
+ ret = imp->methods->ssumatch(b_signer, b_name, b_addr, b_type, b_key,
+ token_len,
+ token_len ? token_region.base : NULL,
+ imp->driverarg, dbdata);
+ MAYBE_UNLOCK(imp);
+ return (ret);
+}
+
static dns_dlzmethods_t sdlzmethods = {
dns_sdlzcreate,
dns_sdlzdestroy,
dns_sdlzfindzone,
- dns_sdlzallowzonexfr
+ dns_sdlzallowzonexfr,
+ dns_sdlzconfigure,
+ dns_sdlzssumatch
};
/*
@@ -1530,8 +1790,16 @@ dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl,
ISC_LINK_INIT(rdatalist, link);
ISC_LIST_APPEND(lookup->lists, rdatalist, link);
} else
- if (rdatalist->ttl != ttl)
- return (DNS_R_BADTTL);
+ if (rdatalist->ttl > ttl) {
+ /*
+ * BIND9 doesn't enforce all RRs in an RRset
+ * having the same TTL, as per RFC 2136,
+ * section 7.12. If a DLZ backend has
+ * different TTLs, then the best
+ * we can do is return the lowest.
+ */
+ rdatalist->ttl = ttl;
+ }
rdata = isc_mem_get(mctx, sizeof(dns_rdata_t));
if (rdata == NULL)
@@ -1615,7 +1883,7 @@ dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name,
isc_buffer_init(&b, name, strlen(name));
isc_buffer_add(&b, strlen(name));
- result = dns_name_fromtext(newname, &b, origin, ISC_FALSE, NULL);
+ result = dns_name_fromtext(newname, &b, origin, 0, NULL);
if (result != ISC_R_SUCCESS)
return (result);
@@ -1694,9 +1962,7 @@ dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods,
DNS_SDLZFLAG_THREADSAFE)) == 0);
/* Write debugging message to log */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
- "Registering SDLZ driver '%s'", drivername);
+ sdlz_log(ISC_LOG_DEBUG(2), "Registering SDLZ driver '%s'", drivername);
/*
* Allocate memory for a sdlz_implementation object. Error if
@@ -1769,9 +2035,7 @@ dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp) {
isc_mem_t *mctx;
/* Write debugging message to log */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
- "Unregistering SDLZ driver.");
+ sdlz_log(ISC_LOG_DEBUG(2), "Unregistering SDLZ driver.");
/*
* Performs checks to make sure data is as we expect it to be.
@@ -1797,3 +2061,16 @@ dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp) {
*sdlzimp = NULL;
}
+
+
+isc_result_t
+dns_sdlz_setdb(dns_dlzdb_t *dlzdatabase, dns_rdataclass_t rdclass,
+ dns_name_t *name, dns_db_t **dbp)
+{
+ isc_result_t result;
+
+ result = dns_sdlzcreateDBP(dlzdatabase->mctx,
+ dlzdatabase->implementation->driverarg,
+ dlzdatabase->dbdata, name, rdclass, dbp);
+ return (result);
+}
diff --git a/lib/dns/soa.c b/lib/dns/soa.c
index f3385860b237..bd0d185d084a 100644
--- a/lib/dns/soa.c
+++ b/lib/dns/soa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,15 +15,18 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: soa.c,v 1.8 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: soa.c,v 1.12 2009-09-10 02:18:40 each Exp $ */
/*! \file */
#include <config.h>
+#include <string.h>
+#include <isc/buffer.h>
#include <isc/util.h>
#include <dns/rdata.h>
+#include <dns/rdatastruct.h>
#include <dns/soa.h>
static inline isc_uint32_t
@@ -60,6 +63,39 @@ soa_get(dns_rdata_t *rdata, int offset) {
return (decode_uint32(rdata->data + rdata->length - 20 + offset));
}
+isc_result_t
+dns_soa_buildrdata(dns_name_t *origin, dns_name_t *contact,
+ dns_rdataclass_t rdclass,
+ isc_uint32_t serial, isc_uint32_t refresh,
+ isc_uint32_t retry, isc_uint32_t expire,
+ isc_uint32_t minimum, unsigned char *buffer,
+ dns_rdata_t *rdata) {
+ dns_rdata_soa_t soa;
+ isc_buffer_t rdatabuf;
+
+ REQUIRE(origin != NULL);
+ REQUIRE(contact != NULL);
+
+ memset(buffer, 0, DNS_SOA_BUFFERSIZE);
+ isc_buffer_init(&rdatabuf, buffer, DNS_SOA_BUFFERSIZE);
+
+ soa.common.rdtype = dns_rdatatype_soa;
+ soa.common.rdclass = rdclass;
+ soa.mctx = NULL;
+ soa.serial = serial;
+ soa.refresh = refresh;
+ soa.retry = retry;
+ soa.expire = expire;
+ soa.minimum = minimum;
+ dns_name_init(&soa.origin, NULL);
+ dns_name_clone(origin, &soa.origin);
+ dns_name_init(&soa.contact, NULL);
+ dns_name_clone(contact, &soa.contact);
+
+ return (dns_rdata_fromstruct(rdata, rdclass, dns_rdatatype_soa,
+ &soa, &rdatabuf));
+}
+
isc_uint32_t
dns_soa_getserial(dns_rdata_t *rdata) {
return soa_get(rdata, 0);
diff --git a/lib/dns/spnego.c b/lib/dns/spnego.c
index ad15331edf3b..5ad492ce4c25 100644
--- a/lib/dns/spnego.c
+++ b/lib/dns/spnego.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006-2011 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: spnego.c,v 1.8.118.4 2009-07-21 07:27:13 marka Exp $ */
+/* $Id: spnego.c,v 1.16 2011-01-11 23:47:13 tbox Exp $ */
/*! \file
* \brief
@@ -172,6 +172,8 @@
/* asn1_err.h */
/* Generated from ../../../lib/asn1/asn1_err.et */
+#ifndef ERROR_TABLE_BASE_asn1
+/* these may be brought in already via gssapi_krb5.h */
typedef enum asn1_error_number {
ASN1_BAD_TIMEFORMAT = 1859794432,
ASN1_MISSING_FIELD = 1859794433,
@@ -186,6 +188,7 @@ typedef enum asn1_error_number {
} asn1_error_number;
#define ERROR_TABLE_BASE_asn1 1859794432
+#endif
#define __asn1_common_definitions__
@@ -409,7 +412,7 @@ code_NegTokenArg(OM_uint32 * minor_status,
{
OM_uint32 ret;
u_char *buf;
- size_t buf_size, buf_len;
+ size_t buf_size, buf_len = 0;
buf_size = 1024;
buf = malloc(buf_size);
diff --git a/lib/dns/ssu.c b/lib/dns/ssu.c
index 128071cd00a3..eb135510f087 100644
--- a/lib/dns/ssu.c
+++ b/lib/dns/ssu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -17,7 +17,7 @@
/*! \file */
/*
- * $Id: ssu.c,v 1.34 2008-01-18 23:46:58 tbox Exp $
+ * $Id: ssu.c,v 1.38 2011-01-06 23:47:00 tbox Exp $
* Principal Author: Brian Wellington
*/
@@ -30,11 +30,13 @@
#include <isc/string.h>
#include <isc/util.h>
+#include <dns/dlz.h>
#include <dns/fixedname.h>
#include <dns/name.h>
#include <dns/ssu.h>
#include <dst/gssapi.h>
+#include <dst/dst.h>
#define SSUTABLEMAGIC ISC_MAGIC('S', 'S', 'U', 'T')
#define VALID_SSUTABLE(table) ISC_MAGIC_VALID(table, SSUTABLEMAGIC)
@@ -59,6 +61,7 @@ struct dns_ssutable {
isc_mem_t *mctx;
unsigned int references;
isc_mutex_t lock;
+ dns_dlzdb_t *dlzdatabase;
ISC_LIST(dns_ssurule_t) rules;
};
@@ -345,7 +348,8 @@ stf_from_address(dns_name_t *stfself, isc_netaddr_t *tcpaddr) {
isc_boolean_t
dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
dns_name_t *name, isc_netaddr_t *tcpaddr,
- dns_rdatatype_t type)
+ dns_rdatatype_t type,
+ const dst_key_t *key)
{
dns_ssurule_t *rule;
unsigned int i;
@@ -483,10 +487,27 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
if (!dns_name_equal(stfself, name))
continue;
break;
+ case DNS_SSUMATCHTYPE_EXTERNAL:
+ if (!dns_ssu_external_match(rule->identity, signer,
+ name, tcpaddr, type, key,
+ table->mctx))
+ continue;
+ break;
+ case DNS_SSUMATCHTYPE_DLZ:
+ if (!dns_dlz_ssumatch(table->dlzdatabase, signer,
+ name, tcpaddr, type, key))
+ continue;
+ break;
}
if (rule->ntypes == 0) {
- if (!isusertype(type))
+ /*
+ * If this is a DLZ rule, then the DLZ ssu
+ * checks will have already checked
+ * the type.
+ */
+ if (rule->matchtype != DNS_SSUMATCHTYPE_DLZ &&
+ !isusertype(type))
continue;
} else {
for (i = 0; i < rule->ntypes; i++) {
@@ -550,3 +571,42 @@ dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule) {
*nextrule = ISC_LIST_NEXT(rule, link);
return (*nextrule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE);
}
+
+/*
+ * Create a specialised SSU table that points at an external DLZ database
+ */
+isc_result_t
+dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep,
+ dns_dlzdb_t *dlzdatabase)
+{
+ isc_result_t result;
+ dns_ssurule_t *rule;
+ dns_ssutable_t *table = NULL;
+
+ REQUIRE(tablep != NULL && *tablep == NULL);
+
+ result = dns_ssutable_create(mctx, &table);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ table->dlzdatabase = dlzdatabase;
+
+ rule = isc_mem_get(table->mctx, sizeof(dns_ssurule_t));
+ if (rule == NULL) {
+ dns_ssutable_detach(&table);
+ return (ISC_R_NOMEMORY);
+ }
+
+ rule->identity = NULL;
+ rule->name = NULL;
+ rule->types = NULL;
+ rule->grant = ISC_TRUE;
+ rule->matchtype = DNS_SSUMATCHTYPE_DLZ;
+ rule->ntypes = 0;
+ rule->types = NULL;
+ rule->magic = SSURULEMAGIC;
+
+ ISC_LIST_INITANDAPPEND(table->rules, rule, link);
+ *tablep = table;
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/dns/ssu_external.c b/lib/dns/ssu_external.c
new file mode 100644
index 000000000000..ac72a1f85daa
--- /dev/null
+++ b/lib/dns/ssu_external.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ssu_external.c,v 1.7 2011-01-13 07:05:57 marka Exp $ */
+
+/*
+ * This implements external update-policy rules. This allows permission
+ * to update a zone to be checked by consulting an external daemon (e.g.,
+ * kerberos).
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifdef ISC_PLATFORM_HAVESYSUNH
+#include <sys/socket.h>
+#include <sys/un.h>
+#endif
+
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/netaddr.h>
+#include <isc/result.h>
+#include <isc/string.h>
+#include <isc/util.h>
+#include <isc/strerror.h>
+
+#include <dns/fixedname.h>
+#include <dns/name.h>
+#include <dns/ssu.h>
+#include <dns/log.h>
+#include <dns/rdatatype.h>
+
+#include <dst/dst.h>
+
+
+static void
+ssu_e_log(int level, const char *fmt, ...) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_SECURITY,
+ DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(level), fmt, ap);
+ va_end(ap);
+}
+
+
+/*
+ * Connect to a UNIX domain socket.
+ */
+static int
+ux_socket_connect(const char *path) {
+ int fd = -1;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ struct sockaddr_un addr;
+
+ REQUIRE(path != NULL);
+
+ if (strlen(path) > sizeof(addr.sun_path)) {
+ ssu_e_log(3, "ssu_external: socket path '%s' "
+ "longer than system maximum %u",
+ path, sizeof(addr.sun_path));
+ return (-1);
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, path, sizeof(addr.sun_path));
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1) {
+ char strbuf[ISC_STRERRORSIZE];
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ssu_e_log(3, "ssu_external: unable to create socket - %s",
+ strbuf);
+ return (-1);
+ }
+
+ if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+ char strbuf[ISC_STRERRORSIZE];
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ssu_e_log(3, "ssu_external: unable to connect to "
+ "socket '%s' - %s",
+ path, strbuf);
+ close(fd);
+ return (-1);
+ }
+#endif
+ return (fd);
+}
+
+/* Change this version if you update the format of the request */
+#define SSU_EXTERNAL_VERSION 1
+
+/*
+ * Perform an update-policy rule check against an external application
+ * over a socket.
+ *
+ * This currently only supports local: for unix domain datagram sockets.
+ *
+ * Note that by using a datagram socket and creating a new socket each
+ * time we avoid the need for locking and allow for parallel access to
+ * the authorization server.
+ */
+isc_boolean_t
+dns_ssu_external_match(dns_name_t *identity,
+ dns_name_t *signer, dns_name_t *name,
+ isc_netaddr_t *tcpaddr, dns_rdatatype_t type,
+ const dst_key_t *key, isc_mem_t *mctx)
+{
+ char b_identity[DNS_NAME_FORMATSIZE];
+ char b_signer[DNS_NAME_FORMATSIZE];
+ char b_name[DNS_NAME_FORMATSIZE];
+ char b_addr[ISC_NETADDR_FORMATSIZE];
+ char b_type[DNS_RDATATYPE_FORMATSIZE];
+ char b_key[DST_KEY_FORMATSIZE];
+ isc_buffer_t *tkey_token;
+ int fd;
+ const char *sock_path;
+ size_t req_len;
+ isc_region_t token_region;
+ unsigned char *data;
+ isc_buffer_t buf;
+ isc_uint32_t token_len = 0;
+ isc_uint32_t reply;
+ ssize_t ret;
+
+ /* The identity contains local:/path/to/socket */
+ dns_name_format(identity, b_identity, sizeof(b_identity));
+
+ /* For now only local: is supported */
+ if (strncmp(b_identity, "local:", 6) != 0) {
+ ssu_e_log(3, "ssu_external: invalid socket path '%s'",
+ b_identity);
+ return (ISC_FALSE);
+ }
+ sock_path = &b_identity[6];
+
+ fd = ux_socket_connect(sock_path);
+ if (fd == -1)
+ return (ISC_FALSE);
+
+ tkey_token = dst_key_tkeytoken(key);
+
+ /* Format the request elements */
+ if (signer)
+ dns_name_format(signer, b_signer, sizeof(b_signer));
+ else
+ b_signer[0] = 0;
+
+ dns_name_format(name, b_name, sizeof(b_name));
+
+ if (tcpaddr)
+ isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr));
+ else
+ b_addr[0] = 0;
+
+ dns_rdatatype_format(type, b_type, sizeof(b_type));
+
+ if (key)
+ dst_key_format(key, b_key, sizeof(b_key));
+ else
+ b_key[0] = 0;
+
+ if (tkey_token) {
+ isc_buffer_region(tkey_token, &token_region);
+ token_len = token_region.length;
+ }
+
+ /* Work out how big the request will be */
+ req_len = sizeof(isc_uint32_t) + /* Format version */
+ sizeof(isc_uint32_t) + /* Length */
+ strlen(b_signer) + 1 + /* Signer */
+ strlen(b_name) + 1 + /* Name */
+ strlen(b_addr) + 1 + /* Address */
+ strlen(b_type) + 1 + /* Type */
+ strlen(b_key) + 1 + /* Key */
+ sizeof(isc_uint32_t) + /* tkey_token length */
+ token_len; /* tkey_token */
+
+
+ /* format the buffer */
+ data = isc_mem_allocate(mctx, req_len);
+ if (data == NULL) {
+ close(fd);
+ return (ISC_FALSE);
+ }
+
+ isc_buffer_init(&buf, data, req_len);
+ isc_buffer_putuint32(&buf, SSU_EXTERNAL_VERSION);
+ isc_buffer_putuint32(&buf, req_len);
+
+ /* Strings must be null-terminated */
+ isc_buffer_putstr(&buf, b_signer);
+ isc_buffer_putuint8(&buf, 0);
+ isc_buffer_putstr(&buf, b_name);
+ isc_buffer_putuint8(&buf, 0);
+ isc_buffer_putstr(&buf, b_addr);
+ isc_buffer_putuint8(&buf, 0);
+ isc_buffer_putstr(&buf, b_type);
+ isc_buffer_putuint8(&buf, 0);
+ isc_buffer_putstr(&buf, b_key);
+ isc_buffer_putuint8(&buf, 0);
+
+ isc_buffer_putuint32(&buf, token_len);
+ if (tkey_token && token_len != 0)
+ isc_buffer_putmem(&buf, token_region.base, token_len);
+
+ ENSURE(isc_buffer_availablelength(&buf) == 0);
+
+ /* Send the request */
+ ret = write(fd, data, req_len);
+ isc_mem_free(mctx, data);
+ if (ret != (ssize_t) req_len) {
+ char strbuf[ISC_STRERRORSIZE];
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ssu_e_log(3, "ssu_external: unable to send request - %s",
+ strbuf);
+ close(fd);
+ return (ISC_FALSE);
+ }
+
+ /* Receive the reply */
+ ret = read(fd, &reply, sizeof(isc_uint32_t));
+ if (ret != (ssize_t) sizeof(isc_uint32_t)) {
+ char strbuf[ISC_STRERRORSIZE];
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ ssu_e_log(3, "ssu_external: unable to receive reply - %s",
+ strbuf);
+ close(fd);
+ return (ISC_FALSE);
+ }
+
+ close(fd);
+
+ reply = ntohl(reply);
+
+ if (reply == 0) {
+ ssu_e_log(3, "ssu_external: denied external auth for '%s'",
+ b_name);
+ return (ISC_FALSE);
+ } else if (reply == 1) {
+ ssu_e_log(3, "ssu_external: allowed external auth for '%s'",
+ b_name);
+ return (ISC_TRUE);
+ }
+
+ ssu_e_log(3, "ssu_external: invalid reply 0x%08x", reply);
+
+ return (ISC_FALSE);
+}
diff --git a/lib/dns/stats.c b/lib/dns/stats.c
index b73a3b3b3398..cb46bf54aeb8 100644
--- a/lib/dns/stats.c
+++ b/lib/dns/stats.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: stats.c,v 1.16.118.2 2009-01-29 23:47:44 tbox Exp $ */
+/* $Id: stats.c,v 1.18 2009-01-27 23:47:54 tbox Exp $ */
/*! \file */
diff --git a/lib/dns/time.c b/lib/dns/time.c
index bd8cdc31d74c..3f55f1937499 100644
--- a/lib/dns/time.c
+++ b/lib/dns/time.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: time.c,v 1.31.332.4 2010-04-21 23:48:05 tbox Exp $ */
+/* $Id: time.c,v 1.35 2010-04-21 23:51:22 tbox Exp $ */
/*! \file */
diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c
index 7107dd50911d..a861ee3b7aae 100644
--- a/lib/dns/tkey.c
+++ b/lib/dns/tkey.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,7 +16,7 @@
*/
/*
- * $Id: tkey.c,v 1.90.118.4 2010-12-09 01:12:55 marka Exp $
+ * $Id: tkey.c,v 1.100 2011-01-08 23:47:01 tbox Exp $
*/
/*! \file */
#include <config.h>
@@ -99,6 +99,7 @@ dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp)
tctx->dhkey = NULL;
tctx->domain = NULL;
tctx->gsscred = NULL;
+ tctx->gssapi_keytab = NULL;
*tctxp = tctx;
return (ISC_R_SUCCESS);
@@ -121,6 +122,9 @@ dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp) {
dns_name_free(tctx->domain, mctx);
isc_mem_put(mctx, tctx->domain, sizeof(dns_name_t));
}
+ if (tctx->gssapi_keytab != NULL) {
+ isc_mem_free(mctx, tctx->gssapi_keytab);
+ }
if (tctx->gsscred != NULL)
dst_gssapi_releasecred(&tctx->gsscred);
isc_entropy_detach(&tctx->ectx);
@@ -430,8 +434,17 @@ process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin,
isc_buffer_t *outtoken = NULL;
gss_ctx_id_t gss_ctx = NULL;
- if (tctx->gsscred == NULL)
+ /*
+ * You have to define either a gss credential (principal) to
+ * accept with tkey-gssapi-credential, or you have to
+ * configure a specific keytab (with tkey-gssapi-keytab) in
+ * order to use gsstkey
+ */
+ if (tctx->gsscred == NULL && tctx->gssapi_keytab == NULL) {
+ tkey_log("process_gsstkey(): no tkey-gssapi-credential "
+ "or tkey-gssapi-keytab configured");
return (ISC_R_NOPERM);
+ }
if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPI_NAME) &&
!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
@@ -454,7 +467,11 @@ process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin,
dns_fixedname_init(&principal);
- result = dst_gssapi_acceptctx(tctx->gsscred, &intoken,
+ /*
+ * Note that tctx->gsscred may be NULL if tctx->gssapi_keytab is set
+ */
+ result = dst_gssapi_acceptctx(tctx->gsscred, tctx->gssapi_keytab,
+ &intoken,
&outtoken, &gss_ctx,
dns_fixedname_name(&principal),
tctx->mctx);
@@ -479,7 +496,8 @@ process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin,
#endif
isc_uint32_t expire;
- RETERR(dst_key_fromgssapi(name, gss_ctx, ring->mctx, &dstkey));
+ RETERR(dst_key_fromgssapi(name, gss_ctx, ring->mctx,
+ &dstkey, &intoken));
/*
* Limit keys to 1 hour or the context's lifetime whichever
* is smaller.
@@ -734,8 +752,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
}
isc_buffer_init(&b, randomtext, sizeof(randomtext));
isc_buffer_add(&b, sizeof(randomtext));
- result = dns_name_fromtext(keyname, &b, NULL,
- ISC_FALSE, NULL);
+ result = dns_name_fromtext(keyname, &b, NULL, 0, NULL);
if (result != ISC_R_SUCCESS)
goto failure;
}
@@ -985,7 +1002,8 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
isc_result_t
dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname,
isc_buffer_t *intoken, isc_uint32_t lifetime,
- gss_ctx_id_t *context, isc_boolean_t win2k)
+ gss_ctx_id_t *context, isc_boolean_t win2k,
+ isc_mem_t *mctx, char **err_message)
{
dns_rdata_tkey_t tkey;
isc_result_t result;
@@ -999,9 +1017,11 @@ dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname,
REQUIRE(name != NULL);
REQUIRE(gname != NULL);
REQUIRE(context != NULL);
+ REQUIRE(mctx != NULL);
isc_buffer_init(&token, array, sizeof(array));
- result = dst_gssapi_initctx(gname, NULL, &token, context);
+ result = dst_gssapi_initctx(gname, NULL, &token, context,
+ mctx, err_message);
if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS)
return (result);
@@ -1218,7 +1238,7 @@ isc_result_t
dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
dns_name_t *gname, gss_ctx_id_t *context,
isc_buffer_t *outtoken, dns_tsigkey_t **outkey,
- dns_tsig_keyring_t *ring)
+ dns_tsig_keyring_t *ring, char **err_message)
{
dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT;
dns_name_t *tkeyname;
@@ -1232,6 +1252,7 @@ dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
REQUIRE(qmsg != NULL);
REQUIRE(rmsg != NULL);
REQUIRE(gname != NULL);
+ REQUIRE(ring != NULL);
if (outkey != NULL)
REQUIRE(*outkey == NULL);
@@ -1268,10 +1289,11 @@ dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
isc_buffer_init(outtoken, array, sizeof(array));
isc_buffer_init(&intoken, rtkey.key, rtkey.keylen);
- RETERR(dst_gssapi_initctx(gname, &intoken, outtoken, context));
+ RETERR(dst_gssapi_initctx(gname, &intoken, outtoken, context,
+ ring->mctx, err_message));
RETERR(dst_key_fromgssapi(dns_rootname, *context, rmsg->mctx,
- &dstkey));
+ &dstkey, NULL));
RETERR(dns_tsigkey_createfromkey(tkeyname, DNS_TSIG_GSSAPI_NAME,
dstkey, ISC_FALSE, NULL,
@@ -1349,7 +1371,7 @@ isc_result_t
dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
dns_name_t *server, gss_ctx_id_t *context,
dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
- isc_boolean_t win2k)
+ isc_boolean_t win2k, char **err_message)
{
dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT;
dns_name_t *tkeyname;
@@ -1393,12 +1415,13 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
isc_buffer_init(&intoken, rtkey.key, rtkey.keylen);
isc_buffer_init(&outtoken, array, sizeof(array));
- result = dst_gssapi_initctx(server, &intoken, &outtoken, context);
+ result = dst_gssapi_initctx(server, &intoken, &outtoken, context,
+ ring->mctx, err_message);
if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS)
return (result);
RETERR(dst_key_fromgssapi(dns_rootname, *context, rmsg->mctx,
- &dstkey));
+ &dstkey, NULL));
/*
* XXXSRA This seems confused. If we got CONTINUE from initctx,
diff --git a/lib/dns/tsec.c b/lib/dns/tsec.c
new file mode 100644
index 000000000000..b7ed7779adb7
--- /dev/null
+++ b/lib/dns/tsec.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: tsec.c,v 1.7 2010-12-09 00:54:34 marka Exp $ */
+
+#include <config.h>
+
+#include <isc/mem.h>
+
+#include <dns/tsec.h>
+#include <dns/tsig.h>
+#include <dns/result.h>
+
+#include <dst/dst.h>
+
+#define DNS_TSEC_MAGIC ISC_MAGIC('T', 's', 'e', 'c')
+#define DNS_TSEC_VALID(t) ISC_MAGIC_VALID(t, DNS_TSEC_MAGIC)
+
+/*%
+ * DNS Transaction Security object. We assume this is not shared by
+ * multiple threads, and so the structure does not contain a lock.
+ */
+struct dns_tsec {
+ unsigned int magic;
+ dns_tsectype_t type;
+ isc_mem_t *mctx;
+ union {
+ dns_tsigkey_t *tsigkey;
+ dst_key_t *key;
+ } ukey;
+};
+
+isc_result_t
+dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key,
+ dns_tsec_t **tsecp)
+{
+ isc_result_t result;
+ dns_tsec_t *tsec;
+ dns_tsigkey_t *tsigkey = NULL;
+ dns_name_t *algname;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(tsecp != NULL && *tsecp == NULL);
+
+ tsec = isc_mem_get(mctx, sizeof(*tsec));
+ if (tsec == NULL)
+ return (ISC_R_NOMEMORY);
+
+ tsec->type = type;
+ tsec->mctx = mctx;
+
+ switch (type) {
+ case dns_tsectype_tsig:
+ switch (dst_key_alg(key)) {
+ case DST_ALG_HMACMD5:
+ algname = dns_tsig_hmacmd5_name;
+ break;
+ case DST_ALG_HMACSHA1:
+ algname = dns_tsig_hmacsha1_name;
+ break;
+ case DST_ALG_HMACSHA224:
+ algname = dns_tsig_hmacsha224_name;
+ break;
+ case DST_ALG_HMACSHA256:
+ algname = dns_tsig_hmacsha256_name;
+ break;
+ case DST_ALG_HMACSHA384:
+ algname = dns_tsig_hmacsha384_name;
+ break;
+ case DST_ALG_HMACSHA512:
+ algname = dns_tsig_hmacsha512_name;
+ break;
+ default:
+ isc_mem_put(mctx, tsec, sizeof(*tsec));
+ return (DNS_R_BADALG);
+ }
+ result = dns_tsigkey_createfromkey(dst_key_name(key),
+ algname, key, ISC_FALSE,
+ NULL, 0, 0, mctx, NULL,
+ &tsigkey);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, tsec, sizeof(*tsec));
+ return (result);
+ }
+ tsec->ukey.tsigkey = tsigkey;
+ break;
+ case dns_tsectype_sig0:
+ tsec->ukey.key = key;
+ break;
+ default:
+ INSIST(0);
+ }
+
+ tsec->magic = DNS_TSEC_MAGIC;
+
+ *tsecp = tsec;
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_tsec_destroy(dns_tsec_t **tsecp) {
+ dns_tsec_t *tsec;
+
+ REQUIRE(tsecp != NULL && *tsecp != NULL);
+ tsec = *tsecp;
+ REQUIRE(DNS_TSEC_VALID(tsec));
+
+ switch (tsec->type) {
+ case dns_tsectype_tsig:
+ dns_tsigkey_detach(&tsec->ukey.tsigkey);
+ break;
+ case dns_tsectype_sig0:
+ dst_key_free(&tsec->ukey.key);
+ break;
+ default:
+ INSIST(0);
+ }
+
+ tsec->magic = 0;
+ isc_mem_put(tsec->mctx, tsec, sizeof(*tsec));
+
+ *tsecp = NULL;
+}
+
+dns_tsectype_t
+dns_tsec_gettype(dns_tsec_t *tsec) {
+ REQUIRE(DNS_TSEC_VALID(tsec));
+
+ return (tsec->type);
+}
+
+void
+dns_tsec_getkey(dns_tsec_t *tsec, void *keyp) {
+ REQUIRE(DNS_TSEC_VALID(tsec));
+ REQUIRE(keyp != NULL);
+
+ switch (tsec->type) {
+ case dns_tsectype_tsig:
+ dns_tsigkey_attach(tsec->ukey.tsigkey, (dns_tsigkey_t **)keyp);
+ break;
+ case dns_tsectype_sig0:
+ *(dst_key_t **)keyp = tsec->ukey.key;
+ break;
+ default:
+ INSIST(0);
+ }
+}
diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c
index 65d32dc8614f..cec5222f2f8b 100644
--- a/lib/dns/tsig.c
+++ b/lib/dns/tsig.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,7 +16,7 @@
*/
/*
- * $Id: tsig.c,v 1.136.18.5 2010-12-09 01:12:55 marka Exp $
+ * $Id: tsig.c,v 1.147 2011-01-11 23:47:13 tbox Exp $
*/
/*! \file */
#include <config.h>
@@ -91,31 +91,6 @@ static dns_name_t gsstsig = {
};
LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_gssapi_name = &gsstsig;
-static void
-remove_fromring(dns_tsigkey_t *tkey) {
- if (tkey->generated) {
- ISC_LIST_UNLINK(tkey->ring->lru, tkey, link);
- tkey->ring->generated--;
- }
- (void)dns_rbt_deletename(tkey->ring->keys, &tkey->name, ISC_FALSE);
-}
-
-static void
-adjust_lru(dns_tsigkey_t *tkey) {
- if (tkey->generated) {
- RWLOCK(&tkey->ring->lock, isc_rwlocktype_write);
- /*
- * We may have been removed from the LRU list between
- * removing the read lock and aquiring the write lock.
- */
- if (ISC_LINK_LINKED(tkey, link)) {
- ISC_LIST_UNLINK(tkey->ring->lru, tkey, link);
- ISC_LIST_APPEND(tkey->ring->lru, tkey, link);
- }
- RWUNLOCK(&tkey->ring->lock, isc_rwlocktype_write);
- }
-}
-
/*
* Since Microsoft doesn't follow its own standard, we will use this
* alternate name as a second guess.
@@ -228,8 +203,10 @@ tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) {
else
strcpy(namestr, "<null>");
- if (key != NULL && key->generated)
+ if (key != NULL && key->generated && key->creator)
dns_name_format(key->creator, creatorstr, sizeof(creatorstr));
+ else
+ strcpy(creatorstr, "<null>");
va_start(ap, fmt);
vsnprintf(message, sizeof(message), fmt, ap);
@@ -245,6 +222,71 @@ tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) {
level, "tsig key '%s': %s", namestr, message);
}
+static void
+remove_fromring(dns_tsigkey_t *tkey) {
+ if (tkey->generated) {
+ ISC_LIST_UNLINK(tkey->ring->lru, tkey, link);
+ tkey->ring->generated--;
+ }
+ (void)dns_rbt_deletename(tkey->ring->keys, &tkey->name, ISC_FALSE);
+}
+
+static void
+adjust_lru(dns_tsigkey_t *tkey) {
+ if (tkey->generated) {
+ RWLOCK(&tkey->ring->lock, isc_rwlocktype_write);
+ /*
+ * We may have been removed from the LRU list between
+ * removing the read lock and aquiring the write lock.
+ */
+ if (ISC_LINK_LINKED(tkey, link)) {
+ ISC_LIST_UNLINK(tkey->ring->lru, tkey, link);
+ ISC_LIST_APPEND(tkey->ring->lru, tkey, link);
+ }
+ RWUNLOCK(&tkey->ring->lock, isc_rwlocktype_write);
+ }
+}
+
+/*
+ * A supplemental routine just to add a key to ring. Note that reference
+ * counter should be counted separately because we may be adding the key
+ * as part of creation of the key, in which case the reference counter was
+ * already initialized. Also note we don't need RWLOCK for the reference
+ * counter: it's protected by a separate lock.
+ */
+static isc_result_t
+keyring_add(dns_tsig_keyring_t *ring, dns_name_t *name,
+ dns_tsigkey_t *tkey)
+{
+ isc_result_t result;
+
+ RWLOCK(&ring->lock, isc_rwlocktype_write);
+ ring->writecount++;
+
+ /*
+ * Do on the fly cleaning. Find some nodes we might not
+ * want around any more.
+ */
+ if (ring->writecount > 10) {
+ cleanup_ring(ring);
+ ring->writecount = 0;
+ }
+
+ result = dns_rbt_addname(ring->keys, name, tkey);
+ if (tkey->generated) {
+ /*
+ * Add the new key to the LRU list and remove the least
+ * recently used key if there are too many keys on the list.
+ */
+ ISC_LIST_INITANDAPPEND(ring->lru, tkey, link);
+ if (ring->generated++ > ring->maxgenerated)
+ remove_fromring(ISC_LIST_HEAD(ring->lru));
+ }
+ RWUNLOCK(&ring->lock, isc_rwlocktype_write);
+
+ return (result);
+}
+
isc_result_t
dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
dst_key_t *dstkey, isc_boolean_t generated,
@@ -363,7 +405,7 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
tkey->ring = ring;
if (key != NULL)
- refs++;
+ refs = 1;
if (ring != NULL)
refs++;
ret = isc_refcount_init(&tkey->refs, refs);
@@ -379,36 +421,9 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
tkey->magic = TSIG_MAGIC;
if (ring != NULL) {
- RWLOCK(&ring->lock, isc_rwlocktype_write);
- ring->writecount++;
-
- /*
- * Do on the fly cleaning. Find some nodes we might not
- * want around any more.
- */
- if (ring->writecount > 10) {
- cleanup_ring(ring);
- ring->writecount = 0;
- }
-
- ret = dns_rbt_addname(ring->keys, name, tkey);
- if (ret != ISC_R_SUCCESS) {
- RWUNLOCK(&ring->lock, isc_rwlocktype_write);
+ ret = keyring_add(ring, name, tkey);
+ if (ret != ISC_R_SUCCESS)
goto cleanup_refs;
- }
-
- if (tkey->generated) {
- /*
- * Add the new key to the LRU list and remove the
- * least recently used key if there are too many
- * keys on the list.
- */
- ISC_LIST_INITANDAPPEND(ring->lru, tkey, link);
- if (ring->generated++ > ring->maxgenerated)
- remove_fromring(ISC_LIST_HEAD(ring->lru));
- }
-
- RWUNLOCK(&ring->lock, isc_rwlocktype_write);
}
/*
@@ -424,6 +439,7 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
"the key '%s' is too short to be secure",
namestr);
}
+
if (key != NULL)
*key = tkey;
@@ -512,6 +528,184 @@ cleanup_ring(dns_tsig_keyring_t *ring)
}
}
+static void
+destroyring(dns_tsig_keyring_t *ring) {
+ dns_rbt_destroy(&ring->keys);
+ isc_rwlock_destroy(&ring->lock);
+ isc_mem_putanddetach(&ring->mctx, ring, sizeof(dns_tsig_keyring_t));
+}
+
+static unsigned int
+dst_alg_fromname(dns_name_t *algorithm) {
+ if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) {
+ return (DST_ALG_HMACMD5);
+ } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) {
+ return (DST_ALG_HMACSHA1);
+ } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) {
+ return (DST_ALG_HMACSHA224);
+ } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) {
+ return (DST_ALG_HMACSHA256);
+ } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) {
+ return (DST_ALG_HMACSHA384);
+ } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) {
+ return (DST_ALG_HMACSHA512);
+ } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) {
+ return (DST_ALG_GSSAPI);
+ } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
+ return (DST_ALG_GSSAPI);
+ } else
+ return (0);
+}
+
+static isc_result_t
+restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) {
+ dst_key_t *dstkey = NULL;
+ char namestr[1024];
+ char creatorstr[1024];
+ char algorithmstr[1024];
+ char keystr[4096];
+ unsigned int inception, expire;
+ int n;
+ isc_buffer_t b;
+ dns_name_t *name, *creator, *algorithm;
+ dns_fixedname_t fname, fcreator, falgorithm;
+ isc_result_t result;
+ unsigned int dstalg;
+
+ n = fscanf(fp, "%1023s %1023s %u %u %1023s %4095s\n", namestr,
+ creatorstr, &inception, &expire, algorithmstr, keystr);
+ if (n == EOF)
+ return (ISC_R_NOMORE);
+ if (n != 6)
+ return (ISC_R_FAILURE);
+
+ if (isc_serial_lt(expire, now))
+ return (DNS_R_EXPIRED);
+
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ isc_buffer_init(&b, namestr, strlen(namestr));
+ isc_buffer_add(&b, strlen(namestr));
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dns_fixedname_init(&fcreator);
+ creator = dns_fixedname_name(&fcreator);
+ isc_buffer_init(&b, creatorstr, strlen(creatorstr));
+ isc_buffer_add(&b, strlen(creatorstr));
+ result = dns_name_fromtext(creator, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dns_fixedname_init(&falgorithm);
+ algorithm = dns_fixedname_name(&falgorithm);
+ isc_buffer_init(&b, algorithmstr, strlen(algorithmstr));
+ isc_buffer_add(&b, strlen(algorithmstr));
+ result = dns_name_fromtext(algorithm, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dstalg = dst_alg_fromname(algorithm);
+ if (dstalg == 0)
+ return (DNS_R_BADALG);
+
+ result = dst_key_restore(name, dstalg, DNS_KEYOWNER_ENTITY,
+ DNS_KEYPROTO_DNSSEC, dns_rdataclass_in,
+ ring->mctx, keystr, &dstkey);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = dns_tsigkey_createfromkey(name, algorithm, dstkey,
+ ISC_TRUE, creator, inception,
+ expire, ring->mctx, ring, NULL);
+ if (result != ISC_R_SUCCESS && dstkey != NULL)
+ dst_key_free(&dstkey);
+ return (result);
+}
+
+static void
+dump_key(dns_tsigkey_t *tkey, FILE *fp)
+{
+ char *buffer = NULL;
+ int length = 0;
+ char namestr[DNS_NAME_FORMATSIZE];
+ char creatorstr[DNS_NAME_FORMATSIZE];
+ char algorithmstr[DNS_NAME_FORMATSIZE];
+ isc_result_t result;
+
+ dns_name_format(&tkey->name, namestr, sizeof(namestr));
+ dns_name_format(tkey->creator, creatorstr, sizeof(creatorstr));
+ dns_name_format(tkey->algorithm, algorithmstr, sizeof(algorithmstr));
+ result = dst_key_dump(tkey->key, tkey->mctx, &buffer, &length);
+ if (result == ISC_R_SUCCESS)
+ fprintf(fp, "%s %s %u %u %s %.*s\n", namestr, creatorstr,
+ tkey->inception, tkey->expire, algorithmstr,
+ length, buffer);
+ if (buffer != NULL)
+ isc_mem_put(tkey->mctx, buffer, length);
+}
+
+isc_result_t
+dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp) {
+ isc_result_t result;
+ dns_rbtnodechain_t chain;
+ dns_name_t foundname;
+ dns_fixedname_t fixedorigin;
+ dns_name_t *origin;
+ isc_stdtime_t now;
+ dns_rbtnode_t *node;
+ dns_tsigkey_t *tkey;
+ dns_tsig_keyring_t *ring;
+ unsigned int references;
+
+ REQUIRE(ringp != NULL && *ringp != NULL);
+
+ ring = *ringp;
+ *ringp = NULL;
+
+ RWLOCK(&ring->lock, isc_rwlocktype_write);
+ INSIST(ring->references > 0);
+ ring->references--;
+ references = ring->references;
+ RWUNLOCK(&ring->lock, isc_rwlocktype_write);
+
+ if (references != 0)
+ return (DNS_R_CONTINUE);
+
+ isc_stdtime_get(&now);
+ dns_name_init(&foundname, NULL);
+ dns_fixedname_init(&fixedorigin);
+ origin = dns_fixedname_name(&fixedorigin);
+ dns_rbtnodechain_init(&chain, ring->mctx);
+ result = dns_rbtnodechain_first(&chain, ring->keys, &foundname,
+ origin);
+ if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
+ dns_rbtnodechain_invalidate(&chain);
+ goto destroy;
+ }
+
+ for (;;) {
+ node = NULL;
+ dns_rbtnodechain_current(&chain, &foundname, origin, &node);
+ tkey = node->data;
+ if (tkey != NULL && tkey->generated && tkey->expire >= now)
+ dump_key(tkey, fp);
+ result = dns_rbtnodechain_next(&chain, &foundname,
+ origin);
+ if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) {
+ dns_rbtnodechain_invalidate(&chain);
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+ goto destroy;
+ }
+ }
+
+ destroy:
+ destroyring(ring);
+ return (result);
+}
+
isc_result_t
dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
unsigned char *secret, int length, isc_boolean_t generated,
@@ -1589,14 +1783,43 @@ dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp) {
ring->maxgenerated = DNS_TSIG_MAXGENERATEDKEYS;
ISC_LIST_INIT(ring->lru);
isc_mem_attach(mctx, &ring->mctx);
+ ring->references = 1;
*ringp = ring;
return (ISC_R_SUCCESS);
}
+isc_result_t
+dns_tsigkeyring_add(dns_tsig_keyring_t *ring, dns_name_t *name,
+ dns_tsigkey_t *tkey)
+{
+ isc_result_t result;
+
+ result = keyring_add(ring, name, tkey);
+ if (result == ISC_R_SUCCESS)
+ isc_refcount_increment(&tkey->refs, NULL);
+
+ return (result);
+}
+
void
-dns_tsigkeyring_destroy(dns_tsig_keyring_t **ringp) {
+dns_tsigkeyring_attach(dns_tsig_keyring_t *source, dns_tsig_keyring_t **target)
+{
+ REQUIRE(source != NULL);
+ REQUIRE(target != NULL && *target == NULL);
+
+ RWLOCK(&source->lock, isc_rwlocktype_write);
+ INSIST(source->references > 0);
+ source->references++;
+ INSIST(source->references > 0);
+ *target = source;
+ RWUNLOCK(&source->lock, isc_rwlocktype_write);
+}
+
+void
+dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp) {
dns_tsig_keyring_t *ring;
+ unsigned int references;
REQUIRE(ringp != NULL);
REQUIRE(*ringp != NULL);
@@ -1604,7 +1827,27 @@ dns_tsigkeyring_destroy(dns_tsig_keyring_t **ringp) {
ring = *ringp;
*ringp = NULL;
- dns_rbt_destroy(&ring->keys);
- isc_rwlock_destroy(&ring->lock);
- isc_mem_putanddetach(&ring->mctx, ring, sizeof(dns_tsig_keyring_t));
+ RWLOCK(&ring->lock, isc_rwlocktype_write);
+ INSIST(ring->references > 0);
+ ring->references--;
+ references = ring->references;
+ RWUNLOCK(&ring->lock, isc_rwlocktype_write);
+
+ if (references == 0)
+ destroyring(ring);
+}
+
+void
+dns_keyring_restore(dns_tsig_keyring_t *ring, FILE *fp) {
+ isc_stdtime_t now;
+ isc_result_t result;
+
+ isc_stdtime_get(&now);
+ do {
+ result = restore_key(ring, now, fp);
+ if (result == ISC_R_NOMORE)
+ return;
+ if (result == DNS_R_BADALG || result == DNS_R_EXPIRED)
+ result = ISC_R_SUCCESS;
+ } while (result == ISC_R_SUCCESS);
}
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index 79c8798bbeee..6c0d38dc71a5 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.164.12.23.4.3 2011-06-21 20:13:23 each Exp $ */
+/* $Id: validator.c,v 1.197.40.3 2011-06-21 20:15:54 each Exp $ */
#include <config.h>
@@ -28,17 +28,17 @@
#include <isc/util.h>
#include <dns/db.h>
-#include <dns/ds.h>
#include <dns/dnssec.h>
+#include <dns/ds.h>
#include <dns/events.h>
#include <dns/keytable.h>
+#include <dns/keyvalues.h>
#include <dns/log.h>
#include <dns/message.h>
#include <dns/ncache.h>
#include <dns/nsec.h>
#include <dns/nsec3.h>
#include <dns/rdata.h>
-#include <dns/rdatastruct.h>
#include <dns/rdataset.h>
#include <dns/rdatatype.h>
#include <dns/resolver.h>
@@ -255,9 +255,17 @@ dlv_algorithm_supported(dns_validator_t *val) {
dlv.algorithm))
continue;
+#ifdef HAVE_OPENSSL_GOST
+ if (dlv.digest_type != DNS_DSDIGEST_SHA256 &&
+ dlv.digest_type != DNS_DSDIGEST_SHA1 &&
+ dlv.digest_type != DNS_DSDIGEST_GOST)
+ continue;
+#else
if (dlv.digest_type != DNS_DSDIGEST_SHA256 &&
dlv.digest_type != DNS_DSDIGEST_SHA1)
continue;
+#endif
+
return (ISC_TRUE);
}
@@ -383,7 +391,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
}
/*%
- * We have been asked to to look for a key.
+ * We have been asked to look for a key.
* If found resume the validation process.
* If not found fail the validation process.
*/
@@ -582,7 +590,8 @@ dsfetched2(isc_task_t *task, isc_event_t *event) {
if (isdelegation(tname, &val->frdataset, eresult)) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, no DS"
+ " and this is a delegation");
validator_done(val, DNS_R_MUSTBESECURE);
} else if (val->view->dlv == NULL || DLVTRIED(val)) {
markanswer(val, "dsfetched2");
@@ -1089,7 +1098,7 @@ nsec3noexistnodata(dns_validator_t *val, dns_name_t* name,
if (ns && !soa) {
if (!atparent) {
/*
- * This NSEC record is from somewhere
+ * This NSEC3 record is from somewhere
* higher in the DNS, and at the
* parent of a delegation. It can not
* be legitimately used here.
@@ -1100,7 +1109,7 @@ nsec3noexistnodata(dns_validator_t *val, dns_name_t* name,
}
} else if (atparent && ns && soa) {
/*
- * This NSEC record is from the child.
+ * This NSEC3 record is from the child.
* It can not be legitimately used here.
*/
validator_log(val, ISC_LOG_DEBUG(3),
@@ -1505,8 +1514,11 @@ create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
if (dns_rdataset_isassociated(&val->fsigrdataset))
dns_rdataset_disassociate(&val->fsigrdataset);
- if (check_deadlock(val, name, type, NULL, NULL))
+ if (check_deadlock(val, name, type, NULL, NULL)) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "deadlock found (create_fetch)");
return (DNS_R_NOVALIDSIG);
+ }
validator_logcreate(val, name, type, caller, "fetch");
return (dns_resolver_createfetch(val->view->resolver, name, type,
@@ -1528,8 +1540,11 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
{
isc_result_t result;
- if (check_deadlock(val, name, type, rdataset, sigrdataset))
+ if (check_deadlock(val, name, type, rdataset, sigrdataset)) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "deadlock found (create_validator)");
return (DNS_R_NOVALIDSIG);
+ }
validator_logcreate(val, name, type, caller, "validator");
result = dns_validator_create(val->view, name, type,
@@ -1768,16 +1783,23 @@ compute_keytag(dns_rdata_t *rdata, dns_rdata_dnskey_t *key) {
*/
static isc_boolean_t
isselfsigned(dns_validator_t *val) {
+ dns_fixedname_t fixed;
dns_rdataset_t *rdataset, *sigrdataset;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_t sigrdata = DNS_RDATA_INIT;
dns_rdata_dnskey_t key;
dns_rdata_rrsig_t sig;
dns_keytag_t keytag;
+ dns_name_t *name;
isc_result_t result;
+ dst_key_t *dstkey;
+ isc_mem_t *mctx;
+ isc_boolean_t answer = ISC_FALSE;
rdataset = val->event->rdataset;
sigrdataset = val->event->sigrdataset;
+ name = val->event->name;
+ mctx = val->view->mctx;
INSIST(rdataset->type == dns_rdatatype_dnskey);
@@ -1799,12 +1821,31 @@ isselfsigned(dns_validator_t *val) {
result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (sig.algorithm == key.algorithm &&
- sig.keyid == keytag)
- return (ISC_TRUE);
+ if (sig.algorithm != key.algorithm ||
+ sig.keyid != keytag ||
+ !dns_name_equal(name, &sig.signer))
+ continue;
+
+ dstkey = NULL;
+ result = dns_dnssec_keyfromrdata(name, &rdata, mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ result = dns_dnssec_verify2(name, rdataset, dstkey,
+ ISC_TRUE, mctx, &sigrdata,
+ dns_fixedname_name(&fixed));
+ dst_key_free(&dstkey);
+ if (result != ISC_R_SUCCESS)
+ continue;
+ if ((key.flags & DNS_KEYFLAG_REVOKE) == 0) {
+ answer = ISC_TRUE;
+ continue;
+ }
+ dns_view_untrust(val->view, name, &key, mctx);
}
}
- return (ISC_FALSE);
+ return (answer);
}
/*%
@@ -1946,6 +1987,8 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
break;
}
val->key = dns_keynode_key(val->keynode);
+ if (val->key == NULL)
+ break;
} else {
if (get_dst_key(val, val->siginfo, val->keyset)
!= ISC_R_SUCCESS)
@@ -1962,8 +2005,6 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
isc_stdtime_get(&now);
ttl = ISC_MIN(event->rdataset->ttl,
val->siginfo->timeexpire - now);
- if (val->keyset != NULL)
- ttl = ISC_MIN(ttl, val->keyset->ttl);
event->rdataset->ttl = ttl;
event->sigrdataset->ttl = ttl;
}
@@ -1992,7 +2033,8 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
} else if (result == ISC_R_SUCCESS) {
marksecure(event);
validator_log(val, ISC_LOG_DEBUG(3),
- "marking as secure");
+ "marking as secure, "
+ "noqname proof not needed");
return (result);
} else {
validator_log(val, ISC_LOG_DEBUG(3),
@@ -2013,25 +2055,102 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
}
/*%
+ * Check whether this DNSKEY (keyrdata) signed the DNSKEY RRset
+ * (val->event->rdataset).
+ */
+static isc_result_t
+checkkey(dns_validator_t *val, dns_rdata_t *keyrdata, isc_uint16_t keyid,
+ dns_secalg_t algorithm)
+{
+ dns_rdata_rrsig_t sig;
+ dst_key_t *dstkey = NULL;
+ isc_result_t result;
+
+ for (result = dns_rdataset_first(val->event->sigrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(val->event->sigrdataset))
+ {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(val->event->sigrdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &sig, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if (keyid != sig.keyid || algorithm != sig.algorithm)
+ continue;
+ if (dstkey == NULL) {
+ result = dns_dnssec_keyfromrdata(val->event->name,
+ keyrdata,
+ val->view->mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS)
+ /*
+ * This really shouldn't happen, but...
+ */
+ continue;
+ }
+ result = verify(val, dstkey, &rdata, sig.keyid);
+ if (result == ISC_R_SUCCESS)
+ break;
+ }
+ if (dstkey != NULL)
+ dst_key_free(&dstkey);
+ return (result);
+}
+
+/*%
+ * Find the DNSKEY that corresponds to the DS.
+ */
+static isc_result_t
+keyfromds(dns_validator_t *val, dns_rdataset_t *rdataset, dns_rdata_t *dsrdata,
+ isc_uint8_t digest, isc_uint16_t keyid, dns_secalg_t algorithm,
+ dns_rdata_t *keyrdata)
+{
+ dns_keytag_t keytag;
+ dns_rdata_dnskey_t key;
+ isc_result_t result;
+ unsigned char dsbuf[DNS_DS_BUFFERSIZE];
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset))
+ {
+ dns_rdata_t newdsrdata = DNS_RDATA_INIT;
+
+ dns_rdata_reset(keyrdata);
+ dns_rdataset_current(rdataset, keyrdata);
+ result = dns_rdata_tostruct(keyrdata, &key, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ keytag = compute_keytag(keyrdata, &key);
+ if (keyid != keytag || algorithm != key.algorithm)
+ continue;
+ dns_rdata_reset(&newdsrdata);
+ result = dns_ds_buildrdata(val->event->name, keyrdata, digest,
+ dsbuf, &newdsrdata);
+ if (result != ISC_R_SUCCESS) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "dns_ds_buildrdata() -> %s",
+ dns_result_totext(result));
+ continue;
+ }
+ if (dns_rdata_compare(dsrdata, &newdsrdata) == 0)
+ break;
+ }
+ return (result);
+}
+
+/*%
* Validate the DNSKEY RRset by looking for a DNSKEY that matches a
* DLV record and that also verifies the DNSKEY RRset.
*/
static isc_result_t
dlv_validatezonekey(dns_validator_t *val) {
- dns_keytag_t keytag;
dns_rdata_dlv_t dlv;
- dns_rdata_dnskey_t key;
- dns_rdata_rrsig_t sig;
dns_rdata_t dlvrdata = DNS_RDATA_INIT;
dns_rdata_t keyrdata = DNS_RDATA_INIT;
- dns_rdata_t newdsrdata = DNS_RDATA_INIT;
- dns_rdata_t sigrdata = DNS_RDATA_INIT;
dns_rdataset_t trdataset;
- dst_key_t *dstkey;
isc_boolean_t supported_algorithm;
isc_result_t result;
- unsigned char dsbuf[DNS_DS_BUFFERSIZE];
- isc_uint8_t digest_type;
+ char digest_types[256];
validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey");
@@ -2048,7 +2167,7 @@ dlv_validatezonekey(dns_validator_t *val) {
* need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256
* is present.
*/
- digest_type = DNS_DSDIGEST_SHA1;
+ memset(digest_types, 1, sizeof(digest_types));
for (result = dns_rdataset_first(&val->dlv);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&val->dlv)) {
@@ -2064,7 +2183,7 @@ dlv_validatezonekey(dns_validator_t *val) {
if (dlv.digest_type == DNS_DSDIGEST_SHA256 &&
dlv.length == ISC_SHA256_DIGESTLENGTH) {
- digest_type = DNS_DSDIGEST_SHA256;
+ digest_types[DNS_DSDIGEST_SHA1] = 0;
break;
}
}
@@ -2082,7 +2201,7 @@ dlv_validatezonekey(dns_validator_t *val) {
dlv.digest_type))
continue;
- if (dlv.digest_type != digest_type)
+ if (digest_types[dlv.digest_type] == 0)
continue;
if (!dns_resolver_algorithm_supported(val->view->resolver,
@@ -2095,70 +2214,27 @@ dlv_validatezonekey(dns_validator_t *val) {
dns_rdataset_init(&trdataset);
dns_rdataset_clone(val->event->rdataset, &trdataset);
- for (result = dns_rdataset_first(&trdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&trdataset))
- {
- dns_rdata_reset(&keyrdata);
- dns_rdataset_current(&trdataset, &keyrdata);
- result = dns_rdata_tostruct(&keyrdata, &key, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- keytag = compute_keytag(&keyrdata, &key);
- if (dlv.key_tag != keytag ||
- dlv.algorithm != key.algorithm)
- continue;
- dns_rdata_reset(&newdsrdata);
- result = dns_ds_buildrdata(val->event->name,
- &keyrdata, dlv.digest_type,
- dsbuf, &newdsrdata);
- if (result != ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "dns_ds_buildrdata() -> %s",
- dns_result_totext(result));
- continue;
- }
- /* Covert to DLV */
- newdsrdata.type = dns_rdatatype_dlv;
- if (dns_rdata_compare(&dlvrdata, &newdsrdata) == 0)
- break;
- }
+ /*
+ * Convert to DLV to DS and find matching DNSKEY.
+ */
+ dlvrdata.type = dns_rdatatype_ds;
+ result = keyfromds(val, &trdataset, &dlvrdata,
+ dlv.digest_type, dlv.key_tag,
+ dlv.algorithm, &keyrdata);
if (result != ISC_R_SUCCESS) {
dns_rdataset_disassociate(&trdataset);
validator_log(val, ISC_LOG_DEBUG(3),
"no DNSKEY matching DLV");
continue;
}
+
validator_log(val, ISC_LOG_DEBUG(3),
"Found matching DLV record: checking for signature");
+ /*
+ * Check that this DNSKEY signed the DNSKEY rrset.
+ */
+ result = checkkey(val, &keyrdata, dlv.key_tag, dlv.algorithm);
- for (result = dns_rdataset_first(val->event->sigrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(val->event->sigrdataset))
- {
- dns_rdata_reset(&sigrdata);
- dns_rdataset_current(val->event->sigrdataset,
- &sigrdata);
- result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (dlv.key_tag != sig.keyid ||
- dlv.algorithm != sig.algorithm)
- continue;
- dstkey = NULL;
- result = dns_dnssec_keyfromrdata(val->event->name,
- &keyrdata,
- val->view->mctx,
- &dstkey);
- if (result != ISC_R_SUCCESS)
- /*
- * This really shouldn't happen, but...
- */
- continue;
-
- result = verify(val, dstkey, &sigrdata, sig.keyid);
- dst_key_free(&dstkey);
- if (result == ISC_R_SUCCESS)
- break;
- }
dns_rdataset_disassociate(&trdataset);
if (result == ISC_R_SUCCESS)
break;
@@ -2167,12 +2243,13 @@ dlv_validatezonekey(dns_validator_t *val) {
}
if (result == ISC_R_SUCCESS) {
marksecure(val->event);
- validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
+ validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (dlv)");
return (result);
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure,"
+ "no supported algorithm/digest (dlv)");
return (DNS_R_MUSTBESECURE);
}
validator_log(val, ISC_LOG_DEBUG(3),
@@ -2184,7 +2261,8 @@ dlv_validatezonekey(dns_validator_t *val) {
}
/*%
- * Attempts positive response validation of an RRset containing zone keys.
+ * Attempts positive response validation of an RRset containing zone keys
+ * (i.e. a DNSKEY rrset).
*
* Returns:
* \li ISC_R_SUCCESS Validation completed successfully
@@ -2198,19 +2276,15 @@ validatezonekey(dns_validator_t *val) {
dns_validatorevent_t *event;
dns_rdataset_t trdataset;
dns_rdata_t dsrdata = DNS_RDATA_INIT;
- dns_rdata_t newdsrdata = DNS_RDATA_INIT;
dns_rdata_t keyrdata = DNS_RDATA_INIT;
dns_rdata_t sigrdata = DNS_RDATA_INIT;
- unsigned char dsbuf[DNS_DS_BUFFERSIZE];
char namebuf[DNS_NAME_FORMATSIZE];
- dns_keytag_t keytag;
dns_rdata_ds_t ds;
- dns_rdata_dnskey_t key;
dns_rdata_rrsig_t sig;
dst_key_t *dstkey;
isc_boolean_t supported_algorithm;
isc_boolean_t atsep = ISC_FALSE;
- isc_uint8_t digest_type;
+ char digest_types[256];
/*
* Caller must be holding the validator lock.
@@ -2259,8 +2333,7 @@ validatezonekey(dns_validator_t *val) {
result = dns_keytable_findkeynode(val->keytable,
val->event->name,
sig.algorithm,
- sig.keyid,
- &keynode);
+ sig.keyid, &keynode);
if (result == ISC_R_NOTFOUND &&
dns_keytable_finddeepestmatch(val->keytable,
val->event->name, found) != ISC_R_SUCCESS) {
@@ -2284,11 +2357,18 @@ validatezonekey(dns_validator_t *val) {
while (result == ISC_R_SUCCESS) {
dns_keynode_t *nextnode = NULL;
dstkey = dns_keynode_key(keynode);
+ if (dstkey == NULL) {
+ dns_keytable_detachkeynode(
+ val->keytable,
+ &keynode);
+ break;
+ }
result = verify(val, dstkey, &sigrdata,
sig.keyid);
if (result == ISC_R_SUCCESS) {
- dns_keytable_detachkeynode(val->keytable,
- &keynode);
+ dns_keytable_detachkeynode(
+ val->keytable,
+ &keynode);
break;
}
result = dns_keytable_findnextkeynode(
@@ -2318,8 +2398,8 @@ validatezonekey(dns_validator_t *val) {
sizeof(namebuf));
validator_log(val, ISC_LOG_NOTICE,
"unable to find a DNSKEY which verifies "
- "the DNSKEY RRset and also matches one "
- "of specified trusted-keys for '%s'",
+ "the DNSKEY RRset and also matches a "
+ "trusted key for '%s'",
namebuf);
validator_log(val, ISC_LOG_NOTICE,
"please check the 'trusted-keys' for "
@@ -2413,7 +2493,8 @@ validatezonekey(dns_validator_t *val) {
if (val->dsset->trust < dns_trust_secure) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure,"
+ " insecure DS");
return (DNS_R_MUSTBESECURE);
}
if (val->view->dlv == NULL || DLVTRIED(val)) {
@@ -2437,7 +2518,7 @@ validatezonekey(dns_validator_t *val) {
* need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256
* is present.
*/
- digest_type = DNS_DSDIGEST_SHA1;
+ memset(digest_types, 1, sizeof(digest_types));
for (result = dns_rdataset_first(val->dsset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(val->dsset)) {
@@ -2453,7 +2534,7 @@ validatezonekey(dns_validator_t *val) {
if (ds.digest_type == DNS_DSDIGEST_SHA256 &&
ds.length == ISC_SHA256_DIGESTLENGTH) {
- digest_type = DNS_DSDIGEST_SHA256;
+ digest_types[DNS_DSDIGEST_SHA1] = 0;
break;
}
}
@@ -2471,7 +2552,7 @@ validatezonekey(dns_validator_t *val) {
ds.digest_type))
continue;
- if (ds.digest_type != digest_type)
+ if (digest_types[ds.digest_type] == 0)
continue;
if (!dns_resolver_algorithm_supported(val->view->resolver,
@@ -2485,29 +2566,10 @@ validatezonekey(dns_validator_t *val) {
dns_rdataset_clone(val->event->rdataset, &trdataset);
/*
- * Look for the KEY that matches the DS record.
+ * Find matching DNSKEY from DS.
*/
- for (result = dns_rdataset_first(&trdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&trdataset))
- {
- dns_rdata_reset(&keyrdata);
- dns_rdataset_current(&trdataset, &keyrdata);
- result = dns_rdata_tostruct(&keyrdata, &key, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- keytag = compute_keytag(&keyrdata, &key);
- if (ds.key_tag != keytag ||
- ds.algorithm != key.algorithm)
- continue;
- dns_rdata_reset(&newdsrdata);
- result = dns_ds_buildrdata(val->event->name,
- &keyrdata, ds.digest_type,
- dsbuf, &newdsrdata);
- if (result != ISC_R_SUCCESS)
- continue;
- if (dns_rdata_compare(&dsrdata, &newdsrdata) == 0)
- break;
- }
+ result = keyfromds(val, &trdataset, &dsrdata, ds.digest_type,
+ ds.key_tag, ds.algorithm, &keyrdata);
if (result != ISC_R_SUCCESS) {
dns_rdataset_disassociate(&trdataset);
validator_log(val, ISC_LOG_DEBUG(3),
@@ -2515,38 +2577,11 @@ validatezonekey(dns_validator_t *val) {
continue;
}
- for (result = dns_rdataset_first(val->event->sigrdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(val->event->sigrdataset))
- {
- dns_rdata_reset(&sigrdata);
- dns_rdataset_current(val->event->sigrdataset,
- &sigrdata);
- result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if (ds.key_tag != sig.keyid ||
- ds.algorithm != sig.algorithm)
- continue;
- if (!dns_name_equal(val->event->name, &sig.signer)) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "DNSKEY signer mismatch");
- continue;
- }
- dstkey = NULL;
- result = dns_dnssec_keyfromrdata(val->event->name,
- &keyrdata,
- val->view->mctx,
- &dstkey);
- if (result != ISC_R_SUCCESS)
- /*
- * This really shouldn't happen, but...
- */
- continue;
- result = verify(val, dstkey, &sigrdata, sig.keyid);
- dst_key_free(&dstkey);
- if (result == ISC_R_SUCCESS)
- break;
- }
+ /*
+ * Check that this DNSKEY signed the DNSKEY rrset.
+ */
+ result = checkkey(val, &keyrdata, ds.key_tag, ds.algorithm);
+
dns_rdataset_disassociate(&trdataset);
if (result == ISC_R_SUCCESS)
break;
@@ -2555,20 +2590,24 @@ validatezonekey(dns_validator_t *val) {
}
if (result == ISC_R_SUCCESS) {
marksecure(event);
- validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
+ validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (DS)");
return (result);
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "no supported algorithm/digest (DS)");
return (DNS_R_MUSTBESECURE);
}
validator_log(val, ISC_LOG_DEBUG(3),
"no supported algorithm/digest (DS)");
markanswer(val, "validatezonekey (3)");
return (ISC_R_SUCCESS);
- } else
+ } else {
+ validator_log(val, ISC_LOG_INFO,
+ "no valid signature found (DS)");
return (DNS_R_NOVALIDSIG);
+ }
}
/*%
@@ -3094,9 +3133,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
findnsec3proofs(val);
if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val)) {
validator_log(val, ISC_LOG_DEBUG(3),
- "noqname proof found");
- validator_log(val, ISC_LOG_DEBUG(3),
- "marking as secure");
+ "marking as secure, noqname proof found");
marksecure(val->event);
return (ISC_R_SUCCESS);
} else if (FOUNDOPTOUT(val) &&
@@ -3143,7 +3180,6 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
marksecure(val->event);
return (ISC_R_SUCCESS);
}
- findnsec3proofs(val);
if (val->authfail != 0 && val->authcount == val->authfail)
return (DNS_R_BROKENCHAIN);
@@ -3345,7 +3381,8 @@ startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) {
namebuf);
if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
- validator_log(val, ISC_LOG_WARNING, "must be secure failure");
+ validator_log(val, ISC_LOG_WARNING, "must be secure failure, "
+ " %s is under DLV (startfinddlvsep)", namebuf);
return (DNS_R_MUSTBESECURE);
}
@@ -3397,10 +3434,12 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
INSIST(val->view->dlv != NULL);
if (!resume) {
-
if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
+ dns_name_format(val->event->name, namebuf,
+ sizeof(namebuf));
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "%s is under DLV (finddlvsep)", namebuf);
return (DNS_R_MUSTBESECURE);
}
@@ -3468,8 +3507,11 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
return (result);
return (DNS_R_WAIT);
}
- if (val->frdataset.trust < dns_trust_secure)
+ if (val->frdataset.trust < dns_trust_secure) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "DLV not validated");
return (DNS_R_NOVALIDSIG);
+ }
val->havedlvsep = ISC_TRUE;
dns_rdataset_clone(&val->frdataset, &val->dlv);
return (ISC_R_SUCCESS);
@@ -3554,10 +3596,13 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if (result == ISC_R_NOTFOUND) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "not beneath secure root");
result = DNS_R_MUSTBESECURE;
goto out;
- }
+ } else
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "not beneath secure root");
if (val->view->dlv == NULL || DLVTRIED(val)) {
markanswer(val, "proveunsecure (1)");
return (ISC_R_SUCCESS);
@@ -3577,7 +3622,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
/*
* If we have a DS rdataset and it is secure then check if
* the DS rdataset has a supported algorithm combination.
- * If not this is a insecure delegation as far as this
+ * If not this is an insecure delegation as far as this
* resolver is concerned. Fall back to DLV if available.
*/
if (have_ds && val->frdataset.trust >= dns_trust_secure &&
@@ -3588,7 +3633,8 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if ((val->view->dlv == NULL || DLVTRIED(val)) &&
val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure at '%s'",
+ "must be secure failure at '%s', "
+ "can't fall back to DLV",
namebuf);
result = DNS_R_MUSTBESECURE;
goto out;
@@ -3630,7 +3676,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
/*
* There is no DS. If this is a delegation,
- * we maybe done.
+ * we may be done.
*/
/*
* If we have "trust == answer" then this namespace
@@ -3643,7 +3689,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
&val->frdataset,
NULL, dsvalidated,
"proveunsecure");
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto out;
return (DNS_R_WAIT);
}
@@ -3655,12 +3701,13 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if (result == DNS_R_NXRRSET &&
!dns_rdataset_isassociated(&val->frdataset) &&
dns_view_findzonecut2(val->view, tname, found,
- 0, 0, ISC_FALSE, ISC_FALSE,
- NULL, NULL) == ISC_R_SUCCESS &&
+ 0, 0, ISC_FALSE, ISC_FALSE,
+ NULL, NULL) == ISC_R_SUCCESS &&
dns_name_equal(tname, found)) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "no DS at zone cut");
return (DNS_R_MUSTBESECURE);
}
if (val->view->dlv == NULL || DLVTRIED(val)) {
@@ -3676,13 +3723,18 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
* there's no way of validating existing
* negative response blobs, give up.
*/
+ validator_log(val, ISC_LOG_WARNING,
+ "can't validate existing "
+ "negative responses (no DS)");
result = DNS_R_NOVALIDSIG;
goto out;
}
if (isdelegation(tname, &val->frdataset, result)) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "%s is a delegation",
+ namebuf);
return (DNS_R_MUSTBESECURE);
}
if (val->view->dlv == NULL || DLVTRIED(val)) {
@@ -3705,7 +3757,10 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if (val->mustbesecure) {
validator_log(val,
ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure, "
+ "no supported algorithm/"
+ "digest (%s/DS)",
+ namebuf);
result = DNS_R_MUSTBESECURE;
goto out;
}
@@ -3723,6 +3778,8 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
}
else if (!dns_rdataset_isassociated(&val->fsigrdataset))
{
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "DS is unsigned");
result = DNS_R_NOVALIDSIG;
goto out;
}
@@ -3771,6 +3828,10 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
* there's no way of validating existing
* negative response blobs, give up.
*/
+ validator_log(val, ISC_LOG_WARNING,
+ "can't validate existing "
+ "negative responses "
+ "(not a zone cut)");
result = DNS_R_NOVALIDSIG;
goto out;
}
@@ -3790,7 +3851,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
/* Couldn't complete insecurity proof */
validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");
- return (DNS_R_NOTINSECURE); /* Couldn't complete insecurity proof */
+ return (DNS_R_NOTINSECURE);
out:
if (dns_rdataset_isassociated(&val->frdataset))
@@ -3829,7 +3890,7 @@ dlv_validator_start(dns_validator_t *val) {
* \li 3. a negative answer (secure or unsecure).
*
* Note a answer that appears to be a secure positive answer may actually
- * be a unsecure positive answer.
+ * be an unsecure positive answer.
*/
static void
validator_start(isc_task_t *task, isc_event_t *event) {
@@ -3895,6 +3956,10 @@ validator_start(isc_task_t *task, isc_event_t *event) {
val->attributes |= VALATTR_INSECURITY;
result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
+ if (result == DNS_R_NOTINSECURE)
+ validator_log(val, ISC_LOG_INFO,
+ "got insecure response; "
+ "parent indicates it should be secure");
} else if (val->event->rdataset == NULL &&
val->event->sigrdataset == NULL)
{
@@ -3967,6 +4032,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
return (ISC_R_NOMEMORY);
val->view = NULL;
dns_view_weakattach(view, &val->view);
+
event = (dns_validatorevent_t *)
isc_event_allocate(view->mctx, task,
DNS_EVENT_VALIDATORSTART,
@@ -3995,8 +4061,12 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
val->fetch = NULL;
val->subvalidator = NULL;
val->parent = NULL;
+
val->keytable = NULL;
- dns_keytable_attach(val->view->secroots, &val->keytable);
+ result = dns_view_getsecroots(val->view, &val->keytable);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
val->keynode = NULL;
val->key = NULL;
val->siginfo = NULL;
diff --git a/lib/dns/view.c b/lib/dns/view.c
index 809cc151334b..24f925a010ed 100644
--- a/lib/dns/view.c
+++ b/lib/dns/view.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,13 +15,16 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.c,v 1.150.84.6 2010-09-24 08:09:08 marka Exp $ */
+/* $Id: view.c,v 1.178 2011-01-13 09:53:04 marka Exp $ */
/*! \file */
#include <config.h>
+#include <isc/file.h>
#include <isc/hash.h>
+#include <isc/print.h>
+#include <isc/sha2.h>
#include <isc/stats.h>
#include <isc/string.h> /* Required for HP/UX (and others?) */
#include <isc/task.h>
@@ -33,17 +36,24 @@
#include <dns/cache.h>
#include <dns/db.h>
#include <dns/dlz.h>
+#ifdef BIND9
+#include <dns/dns64.h>
+#endif
+#include <dns/dnssec.h>
#include <dns/events.h>
#include <dns/forward.h>
#include <dns/keytable.h>
+#include <dns/keyvalues.h>
#include <dns/master.h>
#include <dns/masterdump.h>
#include <dns/order.h>
#include <dns/peer.h>
+#include <dns/rbt.h>
#include <dns/rdataset.h>
#include <dns/request.h>
#include <dns/resolver.h>
#include <dns/result.h>
+#include <dns/rpz.h>
#include <dns/stats.h>
#include <dns/tsig.h>
#include <dns/zone.h>
@@ -85,6 +95,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
if (result != ISC_R_SUCCESS)
goto cleanup_name;
+#ifdef BIND9
view->zonetable = NULL;
result = dns_zt_create(mctx, rdclass, &view->zonetable);
if (result != ISC_R_SUCCESS) {
@@ -94,24 +105,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
result = ISC_R_UNEXPECTED;
goto cleanup_mutex;
}
- view->secroots = NULL;
- result = dns_keytable_create(mctx, &view->secroots);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "dns_keytable_create() failed: %s",
- isc_result_totext(result));
- result = ISC_R_UNEXPECTED;
- goto cleanup_zt;
- }
- view->trustedkeys = NULL;
- result = dns_keytable_create(mctx, &view->trustedkeys);
- if (result != ISC_R_SUCCESS) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "dns_keytable_create() failed: %s",
- isc_result_totext(result));
- result = ISC_R_UNEXPECTED;
- goto cleanup_secroots;
- }
+#endif
+ view->secroots_priv = NULL;
view->fwdtable = NULL;
result = dns_fwdtable_create(mctx, &view->fwdtable);
if (result != ISC_R_SUCCESS) {
@@ -119,7 +114,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
"dns_fwdtable_create() failed: %s",
isc_result_totext(result));
result = ISC_R_UNEXPECTED;
- goto cleanup_trustedkeys;
+ goto cleanup_zt;
}
view->acache = NULL;
@@ -155,6 +150,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->rootexclude = NULL;
view->resstats = NULL;
view->resquerystats = NULL;
+ view->cacheshared = ISC_FALSE;
+ ISC_LIST_INIT(view->dns64);
+ view->dns64cnt = 0;
/*
* Initialize configuration data with default values.
@@ -179,6 +177,10 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->notifyacl = NULL;
view->updateacl = NULL;
view->upfwdacl = NULL;
+ view->denyansweracl = NULL;
+ view->answeracl_exclude = NULL;
+ view->denyanswernames = NULL;
+ view->answernames_exclude = NULL;
view->requestixfr = ISC_TRUE;
view->provideixfr = ISC_TRUE;
view->maxcachettl = 7 * 24 * 3600;
@@ -188,11 +190,20 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->flush = ISC_FALSE;
view->dlv = NULL;
view->maxudp = 0;
+ view->v4_aaaa = dns_v4_aaaa_ok;
+ view->v4_aaaa_acl = NULL;
+ ISC_LIST_INIT(view->rpz_zones);
dns_fixedname_init(&view->dlv_fixed);
+ view->managed_keys = NULL;
+#ifdef BIND9
+ view->new_zone_file = NULL;
+ view->new_zone_config = NULL;
+ view->cfg_destroy = NULL;
result = dns_order_create(view->mctx, &view->order);
if (result != ISC_R_SUCCESS)
goto cleanup_dynkeys;
+#endif
result = dns_peerlist_new(view->mctx, &view->peers);
if (result != ISC_R_SUCCESS)
@@ -222,10 +233,12 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
dns_peerlist_detach(&view->peers);
cleanup_order:
+#ifdef BIND9
dns_order_detach(&view->order);
cleanup_dynkeys:
- dns_tsigkeyring_destroy(&view->dynamickeys);
+#endif
+ dns_tsigkeyring_detach(&view->dynamickeys);
cleanup_references:
isc_refcount_destroy(&view->references);
@@ -233,16 +246,12 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
cleanup_fwdtable:
dns_fwdtable_destroy(&view->fwdtable);
- cleanup_trustedkeys:
- dns_keytable_detach(&view->trustedkeys);
-
- cleanup_secroots:
- dns_keytable_detach(&view->secroots);
-
cleanup_zt:
+#ifdef BIND9
dns_zt_detach(&view->zonetable);
cleanup_mutex:
+#endif
DESTROYLOCK(&view->lock);
cleanup_name:
@@ -256,6 +265,10 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
static inline void
destroy(dns_view_t *view) {
+#ifdef BIND9
+ dns_dns64_t *dns64;
+#endif
+
REQUIRE(!ISC_LINK_LINKED(view, link));
REQUIRE(isc_refcount_current(&view->references) == 0);
REQUIRE(view->weakrefs == 0);
@@ -263,23 +276,62 @@ destroy(dns_view_t *view) {
REQUIRE(ADBSHUTDOWN(view));
REQUIRE(REQSHUTDOWN(view));
+#ifdef BIND9
if (view->order != NULL)
dns_order_detach(&view->order);
+#endif
if (view->peers != NULL)
dns_peerlist_detach(&view->peers);
- if (view->dynamickeys != NULL)
- dns_tsigkeyring_destroy(&view->dynamickeys);
+
+ if (view->dynamickeys != NULL) {
+ isc_result_t result;
+ char template[20];
+ char keyfile[20];
+ FILE *fp = NULL;
+ int n;
+
+ n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
+ view->name);
+ if (n > 0 && (size_t)n < sizeof(keyfile)) {
+ result = isc_file_mktemplate(keyfile, template,
+ sizeof(template));
+ if (result == ISC_R_SUCCESS)
+ (void)isc_file_openuniqueprivate(template, &fp);
+ }
+ if (fp == NULL)
+ dns_tsigkeyring_detach(&view->dynamickeys);
+ else {
+ result = dns_tsigkeyring_dumpanddetach(
+ &view->dynamickeys, fp);
+ if (result == ISC_R_SUCCESS) {
+ if (fclose(fp) == 0)
+ result = isc_file_rename(template,
+ keyfile);
+ if (result != ISC_R_SUCCESS)
+ (void)remove(template);
+ } else {
+ (void)fclose(fp);
+ (void)remove(template);
+ }
+ }
+ }
if (view->statickeys != NULL)
- dns_tsigkeyring_destroy(&view->statickeys);
+ dns_tsigkeyring_detach(&view->statickeys);
if (view->adb != NULL)
dns_adb_detach(&view->adb);
if (view->resolver != NULL)
dns_resolver_detach(&view->resolver);
+#ifdef BIND9
if (view->acache != NULL) {
if (view->cachedb != NULL)
dns_acache_putdb(view->acache, view->cachedb);
dns_acache_detach(&view->acache);
}
+ dns_rpz_view_destroy(view);
+#else
+ INSIST(view->acache == NULL);
+ INSIST(ISC_LIST_EMPTY(view->rpz_zones));
+#endif
if (view->requestmgr != NULL)
dns_requestmgr_detach(&view->requestmgr);
if (view->task != NULL)
@@ -318,6 +370,16 @@ destroy(dns_view_t *view) {
dns_acl_detach(&view->updateacl);
if (view->upfwdacl != NULL)
dns_acl_detach(&view->upfwdacl);
+ if (view->denyansweracl != NULL)
+ dns_acl_detach(&view->denyansweracl);
+ if (view->v4_aaaa_acl != NULL)
+ dns_acl_detach(&view->v4_aaaa_acl);
+ if (view->answeracl_exclude != NULL)
+ dns_rbt_destroy(&view->answeracl_exclude);
+ if (view->denyanswernames != NULL)
+ dns_rbt_destroy(&view->denyanswernames);
+ if (view->answernames_exclude != NULL)
+ dns_rbt_destroy(&view->answernames_exclude);
if (view->delonly != NULL) {
dns_name_t *name;
int i;
@@ -357,8 +419,19 @@ destroy(dns_view_t *view) {
isc_stats_detach(&view->resstats);
if (view->resquerystats != NULL)
dns_stats_detach(&view->resquerystats);
- dns_keytable_detach(&view->trustedkeys);
- dns_keytable_detach(&view->secroots);
+ if (view->secroots_priv != NULL)
+ dns_keytable_detach(&view->secroots_priv);
+#ifdef BIND9
+ for (dns64 = ISC_LIST_HEAD(view->dns64);
+ dns64 != NULL;
+ dns64 = ISC_LIST_HEAD(view->dns64)) {
+ dns_dns64_unlink(&view->dns64, dns64);
+ dns_dns64_destroy(&dns64);
+ }
+ if (view->managed_keys != NULL)
+ dns_zone_detach(&view->managed_keys);
+ dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
+#endif
dns_fwdtable_destroy(&view->fwdtable);
dns_aclenv_destroy(&view->aclenv);
DESTROYLOCK(&view->lock);
@@ -414,12 +487,19 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
dns_adb_shutdown(view->adb);
if (!REQSHUTDOWN(view))
dns_requestmgr_shutdown(view->requestmgr);
+#ifdef BIND9
if (view->acache != NULL)
dns_acache_shutdown(view->acache);
if (view->flush)
dns_zt_flushanddetach(&view->zonetable);
else
dns_zt_detach(&view->zonetable);
+ if (view->managed_keys != NULL) {
+ if (view->flush)
+ dns_zone_flush(view->managed_keys);
+ dns_zone_detach(&view->managed_keys);
+ }
+#endif
done = all_done(view);
UNLOCK(&view->lock);
}
@@ -440,6 +520,7 @@ dns_view_detach(dns_view_t **viewp) {
view_flushanddetach(viewp, ISC_FALSE);
}
+#ifdef BIND9
static isc_result_t
dialup(dns_zone_t *zone, void *dummy) {
UNUSED(dummy);
@@ -452,6 +533,7 @@ dns_view_dialup(dns_view_t *view) {
REQUIRE(DNS_VIEW_VALID(view));
(void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL);
}
+#endif
void
dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
@@ -633,12 +715,20 @@ dns_view_createresolver(dns_view_t *view,
void
dns_view_setcache(dns_view_t *view, dns_cache_t *cache) {
+ dns_view_setcache2(view, cache, ISC_FALSE);
+}
+
+void
+dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(!view->frozen);
+ view->cacheshared = shared;
if (view->cache != NULL) {
+#ifdef BIND9
if (view->acache != NULL)
dns_acache_putdb(view->acache, view->cachedb);
+#endif
dns_db_detach(&view->cachedb);
dns_cache_detach(&view->cache);
}
@@ -646,8 +736,17 @@ dns_view_setcache(dns_view_t *view, dns_cache_t *cache) {
dns_cache_attachdb(cache, &view->cachedb);
INSIST(DNS_DB_VALID(view->cachedb));
+#ifdef BIND9
if (view->acache != NULL)
dns_acache_setdb(view->acache, view->cachedb);
+#endif
+}
+
+isc_boolean_t
+dns_view_iscacheshared(dns_view_t *view) {
+ REQUIRE(DNS_VIEW_VALID(view));
+
+ return (view->cacheshared);
}
void
@@ -665,26 +764,52 @@ dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(ring != NULL);
if (view->statickeys != NULL)
- dns_tsigkeyring_destroy(&view->statickeys);
- view->statickeys = ring;
+ dns_tsigkeyring_detach(&view->statickeys);
+ dns_tsigkeyring_attach(ring, &view->statickeys);
}
void
-dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
+dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) {
REQUIRE(DNS_VIEW_VALID(view));
- view->dstport = dstport;
+ REQUIRE(ring != NULL);
+ if (view->dynamickeys != NULL)
+ dns_tsigkeyring_detach(&view->dynamickeys);
+ dns_tsigkeyring_attach(ring, &view->dynamickeys);
}
-isc_result_t
-dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
- isc_result_t result;
+void
+dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ REQUIRE(ringp != NULL && *ringp == NULL);
+ if (view->dynamickeys != NULL)
+ dns_tsigkeyring_attach(view->dynamickeys, ringp);
+}
+
+void
+dns_view_restorekeyring(dns_view_t *view) {
+ FILE *fp;
+ char keyfile[20];
+ int n;
REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(!view->frozen);
- result = dns_zt_mount(view->zonetable, zone);
+ if (view->dynamickeys != NULL) {
+ n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys",
+ view->name);
+ if (n > 0 && (size_t)n < sizeof(keyfile)) {
+ fp = fopen(keyfile, "r");
+ if (fp != NULL) {
+ dns_keyring_restore(view->dynamickeys, fp);
+ (void)fclose(fp);
+ }
+ }
+ }
+}
- return (result);
+void
+dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ view->dstport = dstport;
}
void
@@ -699,6 +824,29 @@ dns_view_freeze(dns_view_t *view) {
view->frozen = ISC_TRUE;
}
+#ifdef BIND9
+void
+dns_view_thaw(dns_view_t *view) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ REQUIRE(view->frozen);
+
+ view->frozen = ISC_FALSE;
+}
+
+isc_result_t
+dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
+ isc_result_t result;
+
+ REQUIRE(DNS_VIEW_VALID(view));
+ REQUIRE(!view->frozen);
+
+ result = dns_zt_mount(view->zonetable, zone);
+
+ return (result);
+}
+#endif
+
+#ifdef BIND9
isc_result_t
dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) {
isc_result_t result;
@@ -713,20 +861,37 @@ dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) {
return (result);
}
+#endif
isc_result_t
dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints,
dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
+ return (dns_view_find2(view, name, type, now, options, use_hints,
+ ISC_FALSE, dbp, nodep, foundname, rdataset,
+ sigrdataset));
+}
+
+isc_result_t
+dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
+ isc_stdtime_t now, unsigned int options,
+ isc_boolean_t use_hints, isc_boolean_t use_static_stub,
+ dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{
isc_result_t result;
dns_db_t *db, *zdb;
dns_dbnode_t *node, *znode;
- isc_boolean_t is_cache;
+ isc_boolean_t is_cache, is_staticstub_zone;
dns_rdataset_t zrdataset, zsigrdataset;
dns_zone_t *zone;
+#ifndef BIND9
+ UNUSED(use_hints);
+ UNUSED(use_static_stub);
+#endif
+
/*
* Find an rdataset whose owner name is 'name', and whose type is
* 'type'.
@@ -752,15 +917,30 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
zone = NULL;
db = NULL;
node = NULL;
+ is_staticstub_zone = ISC_FALSE;
+#ifdef BIND9
result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
+ if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub &&
+ !use_static_stub) {
+ result = ISC_R_NOTFOUND;
+ }
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
result = dns_zone_getdb(zone, &db);
if (result != ISC_R_SUCCESS && view->cachedb != NULL)
dns_db_attach(view->cachedb, &db);
else if (result != ISC_R_SUCCESS)
goto cleanup;
+ if (dns_zone_gettype(zone) == dns_zone_staticstub &&
+ dns_name_equal(name, dns_zone_getorigin(zone))) {
+ is_staticstub_zone = ISC_TRUE;
+ }
} else if (result == ISC_R_NOTFOUND && view->cachedb != NULL)
dns_db_attach(view->cachedb, &db);
+#else
+ result = ISC_R_NOTFOUND;
+ if (view->cachedb != NULL)
+ dns_db_attach(view->cachedb, &db);
+#endif /* BIND9 */
else
goto cleanup;
@@ -773,8 +953,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
result = dns_db_find(db, name, NULL, type, options,
now, &node, foundname, rdataset, sigrdataset);
- if (result == DNS_R_DELEGATION ||
- result == ISC_R_NOTFOUND) {
+ if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) {
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
if (sigrdataset != NULL &&
@@ -784,10 +963,13 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
dns_db_detachnode(db, &node);
if (!is_cache) {
dns_db_detach(&db);
- if (view->cachedb != NULL) {
+ if (view->cachedb != NULL && !is_staticstub_zone) {
/*
* Either the answer is in the cache, or we
* don't know it.
+ * Note that if the result comes from a
+ * static-stub zone we stop the search here
+ * (see the function description in view.h).
*/
is_cache = ISC_TRUE;
dns_db_attach(view->cachedb, &db);
@@ -817,7 +999,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
*/
result = ISC_R_NOTFOUND;
} else if (result == DNS_R_GLUE) {
- if (view->cachedb != NULL) {
+ if (view->cachedb != NULL && !is_staticstub_zone) {
/*
* We found an answer, but the cache may be better.
* Remember what we've got and go look in the cache.
@@ -843,6 +1025,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
result = ISC_R_SUCCESS;
}
+#ifdef BIND9
if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) {
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
@@ -877,6 +1060,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
if (db == NULL && node != NULL)
dns_db_detachnode(view->hints, &node);
}
+#endif /* BIND9 */
cleanup:
if (dns_rdataset_isassociated(&zrdataset)) {
@@ -905,8 +1089,10 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
} else
INSIST(node == NULL);
+#ifdef BIND9
if (zone != NULL)
dns_zone_detach(&zone);
+#endif
return (result);
}
@@ -969,12 +1155,12 @@ dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
isc_result_t
dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
isc_stdtime_t now, unsigned int options,
- isc_boolean_t use_hints, isc_boolean_t use_cache,
+ isc_boolean_t use_hints, isc_boolean_t use_cache,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{
isc_result_t result;
dns_db_t *db;
- isc_boolean_t is_cache, use_zone, try_hints;
+ isc_boolean_t is_cache, use_zone, try_hints, is_staticstub_zone;
dns_zone_t *zone;
dns_name_t *zfname;
dns_rdataset_t zrdataset, zsigrdataset;
@@ -986,6 +1172,7 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
db = NULL;
zone = NULL;
use_zone = ISC_FALSE;
+ is_staticstub_zone = ISC_FALSE;
try_hints = ISC_FALSE;
zfname = NULL;
@@ -999,9 +1186,16 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
/*
* Find the right database.
*/
+#ifdef BIND9
result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
- if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
+ if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
result = dns_zone_getdb(zone, &db);
+ if (dns_zone_gettype(zone) == dns_zone_staticstub)
+ is_staticstub_zone = ISC_TRUE;
+ }
+#else
+ result = ISC_R_NOTFOUND;
+#endif
if (result == ISC_R_NOTFOUND) {
/*
* We're not directly authoritative for this query name, nor
@@ -1064,7 +1258,9 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
fname, rdataset, sigrdataset);
if (result == ISC_R_SUCCESS) {
if (zfname != NULL &&
- !dns_name_issubdomain(fname, zfname)) {
+ (!dns_name_issubdomain(fname, zfname) ||
+ (dns_zone_staticstub &&
+ dns_name_equal(fname, zfname)))) {
/*
* We found a zonecut in the cache, but our
* zone delegation is better.
@@ -1133,8 +1329,10 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
}
if (db != NULL)
dns_db_detach(&db);
+#ifdef BIND9
if (zone != NULL)
dns_zone_detach(&zone);
+#endif
return (result);
}
@@ -1161,6 +1359,7 @@ dns_viewlist_find(dns_viewlist_t *list, const char *name,
return (ISC_R_SUCCESS);
}
+#ifdef BIND9
isc_result_t
dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name,
isc_boolean_t allclasses, dns_rdataclass_t rdclass,
@@ -1225,6 +1424,7 @@ dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) {
return (dns_zt_loadnew(view->zonetable, stop));
}
+#endif /* BIND9 */
isc_result_t
dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp)
@@ -1269,6 +1469,7 @@ dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) {
view->dynamickeys));
}
+#ifdef BIND9
isc_result_t
dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
isc_result_t result;
@@ -1284,26 +1485,38 @@ dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
dns_resolver_printbadcache(view->resolver, fp);
return (ISC_R_SUCCESS);
}
+#endif
isc_result_t
dns_view_flushcache(dns_view_t *view) {
+ return (dns_view_flushcache2(view, ISC_FALSE));
+}
+
+isc_result_t
+dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) {
isc_result_t result;
REQUIRE(DNS_VIEW_VALID(view));
if (view->cachedb == NULL)
return (ISC_R_SUCCESS);
- result = dns_cache_flush(view->cache);
- if (result != ISC_R_SUCCESS)
- return (result);
+ if (!fixuponly) {
+ result = dns_cache_flush(view->cache);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+#ifdef BIND9
if (view->acache != NULL)
dns_acache_putdb(view->acache, view->cachedb);
+#endif
dns_db_detach(&view->cachedb);
dns_cache_attachdb(view->cache, &view->cachedb);
+#ifdef BIND9
if (view->acache != NULL)
dns_acache_setdb(view->acache, view->cachedb);
if (view->resolver != NULL)
dns_resolver_flushbadcache(view->resolver, NULL);
+#endif
dns_adb_flush(view->adb);
return (ISC_R_SUCCESS);
@@ -1437,11 +1650,13 @@ dns_view_getrootdelonly(dns_view_t *view) {
return (view->rootdelonly);
}
+#ifdef BIND9
isc_result_t
dns_view_freezezones(dns_view_t *view, isc_boolean_t value) {
REQUIRE(DNS_VIEW_VALID(view));
return (dns_zt_freezezones(view->zonetable, value));
}
+#endif
void
dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) {
@@ -1478,3 +1693,97 @@ dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) {
if (view->resquerystats != NULL)
dns_stats_attach(view->resquerystats, statsp);
}
+
+isc_result_t
+dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ if (view->secroots_priv != NULL)
+ dns_keytable_detach(&view->secroots_priv);
+ return (dns_keytable_create(mctx, &view->secroots_priv));
+}
+
+isc_result_t
+dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ REQUIRE(ktp != NULL && *ktp == NULL);
+ if (view->secroots_priv == NULL)
+ return (ISC_R_NOTFOUND);
+ dns_keytable_attach(view->secroots_priv, ktp);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_view_issecuredomain(dns_view_t *view, dns_name_t *name,
+ isc_boolean_t *secure_domain) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ return (dns_keytable_issecuredomain(view->secroots_priv, name,
+ secure_domain));
+}
+
+void
+dns_view_untrust(dns_view_t *view, dns_name_t *keyname,
+ dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx)
+{
+ isc_result_t result;
+ unsigned char data[4096];
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ isc_buffer_t buffer;
+ dst_key_t *key = NULL;
+ dns_keytable_t *sr = NULL;
+
+ /*
+ * Clear the revoke bit, if set, so that the key will match what's
+ * in secroots now.
+ */
+ dnskey->flags &= ~DNS_KEYFLAG_REVOKE;
+
+ /* Convert dnskey to DST key. */
+ isc_buffer_init(&buffer, data, sizeof(data));
+ dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
+ dns_rdatatype_dnskey, dnskey, &buffer);
+ result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key);
+ if (result != ISC_R_SUCCESS)
+ return;
+ result = dns_view_getsecroots(view, &sr);
+ if (result == ISC_R_SUCCESS) {
+ dns_keytable_deletekeynode(sr, key);
+ dns_keytable_detach(&sr);
+ }
+ dst_key_free(&key);
+}
+
+#define NZF ".nzf"
+
+void
+dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx,
+ void (*cfg_destroy)(void **))
+{
+ REQUIRE(DNS_VIEW_VALID(view));
+ REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow);
+
+#ifdef BIND9
+ if (view->new_zone_file != NULL) {
+ isc_mem_free(view->mctx, view->new_zone_file);
+ view->new_zone_file = NULL;
+ }
+
+ if (view->new_zone_config != NULL) {
+ view->cfg_destroy(&view->new_zone_config);
+ view->cfg_destroy = NULL;
+ }
+
+ if (allow) {
+ char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(NZF)];
+ isc_sha256_data((void *)view->name, strlen(view->name), buffer);
+ /* Truncate the hash at 16 chars; full length is overkill */
+ isc_string_printf(buffer + 16, sizeof(NZF), "%s", NZF);
+ view->new_zone_file = isc_mem_strdup(view->mctx, buffer);
+ view->new_zone_config = cfgctx;
+ view->cfg_destroy = cfg_destroy;
+ }
+#else
+ UNUSED(allow);
+ UNUSED(cfgctx);
+ UNUSED(cfg_destroy);
+#endif
+}
diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c
index b3f2e9554500..210bca9f831f 100644
--- a/lib/dns/xfrin.c
+++ b/lib/dns/xfrin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: xfrin.c,v 1.166 2008-09-25 04:12:39 marka Exp $ */
+/* $Id: xfrin.c,v 1.166.522.2.2.1 2011-06-02 23:47:35 tbox Exp $ */
/*! \file */
@@ -83,8 +83,9 @@ typedef enum {
XFRST_IXFR_DEL,
XFRST_IXFR_ADDSOA,
XFRST_IXFR_ADD,
+ XFRST_IXFR_END,
XFRST_AXFR,
- XFRST_END
+ XFRST_AXFR_END
} xfrin_state_t;
/*%
@@ -203,6 +204,7 @@ static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
dns_rdata_t *rdata);
static isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr);
static isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr);
+static isc_result_t axfr_finalize(dns_xfrin_ctx_t *xfr);
static isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr);
static isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr);
@@ -318,6 +320,16 @@ axfr_commit(dns_xfrin_ctx_t *xfr) {
CHECK(axfr_apply(xfr));
CHECK(dns_db_endload(xfr->db, &xfr->axfr.add_private));
+
+ result = ISC_R_SUCCESS;
+ failure:
+ return (result);
+}
+
+static isc_result_t
+axfr_finalize(dns_xfrin_ctx_t *xfr) {
+ isc_result_t result;
+
CHECK(dns_zone_replacedb(xfr->zone, xfr->db, ISC_TRUE));
result = ISC_R_SUCCESS;
@@ -541,7 +553,7 @@ xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl,
isc_uint32_t soa_serial = dns_soa_getserial(rdata);
if (soa_serial == xfr->end_serial) {
CHECK(ixfr_commit(xfr));
- xfr->state = XFRST_END;
+ xfr->state = XFRST_IXFR_END;
break;
} else if (soa_serial != xfr->ixfr.current_serial) {
xfrin_log(xfr, ISC_LOG_ERROR,
@@ -572,11 +584,12 @@ xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl,
CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
if (rdata->type == dns_rdatatype_soa) {
CHECK(axfr_commit(xfr));
- xfr->state = XFRST_END;
+ xfr->state = XFRST_AXFR_END;
break;
}
break;
- case XFRST_END:
+ case XFRST_AXFR_END:
+ case XFRST_IXFR_END:
FAIL(DNS_R_EXTRADATA);
default:
INSIST(0);
@@ -1318,8 +1331,9 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
} else if (dns_message_gettsigkey(msg) != NULL) {
xfr->sincetsig++;
- if (xfr->sincetsig > 100 ||
- xfr->nmsg == 0 || xfr->state == XFRST_END)
+ if (xfr->sincetsig > 100 || xfr->nmsg == 0 ||
+ xfr->state == XFRST_AXFR_END ||
+ xfr->state == XFRST_IXFR_END)
{
result = DNS_R_EXPECTEDTSIG;
goto failure;
@@ -1345,16 +1359,22 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
dns_message_destroy(&msg);
- if (xfr->state == XFRST_GOTSOA) {
+ switch (xfr->state) {
+ case XFRST_GOTSOA:
xfr->reqtype = dns_rdatatype_axfr;
xfr->state = XFRST_INITIALSOA;
CHECK(xfrin_send_request(xfr));
- } else if (xfr->state == XFRST_END) {
+ break;
+ case XFRST_AXFR_END:
+ CHECK(axfr_finalize(xfr));
+ /* FALLTHROUGH */
+ case XFRST_IXFR_END:
/*
* Close the journal.
*/
if (xfr->ixfr.journal != NULL)
dns_journal_destroy(&xfr->ixfr.journal);
+
/*
* Inform the caller we succeeded.
*/
@@ -1368,7 +1388,8 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
*/
xfr->shuttingdown = ISC_TRUE;
maybe_free(xfr);
- } else {
+ break;
+ default:
/*
* Read the next message.
*/
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 108aefbd9b4a..c727c2e22067 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.483.36.23 2010-12-14 00:48:22 marka Exp $ */
+/* $Id: zone.c,v 1.582.8.7 2011-02-18 23:23:08 each Exp $ */
/*! \file */
@@ -47,6 +47,8 @@
#include <dns/dnssec.h>
#include <dns/events.h>
#include <dns/journal.h>
+#include <dns/keydata.h>
+#include <dns/keytable.h>
#include <dns/keyvalues.h>
#include <dns/log.h>
#include <dns/master.h>
@@ -56,6 +58,8 @@
#include <dns/nsec.h>
#include <dns/nsec3.h>
#include <dns/peer.h>
+#include <dns/private.h>
+#include <dns/rbt.h>
#include <dns/rcode.h>
#include <dns/rdataclass.h>
#include <dns/rdatalist.h>
@@ -66,6 +70,7 @@
#include <dns/request.h>
#include <dns/resolver.h>
#include <dns/result.h>
+#include <dns/rriterator.h>
#include <dns/soa.h>
#include <dns/ssu.h>
#include <dns/stats.h>
@@ -129,6 +134,7 @@ typedef struct dns_signing dns_signing_t;
typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
typedef struct dns_nsec3chain dns_nsec3chain_t;
typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
+typedef struct dns_keyfetch dns_keyfetch_t;
#define DNS_ZONE_CHECKLOCK
#ifdef DNS_ZONE_CHECKLOCK
@@ -200,6 +206,8 @@ struct dns_zone {
isc_time_t keywarntime;
isc_time_t signingtime;
isc_time_t nsec3chaintime;
+ isc_time_t refreshkeytime;
+ isc_uint32_t refreshkeycount;
isc_uint32_t refresh;
isc_uint32_t retry;
isc_uint32_t expire;
@@ -273,13 +281,13 @@ struct dns_zone {
/*%
* Statistics counters about zone management.
*/
- isc_stats_t *stats;
+ isc_stats_t *stats;
/*%
* Optional per-zone statistics counters. Counted outside of this
* module.
*/
- isc_boolean_t requeststats_on;
- isc_stats_t *requeststats;
+ isc_boolean_t requeststats_on;
+ isc_stats_t *requeststats;
isc_uint32_t notifydelay;
dns_isselffunc_t isself;
void *isselfarg;
@@ -304,6 +312,21 @@ struct dns_zone {
isc_uint32_t signatures;
isc_uint32_t nodes;
dns_rdatatype_t privatetype;
+
+ /*%
+ * Autosigning/key-maintenance options
+ */
+ isc_uint32_t keyopts;
+
+ /*%
+ * True if added by "rndc addzone"
+ */
+ isc_boolean_t added;
+
+ /*%
+ * whether a rpz radix was needed when last loaded
+ */
+ isc_boolean_t rpz_zone;
};
#define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
@@ -339,7 +362,7 @@ struct dns_zone {
* from SOA (if not set, we
* are still using
* default timer values) */
-#define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
+#define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
#define DNS_ZONEFLG_NOREFRESH 0x00010000U
#define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
#define DNS_ZONEFLG_DIALREFRESH 0x00040000U
@@ -352,8 +375,11 @@ struct dns_zone {
#define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
#define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
#define DNS_ZONEFLG_THAW 0x08000000U
+/* #define DNS_ZONEFLG_XXXXX 0x10000000U XXXMPA unused. */
+#define DNS_ZONEFLG_NODELAY 0x20000000U
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
+#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
/* Flags for zone_load() */
#define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
@@ -484,7 +510,7 @@ struct dns_io {
* DNSKEY as result of an update.
*/
struct dns_signing {
- unsigned int magic;
+ unsigned int magic;
dns_db_t *db;
dns_dbiterator_t *dbiterator;
dns_secalg_t algorithm;
@@ -495,15 +521,15 @@ struct dns_signing {
};
struct dns_nsec3chain {
- unsigned int magic;
+ unsigned int magic;
dns_db_t *db;
dns_dbiterator_t *dbiterator;
dns_rdata_nsec3param_t nsec3param;
unsigned char salt[255];
isc_boolean_t done;
- isc_boolean_t seen_nsec;
- isc_boolean_t delete_nsec;
- isc_boolean_t save_delete_nsec;
+ isc_boolean_t seen_nsec;
+ isc_boolean_t delete_nsec;
+ isc_boolean_t save_delete_nsec;
ISC_LINK(dns_nsec3chain_t) link;
};
/*%<
@@ -528,6 +554,19 @@ struct dns_nsec3chain {
* so it can be recovered in the event of a error.
*/
+struct dns_keyfetch {
+ dns_fixedname_t name;
+ dns_rdataset_t keydataset;
+ dns_rdataset_t dnskeyset;
+ dns_rdataset_t dnskeysigset;
+ dns_zone_t *zone;
+ dns_db_t *db;
+ dns_fetch_t *fetch;
+};
+
+#define HOUR 3600
+#define DAY (24*HOUR)
+#define MONTH (30*DAY)
#define SEND_BUFFER_SIZE 2048
@@ -538,6 +577,10 @@ static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
ISC_FORMAT_PRINTF(3, 4);
static void queue_xfrin(dns_zone_t *zone);
+static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
+ dns_diff_t *diff, dns_diffop_t op,
+ dns_name_t *name, dns_ttl_t ttl,
+ dns_rdata_t *rdata);
static void zone_unload(dns_zone_t *zone);
static void zone_expire(dns_zone_t *zone);
static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
@@ -613,6 +656,10 @@ static isc_boolean_t dns_zonemgr_unreachable(dns_zonemgr_t *zmgr,
isc_time_t *now);
static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
isc_uint16_t keyid, isc_boolean_t delete);
+static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
+ dns_dbnode_t *node, dns_name_t *name,
+ dns_diff_t *diff);
+static void zone_rekey(dns_zone_t *zone);
#define ENTER zone_debuglog(zone, me, 1, "enter")
@@ -710,6 +757,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->type = dns_zone_none;
zone->flags = 0;
zone->options = 0;
+ zone->keyopts = 0;
zone->db_argc = 0;
zone->db_argv = NULL;
isc_time_settoepoch(&zone->expiretime);
@@ -721,6 +769,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
isc_time_settoepoch(&zone->keywarntime);
isc_time_settoepoch(&zone->signingtime);
isc_time_settoepoch(&zone->nsec3chaintime);
+ isc_time_settoepoch(&zone->refreshkeytime);
+ zone->refreshkeycount = 0;
zone->refresh = DNS_ZONE_DEFAULTREFRESH;
zone->retry = DNS_ZONE_DEFAULTRETRY;
zone->expire = 0;
@@ -787,6 +837,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->signatures = 10;
zone->nodes = 100;
zone->privatetype = (dns_rdatatype_t)0xffffU;
+ zone->added = ISC_FALSE;
+ zone->rpz_zone = ISC_FALSE;
zone->magic = ZONE_MAGIC;
@@ -1304,8 +1356,8 @@ dns_zone_getjournal(dns_zone_t *zone) {
* master file (if any) is written by the server, rather than being
* updated manually and read by the server.
*
- * This is true for slave zones, stub zones, and zones that allow
- * dynamic updates either by having an update policy ("ssutable")
+ * This is true for slave zones, stub zones, key zones, and zones that
+ * allow dynamic updates either by having an update policy ("ssutable")
* or an "allow-update" ACL with a value other than exactly "{ none; }".
*/
static isc_boolean_t
@@ -1314,6 +1366,7 @@ zone_isdynamic(dns_zone_t *zone) {
return (ISC_TF(zone->type == dns_zone_slave ||
zone->type == dns_zone_stub ||
+ zone->type == dns_zone_key ||
(!zone->update_disabled && zone->ssutable != NULL) ||
(!zone->update_disabled && zone->update_acl != NULL &&
!dns_acl_isnone(zone->update_acl))));
@@ -1383,11 +1436,12 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
*/
if (zone->masterfile != NULL) {
/*
- * The file is already loaded. If we are just doing a
+ * The file is already loaded. If we are just doing a
* "rndc reconfig", we are done.
*/
if (!isc_time_isepoch(&zone->loadtime) &&
- (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
+ (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 &&
+ zone->rpz_zone == dns_rpz_needed()) {
result = ISC_R_SUCCESS;
goto cleanup;
}
@@ -1396,7 +1450,8 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
if (result == ISC_R_SUCCESS) {
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
- isc_time_compare(&filetime, &zone->loadtime) <= 0) {
+ isc_time_compare(&filetime, &zone->loadtime) <= 0 &&
+ zone->rpz_zone == dns_rpz_needed()) {
dns_zone_log(zone, ISC_LOG_DEBUG(1),
"skipping load: master file "
"older than last load");
@@ -1404,6 +1459,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
goto cleanup;
}
loadtime = filetime;
+ zone->rpz_zone = dns_rpz_needed();
}
}
@@ -1526,6 +1582,8 @@ get_master_options(dns_zone_t *zone) {
options = DNS_MASTER_ZONE;
if (zone->type == dns_zone_slave)
options |= DNS_MASTER_SLAVE;
+ if (zone->type == dns_zone_key)
+ options |= DNS_MASTER_KEY;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
options |= DNS_MASTER_CHECKNS;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
@@ -1541,7 +1599,8 @@ get_master_options(dns_zone_t *zone) {
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
options |= DNS_MASTER_CHECKWILDCARD;
if (zone->type == dns_zone_master &&
- (zone->update_acl != NULL || zone->ssutable != NULL))
+ ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
+ zone->ssutable != NULL))
options |= DNS_MASTER_RESIGN;
return (options);
}
@@ -1740,11 +1799,12 @@ zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
dns_name_format(name, namebuf, sizeof namebuf);
if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
result == DNS_R_EMPTYNAME) {
+ if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
+ level = ISC_LOG_WARNING;
dns_zone_log(zone, level,
"%s/MX '%s' has no address records (A or AAAA)",
ownerbuf, namebuf);
- /* XXX950 make fatal for 9.5.0. */
- return (ISC_TRUE);
+ return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
}
if (result == DNS_R_CNAME) {
@@ -1986,6 +2046,113 @@ zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
}
static isc_boolean_t
+zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
+ dns_rdataset_t *rdataset)
+{
+ dns_rdataset_t tmprdataset;
+ isc_result_t result;
+ isc_boolean_t answer = ISC_TRUE;
+ isc_boolean_t format = ISC_TRUE;
+ int level = ISC_LOG_WARNING;
+ char ownerbuf[DNS_NAME_FORMATSIZE];
+ char typebuf[DNS_RDATATYPE_FORMATSIZE];
+ unsigned int count1 = 0;
+
+ if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
+ level = ISC_LOG_ERROR;
+
+ dns_rdataset_init(&tmprdataset);
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_t rdata1 = DNS_RDATA_INIT;
+ unsigned int count2 = 0;
+
+ count1++;
+ dns_rdataset_current(rdataset, &rdata1);
+ dns_rdataset_clone(rdataset, &tmprdataset);
+ for (result = dns_rdataset_first(&tmprdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&tmprdataset)) {
+ dns_rdata_t rdata2 = DNS_RDATA_INIT;
+ count2++;
+ if (count1 >= count2)
+ continue;
+ dns_rdataset_current(&tmprdataset, &rdata2);
+ if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
+ if (format) {
+ dns_name_format(owner, ownerbuf,
+ sizeof ownerbuf);
+ dns_rdatatype_format(rdata1.type,
+ typebuf,
+ sizeof(typebuf));
+ format = ISC_FALSE;
+ }
+ dns_zone_log(zone, level, "%s/%s has "
+ "semantically identical records",
+ ownerbuf, typebuf);
+ if (level == ISC_LOG_ERROR)
+ answer = ISC_FALSE;
+ break;
+ }
+ }
+ dns_rdataset_disassociate(&tmprdataset);
+ if (!format)
+ break;
+ }
+ return (answer);
+}
+
+static isc_boolean_t
+zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
+ dns_dbiterator_t *dbiterator = NULL;
+ dns_dbnode_t *node = NULL;
+ dns_fixedname_t fixed;
+ dns_name_t *name;
+ dns_rdataset_t rdataset;
+ dns_rdatasetiter_t *rdsit = NULL;
+ isc_boolean_t ok = ISC_TRUE;
+ isc_result_t result;
+
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+ dns_rdataset_init(&rdataset);
+
+ result = dns_db_createiterator(db, 0, &dbiterator);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_TRUE);
+
+ for (result = dns_dbiterator_first(dbiterator);
+ result == ISC_R_SUCCESS;
+ result = dns_dbiterator_next(dbiterator)) {
+ result = dns_dbiterator_current(dbiterator, &node, name);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ for (result = dns_rdatasetiter_first(rdsit);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsit)) {
+ dns_rdatasetiter_current(rdsit, &rdataset);
+ if (!zone_rrset_check_dup(zone, name, &rdataset))
+ ok = ISC_FALSE;
+ dns_rdataset_disassociate(&rdataset);
+ }
+ dns_rdatasetiter_destroy(&rdsit);
+ dns_db_detachnode(db, &node);
+ }
+
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ dns_dbiterator_destroy(&dbiterator);
+
+ return (ok);
+}
+
+static isc_boolean_t
integrity_checks(dns_zone_t *zone, dns_db_t *db) {
dns_dbiterator_t *dbiterator = NULL;
dns_dbnode_t *node = NULL;
@@ -2052,6 +2219,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) {
result = dns_rdataset_next(&rdataset);
}
dns_rdataset_disassociate(&rdataset);
+ goto next;
checkmx:
result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
@@ -2104,7 +2272,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) {
/*
* OpenSSL verification of RSA keys with exponent 3 is known to be
- * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
+ * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
* if they are in use.
*/
static void
@@ -2168,7 +2336,6 @@ zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
dns_db_detachnode(db, &node);
if (version != NULL)
dns_db_closeversion(db, &version, ISC_FALSE);
-
}
static void
@@ -2189,15 +2356,18 @@ resume_signingwithkey(dns_zone_t *zone) {
zone->privatetype,
dns_rdatatype_none, 0,
&rdataset, NULL);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
goto cleanup;
+ }
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset))
{
dns_rdataset_current(&rdataset, &rdata);
- if (rdata.length != 5 || rdata.data[4] != 0) {
+ if (rdata.length != 5 ||
+ rdata.data[0] == 0 || rdata.data[4] != 0) {
dns_rdata_reset(&rdata);
continue;
}
@@ -2219,7 +2389,6 @@ resume_signingwithkey(dns_zone_t *zone) {
dns_db_detachnode(zone->db, &node);
if (version != NULL)
dns_db_closeversion(zone->db, &version, ISC_FALSE);
-
}
static isc_result_t
@@ -2228,6 +2397,9 @@ zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
isc_result_t result;
isc_time_t now;
unsigned int options = 0;
+ char saltbuf[255*2+1];
+ char flags[sizeof("REMOVE|CREATE|NONSEC|OPTOUT")];
+ int i;
nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
if (nsec3chain == NULL)
@@ -2249,6 +2421,40 @@ zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
nsec3chain->delete_nsec = ISC_FALSE;
nsec3chain->save_delete_nsec = ISC_FALSE;
+ if (nsec3param->flags == 0)
+ strlcpy(flags, "NONE", sizeof(flags));
+ else {
+ flags[0] = '\0';
+ if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
+ strlcat(flags, "REMOVE", sizeof(flags));
+ if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
+ if (flags[0] == '\0')
+ strlcpy(flags, "CREATE", sizeof(flags));
+ else
+ strlcat(flags, "|CREATE", sizeof(flags));
+ }
+ if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
+ if (flags[0] == '\0')
+ strlcpy(flags, "NONSEC", sizeof(flags));
+ else
+ strlcat(flags, "|NONSEC", sizeof(flags));
+ }
+ if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
+ if (flags[0] == '\0')
+ strlcpy(flags, "OPTOUT", sizeof(flags));
+ else
+ strlcat(flags, "|OPTOUT", sizeof(flags));
+ }
+ }
+ if (nsec3param->salt_length == 0)
+ strlcpy(saltbuf, "-", sizeof(saltbuf));
+ else
+ for (i = 0; i < nsec3param->salt_length; i++)
+ sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
+ dns_zone_log(zone, ISC_LOG_INFO,
+ "zone_addnsec3chain(%u,%s,%u,%s)",
+ nsec3param->hash, flags, nsec3param->iterations,
+ saltbuf);
for (current = ISC_LIST_HEAD(zone->nsec3chain);
current != NULL;
current = ISC_LIST_NEXT(current, link)) {
@@ -2298,11 +2504,13 @@ static void
resume_addnsec3chain(dns_zone_t *zone) {
dns_dbnode_t *node = NULL;
dns_dbversion_t *version = NULL;
- dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_t rdataset;
isc_result_t result;
dns_rdata_nsec3param_t nsec3param;
+ if (zone->privatetype == 0)
+ return;
+
result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS)
goto cleanup;
@@ -2310,17 +2518,25 @@ resume_addnsec3chain(dns_zone_t *zone) {
dns_db_currentversion(zone->db, &version);
dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(zone->db, node, version,
- dns_rdatatype_nsec3param,
- dns_rdatatype_none, 0,
- &rdataset, NULL);
- if (result != ISC_R_SUCCESS)
+ zone->privatetype, dns_rdatatype_none,
+ 0, &rdataset, NULL);
+ if (result != ISC_R_SUCCESS) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
goto cleanup;
+ }
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset))
{
- dns_rdataset_current(&rdataset, &rdata);
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_t private = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&rdataset, &private);
+ if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
+ sizeof(buf)))
+ continue;
result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 ||
@@ -2332,10 +2548,8 @@ resume_addnsec3chain(dns_zone_t *zone) {
dns_result_totext(result));
}
}
- dns_rdata_reset(&rdata);
}
dns_rdataset_disassociate(&rdataset);
-
cleanup:
if (node != NULL)
dns_db_detachnode(zone->db, &node);
@@ -2353,8 +2567,8 @@ set_resigntime(dns_zone_t *zone) {
dns_rdataset_init(&rdataset);
dns_fixedname_init(&fixed);
- result = dns_db_getsigningtime(zone->db, &rdataset,
- dns_fixedname_name(&fixed));
+ result = dns_db_getsigningtime(zone->db, &rdataset,
+ dns_fixedname_name(&fixed));
if (result != ISC_R_SUCCESS) {
isc_time_settoepoch(&zone->resigntime);
return;
@@ -2392,10 +2606,12 @@ check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
dns_rdatatype_nsec3param,
dns_rdatatype_none, 0, &rdataset, NULL);
if (result == ISC_R_NOTFOUND) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
result = ISC_R_SUCCESS;
goto cleanup;
}
if (result != ISC_R_SUCCESS) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
dns_zone_log(zone, ISC_LOG_ERROR,
"nsec3param lookup failure: %s",
dns_result_totext(result));
@@ -2456,6 +2672,642 @@ check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
return (result);
}
+/*
+ * Set the timer for refreshing the key zone to the soonest future time
+ * of the set (current timer, keydata->refresh, keydata->addhd,
+ * keydata->removehd).
+ */
+static void
+set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
+ isc_stdtime_t now) {
+ const char me[] = "set_refreshkeytimer";
+ isc_stdtime_t then;
+ isc_time_t timenow, timethen;
+ char timebuf[80];
+
+ ENTER;
+ then = key->refresh;
+ if (key->addhd > now && key->addhd < then)
+ then = key->addhd;
+ if (key->removehd > now && key->removehd < then)
+ then = key->removehd;
+
+ TIME_NOW(&timenow);
+ if (then > now)
+ DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
+ else
+ timethen = timenow;
+ if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
+ isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
+ zone->refreshkeytime = timethen;
+
+ isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
+ dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
+ zone_settimer(zone, &timenow);
+}
+
+/*
+ * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
+ * If the key zone is changed, set '*changed' to ISC_TRUE.
+ */
+static isc_result_t
+create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
+ dns_diff_t *diff, dns_keytable_t *keytable,
+ dns_keynode_t **keynodep, isc_boolean_t *changed)
+{
+ const char me[] = "create_keydata";
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_buffer_t keyb, dstb;
+ unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
+ dns_rdata_keydata_t keydata;
+ dns_rdata_dnskey_t dnskey;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_keynode_t *keynode;
+ isc_stdtime_t now;
+ isc_region_t r;
+ dst_key_t *key;
+
+ REQUIRE(keynodep != NULL);
+ keynode = *keynodep;
+
+ ENTER;
+ isc_stdtime_get(&now);
+
+ /* Loop in case there's more than one key. */
+ while (result == ISC_R_SUCCESS) {
+ dns_keynode_t *nextnode = NULL;
+
+ key = dns_keynode_key(keynode);
+ if (key == NULL)
+ goto skip;
+
+ isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
+ CHECK(dst_key_todns(key, &dstb));
+
+ /* Convert DST key to DNSKEY. */
+ dns_rdata_reset(&rdata);
+ isc_buffer_usedregion(&dstb, &r);
+ dns_rdata_fromregion(&rdata, dst_key_class(key),
+ dns_rdatatype_dnskey, &r);
+
+ /* DSTKEY to KEYDATA. */
+ CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
+ CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
+ NULL));
+
+ /* KEYDATA to rdata. */
+ dns_rdata_reset(&rdata);
+ isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
+ CHECK(dns_rdata_fromstruct(&rdata,
+ zone->rdclass, dns_rdatatype_keydata,
+ &keydata, &keyb));
+
+ /* Add rdata to zone. */
+ CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
+ dst_key_name(key), 0, &rdata));
+ *changed = ISC_TRUE;
+
+ skip:
+ result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
+ if (result != ISC_R_NOTFOUND) {
+ dns_keytable_detachkeynode(keytable, &keynode);
+ keynode = nextnode;
+ }
+ }
+
+ /* Refresh new keys from the zone apex as soon as possible. */
+ if (*changed)
+ set_refreshkeytimer(zone, &keydata, now);
+
+ if (keynode != NULL)
+ dns_keytable_detachkeynode(keytable, &keynode);
+ *keynodep = NULL;
+
+ return (ISC_R_SUCCESS);
+
+ failure:
+ return (result);
+}
+
+/*
+ * Remove from the key zone all the KEYDATA records found in rdataset.
+ */
+static isc_result_t
+delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
+ dns_name_t *name, dns_rdataset_t *rdataset)
+{
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ isc_result_t result, uresult;
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_reset(&rdata);
+ dns_rdataset_current(rdataset, &rdata);
+ uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
+ name, 0, &rdata);
+ if (uresult != ISC_R_SUCCESS)
+ return (uresult);
+ }
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+ return (result);
+}
+
+/*
+ * Compute the DNSSEC key ID for a DNSKEY record.
+ */
+static isc_result_t
+compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
+ dns_keytag_t *tag)
+{
+ isc_result_t result;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ unsigned char data[4096];
+ isc_buffer_t buffer;
+ dst_key_t *dstkey = NULL;
+
+ isc_buffer_init(&buffer, data, sizeof(data));
+ dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
+ dns_rdatatype_dnskey, dnskey, &buffer);
+
+ result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
+ if (result == ISC_R_SUCCESS)
+ *tag = dst_key_id(dstkey);
+ dst_key_free(&dstkey);
+
+ return (result);
+}
+
+/*
+ * Add key to the security roots for all views.
+ */
+static void
+trust_key(dns_viewlist_t *viewlist, dns_name_t *keyname,
+ dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) {
+ isc_result_t result;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ unsigned char data[4096];
+ isc_buffer_t buffer;
+ dns_view_t *view;
+ dns_keytable_t *sr = NULL;
+ dst_key_t *dstkey = NULL;
+
+ /* Convert dnskey to DST key. */
+ isc_buffer_init(&buffer, data, sizeof(data));
+ dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
+ dns_rdatatype_dnskey, dnskey, &buffer);
+
+ for (view = ISC_LIST_HEAD(*viewlist); view != NULL;
+ view = ISC_LIST_NEXT(view, link)) {
+
+ result = dns_view_getsecroots(view, &sr);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
+ CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
+ dns_keytable_detach(&sr);
+ }
+
+ failure:
+ if (dstkey != NULL)
+ dst_key_free(&dstkey);
+ if (sr != NULL)
+ dns_keytable_detach(&sr);
+ return;
+}
+
+/*
+ * Remove key from the security roots for all views.
+ */
+static void
+untrust_key(dns_viewlist_t *viewlist, dns_name_t *keyname, isc_mem_t *mctx,
+ dns_rdata_dnskey_t *dnskey)
+{
+ dns_view_t *view;
+
+ for (view = ISC_LIST_HEAD(*viewlist); view != NULL;
+ view = ISC_LIST_NEXT(view, link))
+ dns_view_untrust(view, keyname, dnskey, mctx);
+}
+
+/*
+ * Add a null key to the security roots for all views, so that all queries
+ * to the zone will fail.
+ */
+static void
+fail_secure(dns_viewlist_t *viewlist, dns_name_t *keyname) {
+ isc_result_t result;
+ dns_view_t *view;
+
+ for (view = ISC_LIST_HEAD(*viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link)) {
+ dns_keytable_t *sr = NULL;
+
+ result = dns_view_getsecroots(view, &sr);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ dns_keytable_marksecure(sr, keyname);
+ dns_keytable_detach(&sr);
+ }
+}
+
+/*
+ * Scan a set of KEYDATA records from the key zone. The ones that are
+ * valid (i.e., the add holddown timer has expired) become trusted keys for
+ * all views.
+ */
+static void
+load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
+ isc_result_t result;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_keydata_t keydata;
+ dns_rdata_dnskey_t dnskey;
+ isc_mem_t *mctx = zone->mctx;
+ dns_view_t *view = zone->view;
+ dns_viewlist_t *viewlist = view->viewlist;
+ int trusted = 0, revoked = 0, pending = 0;
+ isc_stdtime_t now;
+
+ isc_stdtime_get(&now);
+
+ /* For each view, delete references to this key from secroots. */
+ for (view = ISC_LIST_HEAD(*viewlist); view != NULL;
+ view = ISC_LIST_NEXT(view, link)) {
+ dns_keytable_t *sr = NULL;
+
+ result = dns_view_getsecroots(view, &sr);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ dns_keytable_delete(sr, name);
+ dns_keytable_detach(&sr);
+ }
+
+ /* Now insert all the accepted trust anchors from this keydata set. */
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_reset(&rdata);
+ dns_rdataset_current(rdataset, &rdata);
+
+ /* Convert rdata to keydata. */
+ dns_rdata_tostruct(&rdata, &keydata, NULL);
+
+ /* Set the key refresh timer. */
+ set_refreshkeytimer(zone, &keydata, now);
+
+ /* If the removal timer is nonzero, this key was revoked. */
+ if (keydata.removehd != 0) {
+ revoked++;
+ continue;
+ }
+
+ /*
+ * If the add timer is still pending, this key is not
+ * trusted yet.
+ */
+ if (now < keydata.addhd) {
+ pending++;
+ continue;
+ }
+
+ /* Convert keydata to dnskey. */
+ dns_keydata_todnskey(&keydata, &dnskey, NULL);
+
+ /* Add to keytables. */
+ trusted++;
+ trust_key(viewlist, name, &dnskey, mctx);
+ }
+
+ if (trusted == 0 && pending != 0) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ dns_name_format(name, namebuf, sizeof namebuf);
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "No valid trust anchors for '%s'!", namebuf);
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "%d key(s) revoked, %d still pending",
+ revoked, pending);
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "All queries to '%s' will fail", namebuf);
+ fail_secure(viewlist, name);
+ }
+}
+
+static isc_result_t
+do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
+ dns_diff_t *diff)
+{
+ dns_diff_t temp_diff;
+ isc_result_t result;
+
+ /*
+ * Create a singleton diff.
+ */
+ dns_diff_init(diff->mctx, &temp_diff);
+ temp_diff.resign = diff->resign;
+ ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
+
+ /*
+ * Apply it to the database.
+ */
+ result = dns_diff_apply(&temp_diff, db, ver);
+ ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
+ if (result != ISC_R_SUCCESS) {
+ dns_difftuple_free(tuple);
+ return (result);
+ }
+
+ /*
+ * Merge it into the current pending journal entry.
+ */
+ dns_diff_appendminimal(diff, tuple);
+
+ /*
+ * Do not clear temp_diff.
+ */
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
+ dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
+ dns_rdata_t *rdata)
+{
+ dns_difftuple_t *tuple = NULL;
+ isc_result_t result;
+ result = dns_difftuple_create(diff->mctx, op,
+ name, ttl, rdata, &tuple);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ return (do_one_tuple(&tuple, db, ver, diff));
+}
+
+static isc_result_t
+increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
+ dns_diff_t *diff, isc_mem_t *mctx) {
+ dns_difftuple_t *deltuple = NULL;
+ dns_difftuple_t *addtuple = NULL;
+ isc_uint32_t serial;
+ isc_result_t result;
+
+ CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
+ CHECK(dns_difftuple_copy(deltuple, &addtuple));
+ addtuple->op = DNS_DIFFOP_ADD;
+
+ serial = dns_soa_getserial(&addtuple->rdata);
+
+ /* RFC1982 */
+ serial = (serial + 1) & 0xFFFFFFFF;
+ if (serial == 0)
+ serial = 1;
+
+ dns_soa_setserial(serial, &addtuple->rdata);
+ CHECK(do_one_tuple(&deltuple, db, ver, diff));
+ CHECK(do_one_tuple(&addtuple, db, ver, diff));
+ result = ISC_R_SUCCESS;
+
+ failure:
+ if (addtuple != NULL)
+ dns_difftuple_free(&addtuple);
+ if (deltuple != NULL)
+ dns_difftuple_free(&deltuple);
+ return (result);
+}
+
+/*
+ * Write all transactions in 'diff' to the zone journal file.
+ */
+static isc_result_t
+zone_journal(dns_zone_t *zone, dns_diff_t *diff, const char *caller) {
+ const char me[] = "zone_journal";
+ const char *journalfile;
+ isc_result_t result = ISC_R_SUCCESS;
+ dns_journal_t *journal = NULL;
+
+ ENTER;
+ journalfile = dns_zone_getjournal(zone);
+ if (journalfile != NULL) {
+ result = dns_journal_open(zone->mctx, journalfile,
+ ISC_TRUE, &journal);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "%s:dns_journal_open -> %s\n",
+ caller, dns_result_totext(result));
+ return (result);
+ }
+
+ result = dns_journal_write_transaction(journal, diff);
+ dns_journal_destroy(&journal);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "%s:dns_journal_write_transaction -> %s\n",
+ caller, dns_result_totext(result));
+ return (result);
+ }
+ }
+ return (result);
+}
+
+/*
+ * Create an SOA record for a newly-created zone
+ */
+static isc_result_t
+add_soa(dns_zone_t *zone, dns_db_t *db) {
+ isc_result_t result;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ unsigned char buf[DNS_SOA_BUFFERSIZE];
+ dns_dbversion_t *ver = NULL;
+ dns_diff_t diff;
+
+ dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
+
+ dns_diff_init(zone->mctx, &diff);
+ result = dns_db_newversion(db, &ver);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "add_soa:dns_db_newversion -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+
+ /* Build SOA record */
+ result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
+ 0, 0, 0, 0, 0, buf, &rdata);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "add_soa:dns_soa_buildrdata -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+
+ result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
+ &zone->origin, 0, &rdata);
+
+failure:
+ dns_diff_clear(&diff);
+ if (ver != NULL)
+ dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
+
+ return (result);
+}
+
+/*
+ * Synchronize the set of initializing keys found in managed-keys {}
+ * statements with the set of trust anchors found in the managed-keys.bind
+ * zone. If a domain is no longer named in managed-keys, delete all keys
+ * from that domain from the key zone. If a domain is mentioned in in
+ * managed-keys but there are no references to it in the key zone, load
+ * the key zone with the initializing key(s) for that domain.
+ */
+static isc_result_t
+sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_boolean_t changed = ISC_FALSE;
+ dns_rbtnodechain_t chain;
+ dns_fixedname_t fn;
+ dns_name_t foundname, *origin;
+ dns_keynode_t *keynode = NULL;
+ dns_view_t *view = zone->view;
+ dns_keytable_t *sr = NULL;
+ dns_dbversion_t *ver = NULL;
+ dns_diff_t diff;
+ dns_rriterator_t rrit;
+
+ dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
+
+ dns_name_init(&foundname, NULL);
+ dns_fixedname_init(&fn);
+ origin = dns_fixedname_name(&fn);
+
+ dns_diff_init(zone->mctx, &diff);
+
+ CHECK(dns_view_getsecroots(view, &sr));
+
+ result = dns_db_newversion(db, &ver);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "sync_keyzone:dns_db_newversion -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+
+ /*
+ * Walk the zone DB. If we find any keys whose names are no longer
+ * in managed-keys (or *are* in trusted-keys, meaning they are
+ * permanent and not RFC5011-maintained), delete them from the
+ * zone. Otherwise call load_secroots(), which loads keys into
+ * secroots as appropriate.
+ */
+ dns_rriterator_init(&rrit, db, ver, 0);
+ for (result = dns_rriterator_first(&rrit);
+ result == ISC_R_SUCCESS;
+ result = dns_rriterator_nextrrset(&rrit)) {
+ dns_rdataset_t *rdataset;
+ dns_name_t *rrname = NULL;
+ isc_uint32_t ttl;
+
+ dns_rriterator_current(&rrit, &rrname, &ttl,
+ &rdataset, NULL);
+ if (!dns_rdataset_isassociated(rdataset)) {
+ dns_rriterator_destroy(&rrit);
+ goto failure;
+ }
+
+ if (rdataset->type != dns_rdatatype_keydata)
+ continue;
+
+ result = dns_keytable_find(sr, rrname, &keynode);
+ if ((result != ISC_R_SUCCESS &&
+ result != DNS_R_PARTIALMATCH) ||
+ dns_keynode_managed(keynode) == ISC_FALSE) {
+ CHECK(delete_keydata(db, ver, &diff,
+ rrname, rdataset));
+ changed = ISC_TRUE;
+ } else {
+ load_secroots(zone, rrname, rdataset);
+ }
+
+ if (keynode != NULL)
+ dns_keytable_detachkeynode(sr, &keynode);
+ }
+ dns_rriterator_destroy(&rrit);
+
+ /*
+ * Now walk secroots to find any managed keys that aren't
+ * in the zone. If we find any, we add them to the zone.
+ */
+ RWLOCK(&sr->rwlock, isc_rwlocktype_write);
+ dns_rbtnodechain_init(&chain, zone->mctx);
+ result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
+ if (result == ISC_R_NOTFOUND)
+ result = ISC_R_NOMORE;
+ while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
+ dns_rbtnode_t *rbtnode = NULL;
+
+ dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
+ if (rbtnode->data == NULL)
+ goto skip;
+
+ dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
+ if (dns_keynode_managed(keynode)) {
+ dns_fixedname_t fname;
+ dns_name_t *keyname;
+ dst_key_t *key;
+
+ key = dns_keynode_key(keynode);
+ dns_fixedname_init(&fname);
+
+ if (key == NULL) /* fail_secure() was called. */
+ goto skip;
+
+ keyname = dst_key_name(key);
+ result = dns_db_find(db, keyname, ver,
+ dns_rdatatype_keydata,
+ DNS_DBFIND_NOWILD, 0, NULL,
+ dns_fixedname_name(&fname),
+ NULL, NULL);
+ if (result != ISC_R_SUCCESS)
+ result = create_keydata(zone, db, ver, &diff,
+ sr, &keynode, &changed);
+ if (result != ISC_R_SUCCESS)
+ break;
+ }
+ skip:
+ result = dns_rbtnodechain_next(&chain, &foundname, origin);
+ if (keynode != NULL)
+ dns_keytable_detachkeynode(sr, &keynode);
+ }
+ RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
+
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+
+ if (changed) {
+ /* Write changes to journal file. */
+ result = increment_soa_serial(db, ver, &diff, zone->mctx);
+ if (result == ISC_R_SUCCESS)
+ zone_journal(zone, &diff, "sync_keyzone");
+
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
+ zone_needdump(zone, 30);
+ }
+
+ failure:
+ if (keynode != NULL)
+ dns_keytable_detachkeynode(sr, &keynode);
+ if (sr != NULL)
+ dns_keytable_detach(&sr);
+ if (ver != NULL)
+ dns_db_closeversion(db, &ver, changed);
+ dns_diff_clear(&diff);
+
+ return (result);
+}
+
static isc_result_t
zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
isc_result_t result)
@@ -2467,6 +3319,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
isc_time_t now;
isc_boolean_t needdump = ISC_FALSE;
isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
+ isc_boolean_t nomaster = ISC_FALSE;
unsigned int options;
TIME_NOW(&now);
@@ -2488,12 +3341,16 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
"failed: %s",
zone->masterfile,
dns_result_totext(result));
- } else
+ } else {
dns_zone_log(zone, ISC_LOG_ERROR,
"loading from master file %s failed: %s",
zone->masterfile,
dns_result_totext(result));
- goto cleanup;
+ nomaster = ISC_TRUE;
+ }
+
+ if (zone->type != dns_zone_key)
+ goto cleanup;
}
dns_zone_log(zone, ISC_LOG_DEBUG(2),
@@ -2506,6 +3363,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
/*
+ * If there's no master file for a key zone, then the zone is new:
+ * create an SOA record. (We do this now, instead of later, so that
+ * if there happens to be a journal file, we can roll forward from
+ * a sane starting point.)
+ */
+ if (nomaster && zone->type == dns_zone_key) {
+ result = add_soa(zone, db);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ /*
* Apply update log, if any, on initial load.
*/
if (zone->journal != NULL &&
@@ -2552,7 +3421,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
&refresh, &retry, &expire, &minimum,
&errors);
- if (result != ISC_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
dns_zone_log(zone, ISC_LOG_ERROR,
"could not find NS and/or SOA records");
}
@@ -2563,6 +3432,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
*/
switch (zone->type) {
+ case dns_zone_dlz:
case dns_zone_master:
case dns_zone_slave:
case dns_zone_stub:
@@ -2594,6 +3464,13 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
goto cleanup;
}
+ if (zone->type == dns_zone_master &&
+ DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
+ !zone_check_dup(zone, db)) {
+ result = DNS_R_BADZONE;
+ goto cleanup;
+ }
+
if (zone->db != NULL) {
/*
* This is checked in zone_replacedb() for slave zones
@@ -2621,12 +3498,13 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
goto cleanup;
} else if (!isc_serial_ge(serial, oldserial))
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone serial has gone backwards");
+ "zone serial (%u/%u) has gone "
+ "backwards", serial, oldserial);
else if (serial == oldserial && !hasinclude)
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone serial unchanged. "
+ "zone serial (%u) unchanged. "
"zone may fail to transfer "
- "to slaves.");
+ "to slaves.", serial);
}
if (zone->type == dns_zone_master &&
@@ -2672,6 +3550,13 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
zone->refreshtime = now;
}
break;
+
+ case dns_zone_key:
+ result = sync_keyzone(zone, db);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ break;
+
default:
UNEXPECTED_ERROR(__FILE__, __LINE__,
"unexpected zone type %d", zone->type);
@@ -2685,6 +3570,13 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
if (zone->type == dns_zone_master)
zone_check_dnskeys(zone, db);
+ /*
+ * Schedule DNSSEC key refresh.
+ */
+ if (zone->type == dns_zone_master &&
+ DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
+ zone->refreshkeytime = now;
+
#if 0
/* destroy notification example. */
{
@@ -2709,9 +3601,16 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
DNS_ZONE_SETFLAG(zone,
DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
}
+
result = ISC_R_SUCCESS;
- if (needdump)
- zone_needdump(zone, DNS_DUMP_DELAY);
+
+ if (needdump) {
+ if (zone->type == dns_zone_key)
+ zone_needdump(zone, 30);
+ else
+ zone_needdump(zone, DNS_DUMP_DELAY);
+ }
+
if (zone->task != NULL) {
if (zone->type == dns_zone_master) {
set_resigntime(zone);
@@ -2723,13 +3622,14 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
if (! dns_db_ispersistent(db))
dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
- dns_db_issecure(db) ? " (signed)" : "");
+ dns_db_issecure(db) ? " (DNSSEC signed)" : "");
return (result);
cleanup:
if (zone->type == dns_zone_slave ||
- zone->type == dns_zone_stub) {
+ zone->type == dns_zone_stub ||
+ zone->type == dns_zone_key) {
if (zone->journal != NULL)
zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
if (zone->masterfile != NULL)
@@ -2763,7 +3663,9 @@ exit_check(dns_zone_t *zone) {
}
static isc_boolean_t
-zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
+zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
+ dns_name_t *name, isc_boolean_t logit)
+{
isc_result_t result;
char namebuf[DNS_NAME_FORMATSIZE];
char altbuf[DNS_NAME_FORMATSIZE];
@@ -2782,42 +3684,45 @@ zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
dns_fixedname_init(&fixed);
foundname = dns_fixedname_name(&fixed);
- result = dns_db_find(db, name, NULL, dns_rdatatype_a,
+ result = dns_db_find(db, name, version, dns_rdatatype_a,
0, 0, NULL, foundname, NULL, NULL);
if (result == ISC_R_SUCCESS)
return (ISC_TRUE);
if (result == DNS_R_NXRRSET) {
- result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
+ result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
0, 0, NULL, foundname, NULL, NULL);
if (result == ISC_R_SUCCESS)
return (ISC_TRUE);
}
- dns_name_format(name, namebuf, sizeof namebuf);
if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
result == DNS_R_EMPTYNAME) {
- dns_zone_log(zone, level,
- "NS '%s' has no address records (A or AAAA)",
- namebuf);
- /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
- return (ISC_TRUE);
+ if (logit) {
+ dns_name_format(name, namebuf, sizeof namebuf);
+ dns_zone_log(zone, level, "NS '%s' has no address "
+ "records (A or AAAA)", namebuf);
+ }
+ return (ISC_FALSE);
}
if (result == DNS_R_CNAME) {
- dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)",
- namebuf);
- /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
- return (ISC_TRUE);
+ if (logit) {
+ dns_name_format(name, namebuf, sizeof namebuf);
+ dns_zone_log(zone, level, "NS '%s' is a CNAME "
+ "(illegal)", namebuf);
+ }
+ return (ISC_FALSE);
}
if (result == DNS_R_DNAME) {
- dns_name_format(foundname, altbuf, sizeof altbuf);
- dns_zone_log(zone, level,
- "NS '%s' is below a DNAME '%s' (illegal)",
- namebuf, altbuf);
- /* XXX950 Make fatal ISC_FALSE for 9.5.0. */
- return (ISC_TRUE);
+ if (logit) {
+ dns_name_format(name, namebuf, sizeof namebuf);
+ dns_name_format(foundname, altbuf, sizeof altbuf);
+ dns_zone_log(zone, level, "NS '%s' is below a DNAME "
+ "'%s' (illegal)", namebuf, altbuf);
+ }
+ return (ISC_FALSE);
}
return (ISC_TRUE);
@@ -2826,7 +3731,7 @@ zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
static isc_result_t
zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
dns_dbversion_t *version, unsigned int *nscount,
- unsigned int *errors)
+ unsigned int *errors, isc_boolean_t logit)
{
isc_result_t result;
unsigned int count = 0;
@@ -2838,10 +3743,14 @@ zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
dns_rdatatype_none, 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND)
+ if (result == ISC_R_NOTFOUND) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
goto success;
- if (result != ISC_R_SUCCESS)
+ }
+ if (result != ISC_R_SUCCESS) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
goto invalidate_rdataset;
+ }
result = dns_rdataset_first(&rdataset);
while (result == ISC_R_SUCCESS) {
@@ -2853,7 +3762,7 @@ zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
result = dns_rdata_tostruct(&rdata, &ns, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (dns_name_issubdomain(&ns.name, &zone->origin) &&
- !zone_check_ns(zone, db, &ns.name))
+ !zone_check_ns(zone, db, version, &ns.name, logit))
ecount++;
}
count++;
@@ -2892,6 +3801,7 @@ zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
dns_rdatatype_none, 0, &rdataset, NULL);
if (result == ISC_R_NOTFOUND) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
if (soacount != NULL)
*soacount = 0;
if (serial != NULL)
@@ -2907,8 +3817,10 @@ zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
result = ISC_R_SUCCESS;
goto invalidate_rdataset;
}
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
goto invalidate_rdataset;
+ }
count = 0;
result = dns_rdataset_first(&rdataset);
@@ -2960,15 +3872,14 @@ zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
isc_uint32_t *expire, isc_uint32_t *minimum,
unsigned int *errors)
{
- dns_dbversion_t *version;
isc_result_t result;
isc_result_t answer = ISC_R_SUCCESS;
+ dns_dbversion_t *version = NULL;
dns_dbnode_t *node;
REQUIRE(db != NULL);
REQUIRE(zone != NULL);
- version = NULL;
dns_db_currentversion(db, &version);
node = NULL;
@@ -2980,7 +3891,7 @@ zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
if (nscount != NULL || errors != NULL) {
result = zone_count_ns_rr(zone, db, node, version,
- nscount, errors);
+ nscount, errors, ISC_TRUE);
if (result != ISC_R_SUCCESS)
answer = result;
}
@@ -3028,7 +3939,7 @@ dns_zone_detach(dns_zone_t **zonep) {
*/
if (zone->task != NULL) {
/*
- * This zone is being managed. Post
+ * This zone is being managed. Post
* its control event and let it clean
* up synchronously in the context of
* its task.
@@ -3163,6 +4074,27 @@ dns_zone_getoptions(dns_zone_t *zone) {
return (zone->options);
}
+void
+dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
+{
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ LOCK_ZONE(zone);
+ if (value)
+ zone->keyopts |= keyopt;
+ else
+ zone->keyopts &= ~keyopt;
+ UNLOCK_ZONE(zone);
+}
+
+unsigned int
+dns_zone_getkeyopts(dns_zone_t *zone) {
+
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ return (zone->keyopts);
+}
+
isc_result_t
dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
REQUIRE(DNS_ZONE_VALID(zone));
@@ -3499,6 +4431,17 @@ dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
return (result);
}
+void
+dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+ REQUIRE(zone->type == dns_zone_staticstub);
+
+ ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
+ REQUIRE(zone->db == NULL);
+ dns_db_attach(db, &zone->db);
+ ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
+}
+
/*
* Co-ordinates the starting of routine jobs.
*/
@@ -3535,126 +4478,6 @@ was_dumping(dns_zone_t *zone) {
#define MAXZONEKEYS 10
static isc_result_t
-do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
- dns_diff_t *diff)
-{
- dns_diff_t temp_diff;
- isc_result_t result;
-
- /*
- * Create a singleton diff.
- */
- dns_diff_init(diff->mctx, &temp_diff);
- temp_diff.resign = diff->resign;
- ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
-
- /*
- * Apply it to the database.
- */
- result = dns_diff_apply(&temp_diff, db, ver);
- ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
- if (result != ISC_R_SUCCESS) {
- dns_difftuple_free(tuple);
- return (result);
- }
-
- /*
- * Merge it into the current pending journal entry.
- */
- dns_diff_appendminimal(diff, tuple);
-
- /*
- * Do not clear temp_diff.
- */
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
- dns_diff_t *diff, isc_mem_t *mctx)
-{
- dns_difftuple_t *deltuple = NULL;
- dns_difftuple_t *addtuple = NULL;
- isc_uint32_t serial;
- isc_result_t result;
-
- CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
- CHECK(dns_difftuple_copy(deltuple, &addtuple));
- addtuple->op = DNS_DIFFOP_ADD;
-
- serial = dns_soa_getserial(&addtuple->rdata);
-
- /* RFC1982 */
- serial = (serial + 1) & 0xFFFFFFFF;
- if (serial == 0)
- serial = 1;
-
- dns_soa_setserial(serial, &addtuple->rdata);
- CHECK(do_one_tuple(&deltuple, db, ver, diff));
- CHECK(do_one_tuple(&addtuple, db, ver, diff));
- result = ISC_R_SUCCESS;
-
- failure:
- if (addtuple != NULL)
- dns_difftuple_free(&addtuple);
- if (deltuple != NULL)
- dns_difftuple_free(&deltuple);
- return (result);
-}
-
-static isc_result_t
-update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
- dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
- dns_rdata_t *rdata)
-{
- dns_difftuple_t *tuple = NULL;
- isc_result_t result;
- result = dns_difftuple_create(diff->mctx, op,
- name, ttl, rdata, &tuple);
- if (result != ISC_R_SUCCESS)
- return (result);
- return (do_one_tuple(&tuple, db, ver, diff));
-}
-
-static isc_boolean_t
-ksk_sanity(dns_db_t *db, dns_dbversion_t *ver) {
- isc_boolean_t ret = ISC_FALSE;
- isc_boolean_t have_ksk = ISC_FALSE, have_nonksk = ISC_FALSE;
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_dnskey_t dnskey;
-
- dns_rdataset_init(&rdataset);
- CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
- CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0,
- &rdataset, NULL));
- CHECK(dns_rdataset_first(&rdataset));
- while (result == ISC_R_SUCCESS && (!have_ksk || !have_nonksk)) {
- dns_rdataset_current(&rdataset, &rdata);
- CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
- if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
- == DNS_KEYOWNER_ZONE) {
- if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0)
- have_ksk = ISC_TRUE;
- else
- have_nonksk = ISC_TRUE;
- }
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(&rdataset);
- }
- if (have_ksk && have_nonksk)
- ret = ISC_TRUE;
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (ret);
-}
-
-static isc_result_t
find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
isc_mem_t *mctx, unsigned int maxkeys,
dst_key_t **keys, unsigned int *nkeys)
@@ -3752,10 +4575,14 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
(isc_stdtime_t) 0, &rdataset, NULL);
dns_db_detachnode(db, &node);
- if (result == ISC_R_NOTFOUND)
+ if (result == ISC_R_NOTFOUND) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
+ }
+ if (result != ISC_R_SUCCESS) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
goto failure;
+ }
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
@@ -3841,7 +4668,8 @@ static isc_result_t
add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
- isc_stdtime_t expire, isc_boolean_t check_ksk)
+ isc_stdtime_t expire, isc_boolean_t check_ksk,
+ isc_boolean_t keyset_kskonly)
{
isc_result_t result;
dns_dbnode_t *node = NULL;
@@ -3849,7 +4677,7 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_rdata_t sig_rdata = DNS_RDATA_INIT;
unsigned char data[1024]; /* XXX */
isc_buffer_t buffer;
- unsigned int i;
+ unsigned int i, j;
dns_rdataset_init(&rdataset);
isc_buffer_init(&buffer, data, sizeof(data));
@@ -3865,18 +4693,59 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
result = dns_db_findrdataset(db, node, ver, type, 0,
(isc_stdtime_t) 0, &rdataset, NULL);
dns_db_detachnode(db, &node);
- if (result == ISC_R_NOTFOUND)
+ if (result == ISC_R_NOTFOUND) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
+ }
+ if (result != ISC_R_SUCCESS) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
goto failure;
+ }
+
+#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
+#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
+#define ALG(x) dst_key_alg(x)
for (i = 0; i < nkeys; i++) {
- if (check_ksk && type != dns_rdatatype_dnskey &&
- (dst_key_flags(keys[i]) & DNS_KEYFLAG_KSK) != 0)
- continue;
+ isc_boolean_t both = ISC_FALSE;
+
if (!dst_key_isprivate(keys[i]))
continue;
+
+ if (check_ksk && !REVOKE(keys[i])) {
+ isc_boolean_t have_ksk, have_nonksk;
+ if (KSK(keys[i])) {
+ have_ksk = ISC_TRUE;
+ have_nonksk = ISC_FALSE;
+ } else {
+ have_ksk = ISC_FALSE;
+ have_nonksk = ISC_TRUE;
+ }
+ for (j = 0; j < nkeys; j++) {
+ if (j == i || ALG(keys[i]) != ALG(keys[j]))
+ continue;
+ if (REVOKE(keys[j]))
+ continue;
+ if (KSK(keys[j]))
+ have_ksk = ISC_TRUE;
+ else
+ have_nonksk = ISC_TRUE;
+ both = have_ksk && have_nonksk;
+ if (both)
+ break;
+ }
+ }
+ if (both) {
+ if (type == dns_rdatatype_dnskey) {
+ if (!KSK(keys[i]) && keyset_kskonly)
+ continue;
+ } else if (KSK(keys[i]))
+ continue;
+ } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
+ continue;
+
/* Calculate the signature, creating a RRSIG RDATA. */
+ isc_buffer_clear(&buffer);
CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
&inception, &expire,
mctx, &buffer, &sig_rdata));
@@ -3898,7 +4767,6 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
static void
zone_resigninc(dns_zone_t *zone) {
- const char *journalfile;
dns_db_t *db = NULL;
dns_dbversion_t *version = NULL;
dns_diff_t sig_diff;
@@ -3907,7 +4775,7 @@ zone_resigninc(dns_zone_t *zone) {
dns_rdataset_t rdataset;
dns_rdatatype_t covers;
dst_key_t *zone_keys[MAXZONEKEYS];
- isc_boolean_t check_ksk;
+ isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
isc_result_t result;
isc_stdtime_t now, inception, soaexpire, expire, stop;
isc_uint32_t jitter;
@@ -3962,8 +4830,7 @@ zone_resigninc(dns_zone_t *zone) {
stop = now + 5;
check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
- if (check_ksk)
- check_ksk = ksk_sanity(db, version);
+ keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
name = dns_fixedname_name(&fixed);
result = dns_db_getsigningtime(db, &rdataset, name);
@@ -4007,14 +4874,14 @@ zone_resigninc(dns_zone_t *zone) {
}
result = add_sigs(db, version, name, covers, &sig_diff,
zone_keys, nkeys, zone->mctx, inception,
- expire, check_ksk);
+ expire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_resigninc:add_sigs -> %s\n",
dns_result_totext(result));
break;
}
- result = dns_db_getsigningtime(db, &rdataset,
+ result = dns_db_getsigningtime(db, &rdataset,
dns_fixedname_name(&fixed));
if (nkeys == 0 && result == ISC_R_NOTFOUND) {
result = ISC_R_SUCCESS;
@@ -4052,7 +4919,7 @@ zone_resigninc(dns_zone_t *zone) {
*/
result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
&sig_diff, zone_keys, nkeys, zone->mctx, inception,
- soaexpire, check_ksk);
+ soaexpire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_resigninc:add_sigs -> %s\n",
@@ -4060,31 +4927,10 @@ zone_resigninc(dns_zone_t *zone) {
goto failure;
}
- journalfile = dns_zone_getjournal(zone);
- if (journalfile != NULL) {
- dns_journal_t *journal = NULL;
- result = dns_journal_open(zone->mctx, journalfile,
- ISC_TRUE, &journal);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:dns_journal_open -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
-
- result = dns_journal_write_transaction(journal, &sig_diff);
- dns_journal_destroy(&journal);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:dns_journal_write_transaction -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
- }
+ /* Write changes to journal file. */
+ zone_journal(zone, &sig_diff, "zone_resigninc");
- /*
- * Everything has succeeded. Commit the changes.
- */
+ /* Everything has succeeded. Commit the changes. */
dns_db_closeversion(db, &version, ISC_TRUE);
failure:
@@ -4151,16 +4997,6 @@ next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
return (result);
}
-static void
-set_bit(unsigned char *array, unsigned int index) {
- unsigned int shift, mask;
-
- shift = 7 - (index % 8);
- mask = 1 << shift;
-
- array[index / 8] |= mask;
-}
-
static isc_boolean_t
signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, dst_key_t *key)
@@ -4173,8 +5009,10 @@ signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
type, 0, &rdataset, NULL);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
return (ISC_FALSE);
+ }
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
@@ -4209,21 +5047,6 @@ add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
CHECK(next_active(db, version, name, next, bottom));
CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
&rdata));
- if (dns_name_equal(dns_db_origin(db), name)) {
- /*
- * Set the OPT bit to indicate that this is a
- * partially secure zone.
- */
- isc_region_t region;
-
- dns_rdata_toregion(&rdata, &region);
- dns_name_fromregion(next, &region);
- isc_region_consume(&region, next->length);
- INSIST(region.length > (2 + dns_rdatatype_opt / 8) &&
- region.base[0] == 0 &&
- region.base[1] > dns_rdatatype_opt / 8);
- set_bit(region.base + 2, dns_rdatatype_opt);
- }
CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
&rdata));
failure:
@@ -4236,8 +5059,8 @@ sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
isc_boolean_t build_nsec, dst_key_t *key,
isc_stdtime_t inception, isc_stdtime_t expire,
unsigned int minimum, isc_boolean_t is_ksk,
- isc_boolean_t *delegation, dns_diff_t *diff,
- isc_int32_t *signatures, isc_mem_t *mctx)
+ isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
+ dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
{
isc_result_t result;
dns_rdatasetiter_t *iterator = NULL;
@@ -4255,6 +5078,7 @@ sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
result = ISC_R_SUCCESS;
return (result);
}
+
dns_rdataset_init(&rdataset);
isc_buffer_init(&buffer, data, sizeof(data));
seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
@@ -4275,7 +5099,8 @@ sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
seen_nsec = ISC_TRUE;
else if (rdataset.type == dns_rdatatype_nsec3)
seen_nsec3 = ISC_TRUE;
- seen_rr = ISC_TRUE;
+ if (rdataset.type != dns_rdatatype_rrsig)
+ seen_rr = ISC_TRUE;
dns_rdataset_disassociate(&rdataset);
}
if (result != ISC_R_NOMORE)
@@ -4299,9 +5124,15 @@ sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
/* Build and add NSEC. */
bottom = (seen_ns && !seen_soa) || seen_dname;
- CHECK(add_nsec(db, version, name, node, minimum, bottom, diff));
- /* Count a NSEC generation as a signature generation. */
- (*signatures)--;
+ /*
+ * Build a NSEC record except at the origin.
+ */
+ if (!dns_name_equal(name, dns_db_origin(db))) {
+ CHECK(add_nsec(db, version, name, node, minimum,
+ bottom, diff));
+ /* Count a NSEC generation as a signature generation. */
+ (*signatures)--;
+ }
}
result = dns_rdatasetiter_first(iterator);
while (result == ISC_R_SUCCESS) {
@@ -4309,7 +5140,10 @@ sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
if (rdataset.type == dns_rdatatype_soa ||
rdataset.type == dns_rdatatype_rrsig)
goto next_rdataset;
- if (is_ksk && rdataset.type != dns_rdatatype_dnskey)
+ if (rdataset.type == dns_rdatatype_dnskey) {
+ if (!is_ksk && keyset_kskonly)
+ goto next_rdataset;
+ } else if (is_ksk)
goto next_rdataset;
if (*delegation &&
rdataset.type != dns_rdatatype_ds &&
@@ -4318,6 +5152,7 @@ sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
if (signed_with_key(db, node, version, rdataset.type, key))
goto next_rdataset;
/* Calculate the signature, creating a RRSIG RDATA. */
+ isc_buffer_clear(&buffer);
CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
&expire, mctx, &buffer, &rdata));
/* Update the database and journal with the RRSIG. */
@@ -4334,7 +5169,7 @@ sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
result = ISC_R_SUCCESS;
if (seen_dname)
*delegation = ISC_TRUE;
-failure:
+ failure:
if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset);
if (iterator != NULL)
@@ -4342,63 +5177,45 @@ failure:
return (result);
}
+/*
+ * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
+ */
static isc_result_t
updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
- dns_ttl_t minimum, isc_boolean_t *secureupdated, dns_diff_t *diff)
+ dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
{
isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
dns_rdataset_t rdataset;
- dns_rdata_nsec_t nsec;
dns_dbnode_t *node = NULL;
- /*
- * Check to see if the OPT bit has already been cleared.
- */
CHECK(dns_db_getoriginnode(db, &node));
- dns_rdataset_init(&rdataset);
- CHECK(dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
- dns_rdatatype_none, 0, &rdataset, NULL));
- CHECK(dns_rdataset_first(&rdataset));
- dns_rdataset_current(&rdataset, &rdata);
-
- /*
- * Find the NEXT name for building the new record.
- */
- CHECK(dns_rdata_tostruct(&rdata, &nsec, NULL));
-
- /*
- * Delete the old NSEC record.
- */
- CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_DEL, name, minimum,
- &rdata));
- dns_rdata_reset(&rdata);
-
- /*
- * Add the new NSEC record.
- */
- CHECK(dns_nsec_buildrdata(db, version, node, &nsec.next, nsecbuffer,
- &rdata));
- CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, minimum,
- &rdata));
- dns_rdata_reset(&rdata);
-
- if (secureupdated != NULL)
- *secureupdated = ISC_TRUE;
-
+ if (update_only) {
+ dns_rdataset_init(&rdataset);
+ result = dns_db_findrdataset(db, node, version,
+ dns_rdatatype_nsec,
+ dns_rdatatype_none,
+ 0, &rdataset, NULL);
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (result == ISC_R_NOTFOUND)
+ goto success;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+ }
+ CHECK(delete_nsec(db, version, node, name, diff));
+ CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
+ success:
+ result = ISC_R_SUCCESS;
failure:
if (node != NULL)
dns_db_detachnode(db, &node);
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
return (result);
}
static isc_result_t
-updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
- dns_name_t *name, dns_rdatatype_t privatetype,
- dns_diff_t *diff)
+updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
+ dns_dbversion_t *version, isc_boolean_t build_nsec3,
+ dns_ttl_t minimum, dns_diff_t *diff)
{
isc_result_t result;
dns_dbnode_t *node = NULL;
@@ -4406,43 +5223,68 @@ updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
dns_rdata_t rdata = DNS_RDATA_INIT;
unsigned char data[5];
isc_boolean_t seen_done = ISC_FALSE;
+ isc_boolean_t have_rr = ISC_FALSE;
dns_rdataset_init(&rdataset);
result = dns_db_getoriginnode(signing->db, &node);
if (result != ISC_R_SUCCESS)
goto failure;
- result = dns_db_findrdataset(signing->db, node, version, privatetype,
- dns_rdatatype_none, 0, &rdataset, NULL);
+ result = dns_db_findrdataset(signing->db, node, version,
+ zone->privatetype, dns_rdatatype_none,
+ 0, &rdataset, NULL);
if (result == ISC_R_NOTFOUND) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
result = ISC_R_SUCCESS;
goto failure;
}
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ INSIST(!dns_rdataset_isassociated(&rdataset));
goto failure;
+ }
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
dns_rdataset_current(&rdataset, &rdata);
+ /*
+ * If we don't match the algorithm or keyid skip the record.
+ */
if (rdata.length != 5 ||
rdata.data[0] != signing->algorithm ||
rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
rdata.data[2] != (signing->keyid & 0xff)) {
+ have_rr = ISC_TRUE;
dns_rdata_reset(&rdata);
continue;
}
- if (!signing->delete && rdata.data[4] != 0)
+ /*
+ * We have a match. If we were signing (!signing->delete)
+ * and we already have a record indicating that we have
+ * finished signing (rdata.data[4] != 0) then keep it.
+ * Otherwise it needs to be deleted as we have removed all
+ * the signatures (signing->delete), so any record indicating
+ * completion is now out of date, or we have finished signing
+ * with the new record so we no longer need to remember that
+ * we need to sign the zone with the matching key across a
+ * nameserver re-start.
+ */
+ if (!signing->delete && rdata.data[4] != 0) {
seen_done = ISC_TRUE;
- else
+ have_rr = ISC_TRUE;
+ } else
CHECK(update_one_rr(signing->db, version, diff,
- DNS_DIFFOP_DEL, name,
+ DNS_DIFFOP_DEL, &zone->origin,
rdataset.ttl, &rdata));
dns_rdata_reset(&rdata);
}
if (result == ISC_R_NOMORE)
result = ISC_R_SUCCESS;
if (!signing->delete && !seen_done) {
-
+ /*
+ * If we were signing then we need to indicate that we have
+ * finished signing the zone with this key. If it is already
+ * there we don't need to add it a second time.
+ */
data[0] = signing->algorithm;
data[1] = (signing->keyid >> 8) & 0xff;
data[2] = signing->keyid & 0xff;
@@ -4450,11 +5292,23 @@ updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
data[4] = 1;
rdata.length = sizeof(data);
rdata.data = data;
- rdata.type = privatetype;
+ rdata.type = zone->privatetype;
rdata.rdclass = dns_db_class(signing->db);
CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
- name, rdataset.ttl, &rdata));
+ &zone->origin, rdataset.ttl, &rdata));
+ } else if (!have_rr) {
+ dns_name_t *origin = dns_db_origin(signing->db);
+ /*
+ * Rebuild the NSEC/NSEC3 record for the origin as we no
+ * longer have any private records.
+ */
+ if (build_nsec3)
+ CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
+ minimum, ISC_FALSE, diff));
+ CHECK(updatesecure(signing->db, version, origin, minimum,
+ ISC_TRUE, diff));
}
+
failure:
if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset);
@@ -4463,9 +5317,15 @@ updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
return (result);
}
+/*
+ * If 'active' is set then we are not done with the chain yet so only
+ * delete the nsec3param record which indicates a full chain exists
+ * (flags == 0).
+ */
static isc_result_t
fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
- isc_boolean_t active, dns_diff_t *diff)
+ isc_boolean_t active, dns_rdatatype_t privatetype,
+ dns_diff_t *diff)
{
dns_dbnode_t *node = NULL;
dns_name_t *name = dns_db_origin(db);
@@ -4484,7 +5344,7 @@ fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
0, 0, &rdataset, NULL);
if (result == ISC_R_NOTFOUND)
- goto add;
+ goto try_private;
if (result != ISC_R_SUCCESS)
goto failure;
@@ -4520,6 +5380,50 @@ fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
if (result != ISC_R_NOMORE)
goto failure;
+ dns_rdataset_disassociate(&rdataset);
+
+ try_private:
+
+ if (active)
+ goto add;
+ /*
+ * Delete all private records which match that in nsec3chain.
+ */
+ result = dns_db_findrdataset(db, node, ver, privatetype,
+ 0, 0, &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ goto add;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t private = DNS_RDATA_INIT;
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+
+ dns_rdataset_current(&rdataset, &private);
+ if (!dns_nsec3param_fromprivate(&private, &rdata,
+ buf, sizeof(buf)))
+ continue;
+ CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
+
+ if (nsec3param.hash != chain->nsec3param.hash ||
+ nsec3param.iterations != chain->nsec3param.iterations ||
+ nsec3param.salt_length != chain->nsec3param.salt_length ||
+ memcmp(nsec3param.salt, chain->nsec3param.salt,
+ nsec3param.salt_length)) {
+ dns_rdata_reset(&rdata);
+ continue;
+ }
+
+ CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
+ name, rdataset.ttl, &private));
+ dns_rdata_reset(&rdata);
+ }
+ if (result != ISC_R_NOMORE)
+ goto failure;
+
add:
if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
result = ISC_R_SUCCESS;
@@ -4620,7 +5524,7 @@ deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
static isc_result_t
need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
const dns_rdata_nsec3param_t *param,
- isc_boolean_t *answer, isc_boolean_t *updatensec)
+ isc_boolean_t *answer)
{
dns_dbnode_t *node = NULL;
dns_rdata_t rdata = DNS_RDATA_INIT;
@@ -4634,29 +5538,19 @@ need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_rdataset_init(&rdataset);
+
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
0, 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND)
- goto check_nsec3param;
-
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- CHECK(dns_rdataset_first(&rdataset));
- dns_rdataset_current(&rdataset, &rdata);
-
- if (!dns_nsec_typepresent(&rdata, dns_rdatatype_opt)) {
- /*
- * We have a complete NSEC chain. Signal to update
- * the apex NSEC record.
- */
- *updatensec = ISC_TRUE;
- goto failure;
+ if (result == ISC_R_SUCCESS) {
+ dns_rdataset_disassociate(&rdataset);
+ dns_db_detachnode(db, &node);
+ return (result);
+ }
+ if (result != ISC_R_NOTFOUND) {
+ dns_db_detachnode(db, &node);
+ return (result);
}
- dns_rdataset_disassociate(&rdataset);
- dns_rdata_reset(&rdata);
- check_nsec3param:
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
0, 0, &rdataset, NULL);
if (result == ISC_R_NOTFOUND) {
@@ -4705,13 +5599,60 @@ need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
return (result);
}
+static isc_result_t
+update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
+ dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
+ isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
+ isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
+ dns_diff_t *sig_diff)
+{
+ dns_difftuple_t *tuple;
+ isc_result_t result;
+
+ for (tuple = ISC_LIST_HEAD(diff->tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_HEAD(diff->tuples)) {
+ result = del_sigs(zone, db, version, &tuple->name,
+ tuple->rdata.type, sig_diff,
+ zone_keys, nkeys, now);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "update_sigs:del_sigs -> %s\n",
+ dns_result_totext(result));
+ return (result);
+ }
+ result = add_sigs(db, version, &tuple->name,
+ tuple->rdata.type, sig_diff,
+ zone_keys, nkeys, zone->mctx, inception,
+ expire, check_ksk, keyset_kskonly);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "update_sigs:add_sigs -> %s\n",
+ dns_result_totext(result));
+ return (result);
+ }
+
+ do {
+ dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
+ while (next != NULL &&
+ (tuple->rdata.type != next->rdata.type ||
+ !dns_name_equal(&tuple->name, &next->name)))
+ next = ISC_LIST_NEXT(next, link);
+ ISC_LIST_UNLINK(diff->tuples, tuple, link);
+ dns_diff_appendminimal(sig_diff, &tuple);
+ INSIST(tuple == NULL);
+ tuple = next;
+ } while (tuple != NULL);
+ }
+ return (ISC_R_SUCCESS);
+}
+
/*
* Incrementally build and sign a new NSEC3 chain using the parameters
* requested.
*/
static void
zone_nsec3chain(dns_zone_t *zone) {
- const char *journalfile;
dns_db_t *db = NULL;
dns_dbnode_t *node = NULL;
dns_dbversion_t *version = NULL;
@@ -4727,7 +5668,7 @@ zone_nsec3chain(dns_zone_t *zone) {
dns_nsec3chainlist_t cleanup;
dst_key_t *zone_keys[MAXZONEKEYS];
isc_int32_t signatures;
- isc_boolean_t check_ksk, is_ksk;
+ isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
isc_boolean_t delegation;
isc_boolean_t first;
isc_result_t result;
@@ -4740,9 +5681,9 @@ zone_nsec3chain(dns_zone_t *zone) {
isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
dns_rdatasetiter_t *iterator = NULL;
- dns_difftuple_t *tuple;
isc_boolean_t buildnsecchain;
isc_boolean_t updatensec = ISC_FALSE;
+ dns_rdatatype_t privatetype = zone->privatetype;
dns_rdataset_init(&rdataset);
dns_fixedname_init(&fixed);
@@ -4799,8 +5740,7 @@ zone_nsec3chain(dns_zone_t *zone) {
stop = now + 5;
check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
- if (check_ksk)
- check_ksk = ksk_sanity(db, version);
+ keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
/*
* We keep pulling nodes off each iterator in turn until
@@ -4924,9 +5864,17 @@ zone_nsec3chain(dns_zone_t *zone) {
* Process one node.
*/
dns_dbiterator_pause(nsec3chain->dbiterator);
- CHECK(dns_nsec3_addnsec3(db, version, name,
- &nsec3chain->nsec3param,
- zone->minimum, unsecure, &nsec3_diff));
+ result = dns_nsec3_addnsec3(db, version, name,
+ &nsec3chain->nsec3param,
+ zone->minimum, unsecure,
+ &nsec3_diff);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
+ "dns_nsec3_addnsec3 -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+
/*
* Treat each call to dns_nsec3_addnsec3() as if it's cost is
* two signatures. Additionally there will, in general, be
@@ -4948,7 +5896,8 @@ zone_nsec3chain(dns_zone_t *zone) {
if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
CHECK(fixup_nsec3param(db, version, nsec3chain,
- ISC_FALSE, &param_diff));
+ ISC_FALSE, privatetype,
+ &param_diff));
LOCK_ZONE(zone);
ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
link);
@@ -4962,12 +5911,14 @@ zone_nsec3chain(dns_zone_t *zone) {
CHECK(fixup_nsec3param(db, version,
nsec3chain,
ISC_TRUE,
+ privatetype,
&param_diff));
nsec3chain->delete_nsec = ISC_TRUE;
goto same_addchain;
}
CHECK(fixup_nsec3param(db, version, nsec3chain,
- ISC_FALSE, &param_diff));
+ ISC_FALSE, privatetype,
+ &param_diff));
LOCK_ZONE(zone);
ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
link);
@@ -5028,10 +5979,22 @@ zone_nsec3chain(dns_zone_t *zone) {
* of removing this NSEC3 chain.
*/
if (first && !updatensec &&
- (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
- CHECK(need_nsec_chain(db, version,
- &nsec3chain->nsec3param,
- &buildnsecchain, &updatensec));
+ (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) {
+ result = need_nsec_chain(db, version,
+ &nsec3chain->nsec3param,
+ &buildnsecchain);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone_nsec3chain:"
+ "need_nsec_chain -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+ }
+
+ if (first)
+ dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
+ "buildnsecchain = %u\n", buildnsecchain);
dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
delegation = ISC_FALSE;
@@ -5040,16 +6003,33 @@ zone_nsec3chain(dns_zone_t *zone) {
/*
* Delete the NSECPARAM record that matches this chain.
*/
- if (first)
- CHECK(fixup_nsec3param(db, version, nsec3chain,
- ISC_TRUE, &param_diff));
+ if (first) {
+ result = fixup_nsec3param(db, version,
+ nsec3chain,
+ ISC_TRUE, privatetype,
+ &param_diff);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone_nsec3chain:"
+ "fixup_nsec3param -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+ }
/*
* Delete the NSEC3 records.
*/
- CHECK(deletematchingnsec3(db, version, node, name,
- &nsec3chain->nsec3param,
- &nsec3_diff));
+ result = deletematchingnsec3(db, version, node, name,
+ &nsec3chain->nsec3param,
+ &nsec3_diff);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone_nsec3chain:"
+ "deletematchingnsec3 -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
goto next_removenode;
}
@@ -5100,7 +6080,8 @@ zone_nsec3chain(dns_zone_t *zone) {
seen_nsec = ISC_TRUE;
else if (rdataset.type == dns_rdatatype_nsec3)
seen_nsec3 = ISC_TRUE;
- seen_rr = ISC_TRUE;
+ if (rdataset.type != dns_rdatatype_rrsig)
+ seen_rr = ISC_TRUE;
dns_rdataset_disassociate(&rdataset);
}
dns_rdatasetiter_destroy(&iterator);
@@ -5110,8 +6091,14 @@ zone_nsec3chain(dns_zone_t *zone) {
if ((seen_ns && !seen_soa) || seen_dname)
delegation = ISC_TRUE;
- CHECK(add_nsec(db, version, name, node, zone->minimum,
- delegation, &nsec_diff));
+ /*
+ * Add a NSEC record except at the origin.
+ */
+ if (!dns_name_equal(name, dns_db_origin(db))) {
+ dns_dbiterator_pause(nsec3chain->dbiterator);
+ CHECK(add_nsec(db, version, name, node, zone->minimum,
+ delegation, &nsec_diff));
+ }
next_removenode:
first = ISC_FALSE;
@@ -5133,8 +6120,17 @@ zone_nsec3chain(dns_zone_t *zone) {
UNLOCK_ZONE(zone);
ISC_LIST_APPEND(cleanup, nsec3chain, link);
dns_dbiterator_pause(nsec3chain->dbiterator);
- CHECK(fixup_nsec3param(db, version, nsec3chain,
- ISC_FALSE, &param_diff));
+ result = fixup_nsec3param(db, version,
+ nsec3chain, ISC_FALSE,
+ privatetype,
+ &param_diff);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone_nsec3chain:"
+ "fixup_nsec3param -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
goto next_removechain;
} else if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
@@ -5166,107 +6162,101 @@ zone_nsec3chain(dns_zone_t *zone) {
}
/*
- * Add / update signatures for the NSEC3 records.
+ * We may need to update the NSEC/NSEC3 records for the zone apex.
*/
- for (tuple = ISC_LIST_HEAD(nsec3_diff.tuples);
- tuple != NULL;
- tuple = ISC_LIST_HEAD(nsec3_diff.tuples)) {
- /*
- * We have changed the NSEC3 RRset above so we need to update
- * the signatures.
- */
- result = del_sigs(zone, db, version, &tuple->name,
- dns_rdatatype_nsec3, &sig_diff,
- zone_keys, nkeys, now);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:del_sigs -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
- result = add_sigs(db, version, &tuple->name,
- dns_rdatatype_nsec3, &sig_diff, zone_keys,
- nkeys, zone->mctx, inception, expire,
- check_ksk);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:add_sigs -> %s\n",
- dns_result_totext(result));
- goto failure;
+ if (!ISC_LIST_EMPTY(param_diff.tuples)) {
+ isc_boolean_t rebuild_nsec = ISC_FALSE,
+ rebuild_nsec3 = ISC_FALSE;
+ result = dns_db_getoriginnode(db, &node);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ result = dns_db_allrdatasets(db, node, version, 0, &iterator);
+ for (result = dns_rdatasetiter_first(iterator);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(iterator)) {
+ dns_rdatasetiter_current(iterator, &rdataset);
+ if (rdataset.type == dns_rdatatype_nsec)
+ rebuild_nsec = ISC_TRUE;
+ if (rdataset.type == dns_rdatatype_nsec3param)
+ rebuild_nsec3 = ISC_TRUE;
+ dns_rdataset_disassociate(&rdataset);
}
+ dns_rdatasetiter_destroy(&iterator);
+ dns_db_detachnode(db, &node);
- do {
- dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
- while (next != NULL &&
- !dns_name_equal(&tuple->name, &next->name))
- next = ISC_LIST_NEXT(next, link);
- ISC_LIST_UNLINK(nsec3_diff.tuples, tuple, link);
- dns_diff_appendminimal(&sig_diff, &tuple);
- INSIST(tuple == NULL);
- tuple = next;
- } while (tuple != NULL);
- }
-
- for (tuple = ISC_LIST_HEAD(param_diff.tuples);
- tuple != NULL;
- tuple = ISC_LIST_HEAD(param_diff.tuples)) {
- /*
- * We have changed the NSEC3PARAM RRset above so we need to
- * update the signatures.
- */
- result = del_sigs(zone, db, version, &tuple->name,
- dns_rdatatype_nsec3param, &sig_diff,
- zone_keys, nkeys, now);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:del_sigs -> %s\n",
- dns_result_totext(result));
- goto failure;
+ if (rebuild_nsec) {
+ if (nsec3chain != NULL)
+ dns_dbiterator_pause(nsec3chain->dbiterator);
+ result = updatesecure(db, version, &zone->origin,
+ zone->minimum, ISC_TRUE,
+ &nsec_diff);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone_nsec3chain:"
+ "updatesecure -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
}
- result = add_sigs(db, version, &tuple->name,
- dns_rdatatype_nsec3param, &sig_diff,
- zone_keys, nkeys, zone->mctx, inception,
- expire, check_ksk);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:add_sigs -> %s\n",
- dns_result_totext(result));
- goto failure;
+ if (rebuild_nsec3) {
+ result = dns_nsec3_addnsec3s(db, version,
+ dns_db_origin(db),
+ zone->minimum, ISC_FALSE,
+ &nsec3_diff);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone_nsec3chain:"
+ "dns_nsec3_addnsec3s -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
}
- ISC_LIST_UNLINK(param_diff.tuples, tuple, link);
- dns_diff_appendminimal(&sig_diff, &tuple);
- INSIST(tuple == NULL);
}
- if (updatensec)
- CHECK(updatesecure(db, version, &zone->origin, zone->minimum,
- NULL, &nsec_diff));
+ /*
+ * Add / update signatures for the NSEC3 records.
+ */
+ result = update_sigs(&nsec3_diff, db, version, zone_keys,
+ nkeys, zone, inception, expire, now,
+ check_ksk, keyset_kskonly, &sig_diff);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
+ "update_sigs -> %s\n", dns_result_totext(result));
+ goto failure;
+ }
- for (tuple = ISC_LIST_HEAD(nsec_diff.tuples);
- tuple != NULL;
- tuple = ISC_LIST_HEAD(nsec_diff.tuples)) {
- result = del_sigs(zone, db, version, &tuple->name,
- dns_rdatatype_nsec, &sig_diff,
- zone_keys, nkeys, now);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:del_sigs -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
- result = add_sigs(db, version, &tuple->name,
- dns_rdatatype_nsec, &sig_diff,
- zone_keys, nkeys, zone->mctx, inception,
- expire, check_ksk);
+ /*
+ * We have changed the NSEC3PARAM or private RRsets
+ * above so we need to update the signatures.
+ */
+ result = update_sigs(&param_diff, db, version, zone_keys,
+ nkeys, zone, inception, expire, now,
+ check_ksk, keyset_kskonly, &sig_diff);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
+ "update_sigs -> %s\n", dns_result_totext(result));
+ goto failure;
+ }
+
+ if (updatensec) {
+ if (nsec3chain != NULL)
+ dns_dbiterator_pause(nsec3chain->dbiterator);
+ result = updatesecure(db, version, &zone->origin,
+ zone->minimum, ISC_FALSE, &nsec_diff);
if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:add_sigs -> %s\n",
+ dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
+ "updatesecure -> %s\n",
dns_result_totext(result));
goto failure;
}
- ISC_LIST_UNLINK(nsec_diff.tuples, tuple, link);
- dns_diff_appendminimal(&sig_diff, &tuple);
- INSIST(tuple == NULL);
+ }
+
+ result = update_sigs(&nsec_diff, db, version, zone_keys,
+ nkeys, zone, inception, expire, now,
+ check_ksk, keyset_kskonly, &sig_diff);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
+ "update_sigs -> %s\n", dns_result_totext(result));
+ goto failure;
}
/*
@@ -5294,34 +6284,15 @@ zone_nsec3chain(dns_zone_t *zone) {
result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
&sig_diff, zone_keys, nkeys, zone->mctx, inception,
- soaexpire, check_ksk);
+ soaexpire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
"add_sigs -> %s\n", dns_result_totext(result));
goto failure;
}
- journalfile = dns_zone_getjournal(zone);
- if (journalfile != NULL) {
- dns_journal_t *journal = NULL;
- result = dns_journal_open(zone->mctx, journalfile,
- ISC_TRUE, &journal);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "dns_journal_open -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
-
- result = dns_journal_write_transaction(journal, &sig_diff);
- dns_journal_destroy(&journal);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "dns_journal_write_transaction -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
- }
+ /* Write changes to journal file. */
+ zone_journal(zone, &sig_diff, "zone_nsec3chain");
LOCK_ZONE(zone);
zone_needdump(zone, DNS_DUMP_DELAY);
@@ -5358,6 +6329,9 @@ zone_nsec3chain(dns_zone_t *zone) {
set_resigntime(zone);
failure:
+ if (result != ISC_R_SUCCESS)
+ dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s\n",
+ dns_result_totext(result));
/*
* On error roll back the current nsec3chain.
*/
@@ -5414,6 +6388,8 @@ zone_nsec3chain(dns_zone_t *zone) {
for (i = 0; i < nkeys; i++)
dst_key_free(&zone_keys[i]);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
if (version != NULL) {
dns_db_closeversion(db, &version, ISC_FALSE);
dns_db_detach(&db);
@@ -5506,11 +6482,11 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
*/
static void
zone_sign(dns_zone_t *zone) {
- const char *journalfile;
dns_db_t *db = NULL;
dns_dbnode_t *node = NULL;
dns_dbversion_t *version = NULL;
dns_diff_t sig_diff;
+ dns_diff_t post_diff;
dns_fixedname_t fixed;
dns_fixedname_t nextfixed;
dns_name_t *name, *nextname;
@@ -5519,19 +6495,19 @@ zone_sign(dns_zone_t *zone) {
dns_signinglist_t cleanup;
dst_key_t *zone_keys[MAXZONEKEYS];
isc_int32_t signatures;
- isc_boolean_t check_ksk, is_ksk;
+ isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
isc_boolean_t commit = ISC_FALSE;
isc_boolean_t delegation;
- isc_boolean_t finishedakey = ISC_FALSE;
- isc_boolean_t secureupdated = ISC_FALSE;
- isc_boolean_t build_nsec3 = ISC_FALSE, build_nsec = ISC_FALSE;
+ isc_boolean_t build_nsec = ISC_FALSE;
+ isc_boolean_t build_nsec3 = ISC_FALSE;
isc_boolean_t first;
isc_result_t result;
isc_stdtime_t now, inception, soaexpire, expire, stop;
isc_uint32_t jitter;
- unsigned int i;
+ unsigned int i, j;
unsigned int nkeys = 0;
isc_uint32_t nodes;
+ isc_boolean_t was_ksk;
dns_rdataset_init(&rdataset);
dns_fixedname_init(&fixed);
@@ -5540,6 +6516,7 @@ zone_sign(dns_zone_t *zone) {
nextname = dns_fixedname_name(&nextfixed);
dns_diff_init(zone->mctx, &sig_diff);
sig_diff.resign = zone->sigresigninginterval;
+ dns_diff_init(zone->mctx, &post_diff);
ISC_LIST_INIT(cleanup);
/*
@@ -5584,10 +6561,6 @@ zone_sign(dns_zone_t *zone) {
expire = soaexpire - jitter % 3600;
stop = now + 5;
- check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
- if (check_ksk)
- check_ksk = ksk_sanity(db, version);
-
/*
* We keep pulling nodes off each iterator in turn until
* we have no more nodes to pull off or we reach the limits
@@ -5597,39 +6570,17 @@ zone_sign(dns_zone_t *zone) {
signatures = zone->signatures;
signing = ISC_LIST_HEAD(zone->signing);
first = ISC_TRUE;
- /*
- * See if we have a NSEC chain.
- */
- result = dns_db_getoriginnode(db, &node);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
- dns_rdatatype_none, 0, &rdataset, NULL);
- dns_db_detachnode(db, &node);
- if (result == ISC_R_SUCCESS) {
+
+ check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
+ keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
+
+ /* Determine which type of chain to build */
+ CHECK(dns_private_chains(db, version, zone->privatetype,
+ &build_nsec, &build_nsec3));
+
+ /* If neither chain is found, default to NSEC */
+ if (!build_nsec && !build_nsec3)
build_nsec = ISC_TRUE;
- dns_rdataset_disassociate(&rdataset);
- } else if (result != ISC_R_NOTFOUND) {
- goto failure;
- } else {
- /*
- * No NSEC chain present.
- * See if we need to build a NSEC3 chain?
- */
- result = dns_nsec3_active(db, version, ISC_TRUE, &build_nsec3);
- if (result == ISC_R_SUCCESS) {
- if (build_nsec3)
- build_nsec3 = ISC_FALSE;
- else {
- result = dns_nsec3_active(db, version,
- ISC_FALSE,
- &build_nsec3);
- if (build_nsec3)
- secureupdated = ISC_TRUE;
- else
- build_nsec = ISC_TRUE;
- }
- }
- }
while (signing != NULL && nodes-- > 0 && signatures > 0) {
nextsigning = ISC_LIST_NEXT(signing, link);
@@ -5637,7 +6588,7 @@ zone_sign(dns_zone_t *zone) {
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
if (signing->done || signing->db != zone->db) {
/*
- * The zone has been reloaded. We will have
+ * The zone has been reloaded. We will have
* created new signings as part of the reload
* process so we can destroy this one.
*/
@@ -5651,9 +6602,31 @@ zone_sign(dns_zone_t *zone) {
if (signing->db != db)
goto next_signing;
- is_ksk = ISC_FALSE;
delegation = ISC_FALSE;
+ was_ksk = ISC_FALSE;
+
+ if (first && signing->delete) {
+ /*
+ * Remove the key we are deleting from consideration.
+ */
+ for (i = 0, j = 0; i < nkeys; i++) {
+ /*
+ * Find the key we want to remove.
+ */
+ if (ALG(zone_keys[i]) == signing->algorithm &&
+ dst_key_id(zone_keys[i]) == signing->keyid)
+ {
+ if (KSK(zone_keys[i]))
+ dst_key_free(&zone_keys[i]);
+ continue;
+ }
+ zone_keys[j] = zone_keys[i];
+ j++;
+ }
+ nkeys = j;
+ }
+
dns_dbiterator_current(signing->dbiterator, &node, name);
if (signing->delete) {
@@ -5661,8 +6634,8 @@ zone_sign(dns_zone_t *zone) {
CHECK(del_sig(db, version, name, node, nkeys,
signing->algorithm, signing->keyid,
&sig_diff));
- goto next_node;
}
+
/*
* On the first pass we need to check if the current node
* has not been obscured.
@@ -5694,26 +6667,77 @@ zone_sign(dns_zone_t *zone) {
*/
dns_dbiterator_pause(signing->dbiterator);
for (i = 0; i < nkeys; i++) {
+ isc_boolean_t both = ISC_FALSE;
+
+ /*
+ * Find the keys we want to sign with.
+ */
+ if (!dst_key_isprivate(zone_keys[i]))
+ continue;
+
+ /*
+ * When adding look for the specific key.
+ */
+ if (!signing->delete &&
+ (dst_key_alg(zone_keys[i]) != signing->algorithm ||
+ dst_key_id(zone_keys[i]) != signing->keyid))
+ continue;
+
/*
- * Find the key we want to sign with.
+ * When deleting make sure we are properly signed
+ * with the algorithm that was being removed.
*/
- if (dst_key_alg(zone_keys[i]) != signing->algorithm ||
- dst_key_id(zone_keys[i]) != signing->keyid ||
- !dst_key_isprivate(zone_keys[i]))
+ if (signing->delete &&
+ ALG(zone_keys[i]) != signing->algorithm)
continue;
+
/*
* Do we do KSK processing?
*/
- if (check_ksk &&
- (dst_key_flags(zone_keys[i]) & DNS_KEYFLAG_KSK) != 0)
- is_ksk = ISC_TRUE;
+ if (check_ksk && !REVOKE(zone_keys[i])) {
+ isc_boolean_t have_ksk, have_nonksk;
+ if (KSK(zone_keys[i])) {
+ have_ksk = ISC_TRUE;
+ have_nonksk = ISC_FALSE;
+ } else {
+ have_ksk = ISC_FALSE;
+ have_nonksk = ISC_TRUE;
+ }
+ for (j = 0; j < nkeys; j++) {
+ if (j == i ||
+ ALG(zone_keys[i]) !=
+ ALG(zone_keys[j]))
+ continue;
+ if (REVOKE(zone_keys[j]))
+ continue;
+ if (KSK(zone_keys[j]))
+ have_ksk = ISC_TRUE;
+ else
+ have_nonksk = ISC_TRUE;
+ both = have_ksk && have_nonksk;
+ if (both)
+ break;
+ }
+ }
+ if (both || REVOKE(zone_keys[i]))
+ is_ksk = KSK(zone_keys[i]);
+ else
+ is_ksk = ISC_FALSE;
+
CHECK(sign_a_node(db, name, node, version, build_nsec3,
build_nsec, zone_keys[i], inception,
expire, zone->minimum, is_ksk,
- &delegation, &sig_diff, &signatures,
- zone->mctx));
- break;
+ ISC_TF(both && keyset_kskonly),
+ &delegation, &sig_diff,
+ &signatures, zone->mctx));
+ /*
+ * If we are adding we are done. Look for other keys
+ * of the same algorithm if deleting.
+ */
+ if (!signing->delete)
+ break;
}
+
/*
* Go onto next node.
*/
@@ -5726,9 +6750,7 @@ zone_sign(dns_zone_t *zone) {
ISC_LIST_UNLINK(zone->signing, signing, link);
ISC_LIST_APPEND(cleanup, signing, link);
dns_dbiterator_pause(signing->dbiterator);
- finishedakey = ISC_TRUE;
- if (!is_ksk && !secureupdated && nkeys != 0 &&
- build_nsec) {
+ if (nkeys != 0 && build_nsec) {
/*
* We have finished regenerating the
* zone with a zone signing key.
@@ -5740,8 +6762,8 @@ zone_sign(dns_zone_t *zone) {
result = updatesecure(db, version,
&zone->origin,
zone->minimum,
- &secureupdated,
- &sig_diff);
+ ISC_FALSE,
+ &post_diff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone,
ISC_LOG_ERROR,
@@ -5750,16 +6772,19 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
}
- result = updatesignwithkey(signing, version,
- &zone->origin,
- zone->privatetype,
- &sig_diff);
+ result = updatesignwithkey(zone, signing,
+ version,
+ build_nsec3,
+ zone->minimum,
+ &post_diff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "updatesignwithkey -> %s\n",
+ "updatesignwithkey "
+ "-> %s\n",
dns_result_totext(result));
goto failure;
}
+ build_nsec = ISC_FALSE;
goto next_signing;
} else if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
@@ -5783,53 +6808,13 @@ zone_sign(dns_zone_t *zone) {
first = ISC_TRUE;
}
- if (secureupdated) {
- /*
- * We have changed the NSEC RRset above so we need to update
- * the signatures.
- */
- result = del_sigs(zone, db, version, &zone->origin,
- dns_rdatatype_nsec, &sig_diff, zone_keys,
- nkeys, now);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:del_sigs -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
- result = add_sigs(db, version, &zone->origin,
- dns_rdatatype_nsec, &sig_diff, zone_keys,
- nkeys, zone->mctx, inception, soaexpire,
- check_ksk);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:add_sigs -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
- }
-
- if (finishedakey) {
- /*
- * We have changed the RRset above so we need to update
- * the signatures.
- */
- result = del_sigs(zone, db, version, &zone->origin,
- zone->privatetype, &sig_diff,
- zone_keys, nkeys, now);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:del_sigs -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
- result = add_sigs(db, version, &zone->origin,
- zone->privatetype, &sig_diff,
- zone_keys, nkeys, zone->mctx, inception,
- soaexpire, check_ksk);
+ if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
+ result = update_sigs(&post_diff, db, version, zone_keys,
+ nkeys, zone, inception, expire, now,
+ check_ksk, keyset_kskonly, &sig_diff);
if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:add_sigs -> %s\n",
+ dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
+ "update_sigs -> %s\n",
dns_result_totext(result));
goto failure;
}
@@ -5838,8 +6823,10 @@ zone_sign(dns_zone_t *zone) {
/*
* Have we changed anything?
*/
- if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
+ if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) {
+ result = ISC_R_SUCCESS;
goto pauseall;
+ }
commit = ISC_TRUE;
@@ -5866,7 +6853,7 @@ zone_sign(dns_zone_t *zone) {
*/
result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
&sig_diff, zone_keys, nkeys, zone->mctx, inception,
- soaexpire, check_ksk);
+ soaexpire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_sign:add_sigs -> %s\n",
@@ -5877,27 +6864,9 @@ zone_sign(dns_zone_t *zone) {
/*
* Write changes to journal file.
*/
- journalfile = dns_zone_getjournal(zone);
- if (journalfile != NULL) {
- dns_journal_t *journal = NULL;
- result = dns_journal_open(zone->mctx, journalfile,
- ISC_TRUE, &journal);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:dns_journal_open -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
-
- result = dns_journal_write_transaction(journal, &sig_diff);
- dns_journal_destroy(&journal);
- if (result != ISC_R_SUCCESS) {
- dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:dns_journal_write_transaction -> %s\n",
- dns_result_totext(result));
- goto failure;
- }
- }
+ result = zone_journal(zone, &sig_diff, "zone_sign");
+ if (result != ISC_R_SUCCESS)
+ goto failure;
pauseall:
/*
@@ -5934,6 +6903,7 @@ zone_sign(dns_zone_t *zone) {
if (commit) {
LOCK_ZONE(zone);
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
zone_needdump(zone, DNS_DUMP_DELAY);
UNLOCK_ZONE(zone);
}
@@ -5945,7 +6915,7 @@ zone_sign(dns_zone_t *zone) {
signing = ISC_LIST_HEAD(cleanup);
while (signing != NULL) {
ISC_LIST_UNLINK(cleanup, signing, link);
- ISC_LIST_APPEND(zone->signing, signing, link);
+ ISC_LIST_PREPEND(zone->signing, signing, link);
dns_dbiterator_first(signing->dbiterator);
dns_dbiterator_pause(signing->dbiterator);
signing = ISC_LIST_HEAD(cleanup);
@@ -5961,6 +6931,9 @@ zone_sign(dns_zone_t *zone) {
for (i = 0; i < nkeys; i++)
dst_key_free(&zone_keys[i]);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+
if (version != NULL) {
dns_db_closeversion(db, &version, ISC_FALSE);
dns_db_detach(&db);
@@ -5979,6 +6952,832 @@ zone_sign(dns_zone_t *zone) {
}
static void
+normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
+ unsigned char *data, int size) {
+ dns_rdata_dnskey_t dnskey;
+ dns_rdata_keydata_t keydata;
+ isc_buffer_t buf;
+
+ dns_rdata_reset(target);
+ isc_buffer_init(&buf, data, size);
+
+ switch (rr->type) {
+ case dns_rdatatype_dnskey:
+ dns_rdata_tostruct(rr, &dnskey, NULL);
+ dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
+ dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
+ &dnskey, &buf);
+ break;
+ case dns_rdatatype_keydata:
+ dns_rdata_tostruct(rr, &keydata, NULL);
+ dns_keydata_todnskey(&keydata, &dnskey, NULL);
+ dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
+ &dnskey, &buf);
+ break;
+ default:
+ INSIST(0);
+ }
+}
+
+/*
+ * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
+ * a KEYDATA rdataset from the key zone.
+ *
+ * 'rr' contains either a DNSKEY record, or a KEYDATA record
+ *
+ * After normalizing keys to the same format (DNSKEY, with revoke bit
+ * cleared), return ISC_TRUE if a key that matches 'rr' is found in
+ * 'rdset', or ISC_FALSE if not.
+ */
+
+static isc_boolean_t
+matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
+ unsigned char data1[4096], data2[4096];
+ dns_rdata_t rdata, rdata1, rdata2;
+ isc_result_t result;
+
+ dns_rdata_init(&rdata);
+ dns_rdata_init(&rdata1);
+ dns_rdata_init(&rdata2);
+
+ normalize_key(rr, &rdata1, data1, sizeof(data1));
+
+ for (result = dns_rdataset_first(rdset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdset)) {
+ dns_rdata_reset(&rdata);
+ dns_rdataset_current(rdset, &rdata);
+ normalize_key(&rdata, &rdata2, data2, sizeof(data2));
+ if (dns_rdata_compare(&rdata1, &rdata2) == 0)
+ return (ISC_TRUE);
+ }
+
+ return (ISC_FALSE);
+}
+
+/*
+ * Calculate the refresh interval for a keydata zone, per
+ * RFC5011: MAX(1 hr,
+ * MIN(15 days,
+ * 1/2 * OrigTTL,
+ * 1/2 * RRSigExpirationInterval))
+ * or for retries: MAX(1 hr,
+ * MIN(1 day,
+ * 1/10 * OrigTTL,
+ * 1/10 * RRSigExpirationInterval))
+ */
+static inline isc_stdtime_t
+refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
+ isc_result_t result;
+ isc_uint32_t t;
+ dns_rdataset_t *rdset;
+ dns_rdata_t sigrr = DNS_RDATA_INIT;
+ dns_rdata_sig_t sig;
+ isc_stdtime_t now;
+
+ isc_stdtime_get(&now);
+
+ if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
+ rdset = &kfetch->dnskeysigset;
+ else
+ return (now + HOUR);
+
+ result = dns_rdataset_first(rdset);
+ if (result != ISC_R_SUCCESS)
+ return (now + HOUR);
+
+ dns_rdataset_current(rdset, &sigrr);
+ result = dns_rdata_tostruct(&sigrr, &sig, NULL);
+
+ if (!retry) {
+ t = sig.originalttl / 2;
+
+ if (isc_serial_gt(sig.timeexpire, now)) {
+ isc_uint32_t exp = (sig.timeexpire - now) / 2;
+ if (t > exp)
+ t = exp;
+ }
+
+ if (t > (15*DAY))
+ t = (15*DAY);
+
+ if (t < HOUR)
+ t = HOUR;
+ } else {
+ t = sig.originalttl / 10;
+
+ if (isc_serial_gt(sig.timeexpire, now)) {
+ isc_uint32_t exp = (sig.timeexpire - now) / 10;
+ if (t > exp)
+ t = exp;
+ }
+
+ if (t > DAY)
+ t = DAY;
+
+ if (t < HOUR)
+ t = HOUR;
+ }
+
+ return (now + t);
+}
+
+/*
+ * This routine is called when no changes are needed in a KEYDATA
+ * record except to simply update the refresh timer. Caller should
+ * hold zone lock.
+ */
+static isc_result_t
+minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
+{
+ isc_result_t result;
+ isc_buffer_t keyb;
+ unsigned char key_buf[4096];
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_keydata_t keydata;
+ dns_name_t *name;
+ dns_zone_t *zone = kfetch->zone;
+ isc_stdtime_t now;
+
+ name = dns_fixedname_name(&kfetch->name);
+ isc_stdtime_get(&now);
+
+ for (result = dns_rdataset_first(&kfetch->keydataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&kfetch->keydataset)) {
+ dns_rdata_reset(&rdata);
+ dns_rdataset_current(&kfetch->keydataset, &rdata);
+
+ /* Delete old version */
+ CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
+ name, 0, &rdata));
+
+ /* Update refresh timer */
+ CHECK(dns_rdata_tostruct(&rdata, &keydata, NULL));
+ keydata.refresh = refresh_time(kfetch, ISC_TRUE);
+ set_refreshkeytimer(zone, &keydata, now);
+
+ dns_rdata_reset(&rdata);
+ isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
+ CHECK(dns_rdata_fromstruct(&rdata,
+ zone->rdclass, dns_rdatatype_keydata,
+ &keydata, &keyb));
+
+ /* Insert updated version */
+ CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
+ name, 0, &rdata));
+ }
+ result = ISC_R_SUCCESS;
+ failure:
+ return (result);
+}
+
+/*
+ * Verify that DNSKEY set is signed by the key specified in 'keydata'.
+ */
+static isc_boolean_t
+revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
+ isc_result_t result;
+ dns_name_t *keyname;
+ isc_mem_t *mctx;
+ dns_rdata_t sigrr = DNS_RDATA_INIT;
+ dns_rdata_t rr = DNS_RDATA_INIT;
+ dns_rdata_rrsig_t sig;
+ dns_rdata_dnskey_t dnskey;
+ dst_key_t *dstkey = NULL;
+ unsigned char key_buf[4096];
+ isc_buffer_t keyb;
+ isc_boolean_t answer = ISC_FALSE;
+
+ REQUIRE(kfetch != NULL && keydata != NULL);
+ REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
+
+ keyname = dns_fixedname_name(&kfetch->name);
+ mctx = kfetch->zone->view->mctx;
+
+ /* Generate a key from keydata */
+ isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
+ dns_keydata_todnskey(keydata, &dnskey, NULL);
+ dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
+ &dnskey, &keyb);
+ result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+
+ /* See if that key generated any of the signatures */
+ for (result = dns_rdataset_first(&kfetch->dnskeysigset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&kfetch->dnskeysigset)) {
+ dns_fixedname_t fixed;
+ dns_fixedname_init(&fixed);
+
+ dns_rdata_reset(&sigrr);
+ dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
+ result = dns_rdata_tostruct(&sigrr, &sig, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ if (dst_key_alg(dstkey) == sig.algorithm &&
+ (dst_key_id(dstkey) == sig.keyid ||
+ (sig.algorithm != 1 && sig.keyid ==
+ ((dst_key_id(dstkey) + 128) & 0xffff)))) {
+ result = dns_dnssec_verify2(keyname,
+ &kfetch->dnskeyset,
+ dstkey, ISC_FALSE, mctx, &sigrr,
+ dns_fixedname_name(&fixed));
+
+ dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
+ "Confirm revoked DNSKEY is self-signed: "
+ "%s", dns_result_totext(result));
+
+ if (result == ISC_R_SUCCESS) {
+ answer = ISC_TRUE;
+ break;
+ }
+ }
+ }
+
+ dst_key_free(&dstkey);
+ return (answer);
+}
+
+/*
+ * A DNSKEY set has been fetched from the zone apex of a zone whose trust
+ * anchors are being managed; scan the keyset, and update the key zone and the
+ * local trust anchors according to RFC5011.
+ */
+static void
+keyfetch_done(isc_task_t *task, isc_event_t *event) {
+ isc_result_t result, eresult;
+ dns_fetchevent_t *devent;
+ dns_keyfetch_t *kfetch;
+ dns_zone_t *zone;
+ isc_mem_t *mctx = NULL;
+ dns_keytable_t *secroots = NULL;
+ dns_dbversion_t *ver = NULL;
+ dns_diff_t diff;
+ isc_boolean_t changed = ISC_FALSE;
+ isc_boolean_t alldone = ISC_FALSE;
+ dns_name_t *keyname;
+ dns_rdata_t sigrr = DNS_RDATA_INIT;
+ dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
+ dns_rdata_t keydatarr = DNS_RDATA_INIT;
+ dns_rdata_rrsig_t sig;
+ dns_rdata_dnskey_t dnskey;
+ dns_rdata_keydata_t keydata;
+ isc_boolean_t initializing;
+ char namebuf[DNS_NAME_FORMATSIZE];
+ unsigned char key_buf[4096];
+ isc_buffer_t keyb;
+ dst_key_t *dstkey;
+ isc_stdtime_t now;
+ int pending = 0;
+ isc_boolean_t secure;
+
+ UNUSED(task);
+ INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
+ INSIST(event->ev_arg != NULL);
+
+ kfetch = event->ev_arg;
+ zone = kfetch->zone;
+ isc_mem_attach(zone->mctx, &mctx);
+ keyname = dns_fixedname_name(&kfetch->name);
+
+ devent = (dns_fetchevent_t *) event;
+ eresult = devent->result;
+
+ /* Free resources which are not of interest */
+ if (devent->node != NULL)
+ dns_db_detachnode(devent->db, &devent->node);
+ if (devent->db != NULL)
+ dns_db_detach(&devent->db);
+ isc_event_free(&event);
+ dns_resolver_destroyfetch(&kfetch->fetch);
+
+ isc_stdtime_get(&now);
+ dns_name_format(keyname, namebuf, sizeof(namebuf));
+
+ result = dns_view_getsecroots(zone->view, &secroots);
+ INSIST(result == ISC_R_SUCCESS);
+
+ LOCK_ZONE(zone);
+ dns_db_newversion(kfetch->db, &ver);
+ dns_diff_init(mctx, &diff);
+
+ zone->refreshkeycount--;
+ alldone = ISC_TF(zone->refreshkeycount == 0);
+
+ if (alldone)
+ DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
+
+ /* Fetch failed */
+ if (eresult != ISC_R_SUCCESS ||
+ !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
+ dns_zone_log(zone, ISC_LOG_WARNING,
+ "Unable to fetch DNSKEY set "
+ "'%s': %s", namebuf, dns_result_totext(eresult));
+ CHECK(minimal_update(kfetch, ver, &diff));
+ changed = ISC_TRUE;
+ goto failure;
+ }
+
+ /* No RRSIGs found */
+ if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
+ dns_zone_log(zone, ISC_LOG_WARNING,
+ "No DNSKEY RRSIGs found for "
+ "'%s': %s", namebuf, dns_result_totext(eresult));
+ CHECK(minimal_update(kfetch, ver, &diff));
+ changed = ISC_TRUE;
+ goto failure;
+ }
+
+ /*
+ * Validate the dnskeyset against the current trusted keys.
+ */
+ for (result = dns_rdataset_first(&kfetch->dnskeysigset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&kfetch->dnskeysigset)) {
+ dns_keynode_t *keynode = NULL;
+
+ dns_rdata_reset(&sigrr);
+ dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
+ result = dns_rdata_tostruct(&sigrr, &sig, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ result = dns_keytable_find(secroots, keyname, &keynode);
+ while (result == ISC_R_SUCCESS) {
+ dns_keynode_t *nextnode = NULL;
+ dns_fixedname_t fixed;
+ dns_fixedname_init(&fixed);
+
+ dstkey = dns_keynode_key(keynode);
+ if (dstkey == NULL) /* fail_secure() was called */
+ break;
+
+ if (dst_key_alg(dstkey) == sig.algorithm &&
+ dst_key_id(dstkey) == sig.keyid) {
+ result = dns_dnssec_verify2(keyname,
+ &kfetch->dnskeyset,
+ dstkey, ISC_FALSE,
+ zone->view->mctx, &sigrr,
+ dns_fixedname_name(&fixed));
+
+ dns_zone_log(zone, ISC_LOG_DEBUG(3),
+ "Verifying DNSKEY set for zone "
+ "'%s': %s", namebuf,
+ dns_result_totext(result));
+
+ if (result == ISC_R_SUCCESS) {
+ kfetch->dnskeyset.trust =
+ dns_trust_secure;
+ kfetch->dnskeysigset.trust =
+ dns_trust_secure;
+ dns_keytable_detachkeynode(secroots,
+ &keynode);
+ break;
+ }
+ }
+
+ result = dns_keytable_nextkeynode(secroots,
+ keynode, &nextnode);
+ dns_keytable_detachkeynode(secroots, &keynode);
+ keynode = nextnode;
+ }
+
+ if (kfetch->dnskeyset.trust == dns_trust_secure)
+ break;
+ }
+
+ /*
+ * If we were not able to verify the answer using the current
+ * trusted keys then all we can do is look at any revoked keys.
+ */
+ secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
+
+ /*
+ * First scan keydataset to find keys that are not in dnskeyset
+ * - Missing keys which are not scheduled for removal,
+ * log a warning
+ * - Missing keys which are scheduled for removal and
+ * the remove hold-down timer has completed should
+ * be removed from the key zone
+ * - Missing keys whose acceptance timers have not yet
+ * completed, log a warning and reset the acceptance
+ * timer to 30 days in the future
+ * - All keys not being removed have their refresh timers
+ * updated
+ */
+ initializing = ISC_TRUE;
+ for (result = dns_rdataset_first(&kfetch->keydataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&kfetch->keydataset)) {
+ dns_rdata_reset(&keydatarr);
+ dns_rdataset_current(&kfetch->keydataset, &keydatarr);
+ dns_rdata_tostruct(&keydatarr, &keydata, NULL);
+
+ /*
+ * If any keydata record has a nonzero add holddown, then
+ * there was a pre-existing trust anchor for this domain;
+ * that means we are *not* initializing it and shouldn't
+ * automatically trust all the keys we find at the zone apex.
+ */
+ initializing = initializing && ISC_TF(keydata.addhd == 0);
+
+ if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
+ isc_boolean_t deletekey = ISC_FALSE;
+
+ if (!secure) {
+ if (now > keydata.removehd)
+ deletekey = ISC_TRUE;
+ } else if (now < keydata.addhd) {
+ dns_zone_log(zone, ISC_LOG_WARNING,
+ "Pending key unexpectedly missing "
+ "from %s; restarting acceptance "
+ "timer", namebuf);
+ keydata.addhd = now + MONTH;
+ keydata.refresh = refresh_time(kfetch,
+ ISC_FALSE);
+ } else if (keydata.addhd == 0) {
+ keydata.addhd = now;
+ } else if (keydata.removehd == 0) {
+ dns_zone_log(zone, ISC_LOG_WARNING,
+ "Active key unexpectedly missing "
+ "from %s", namebuf);
+ keydata.refresh = now + HOUR;
+ } else if (now > keydata.removehd) {
+ deletekey = ISC_TRUE;
+ } else {
+ keydata.refresh = refresh_time(kfetch,
+ ISC_FALSE);
+ }
+
+ if (secure || deletekey) {
+ /* Delete old version */
+ CHECK(update_one_rr(kfetch->db, ver, &diff,
+ DNS_DIFFOP_DEL, keyname, 0,
+ &keydatarr));
+ changed = ISC_TRUE;
+ }
+
+ if (!secure || deletekey)
+ continue;
+
+ dns_rdata_reset(&keydatarr);
+ isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
+ dns_rdata_fromstruct(&keydatarr, zone->rdclass,
+ dns_rdatatype_keydata,
+ &keydata, &keyb);
+
+ /* Insert updated version */
+ CHECK(update_one_rr(kfetch->db, ver, &diff,
+ DNS_DIFFOP_ADD, keyname, 0,
+ &keydatarr));
+ changed = ISC_TRUE;
+
+ set_refreshkeytimer(zone, &keydata, now);
+ }
+ }
+
+ /*
+ * Next scan dnskeyset:
+ * - If new keys are found (i.e., lacking a match in keydataset)
+ * add them to the key zone and set the acceptance timer
+ * to 30 days in the future (or to immediately if we've
+ * determined that we're initializing the zone for the
+ * first time)
+ * - Previously-known keys that have been revoked
+ * must be scheduled for removal from the key zone (or,
+ * if they hadn't been accepted as trust anchors yet
+ * anyway, removed at once)
+ * - Previously-known unrevoked keys whose acceptance timers
+ * have completed are promoted to trust anchors
+ * - All keys not being removed have their refresh
+ * timers updated
+ */
+ for (result = dns_rdataset_first(&kfetch->dnskeyset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&kfetch->dnskeyset)) {
+ isc_boolean_t revoked = ISC_FALSE;
+ isc_boolean_t newkey = ISC_FALSE;
+ isc_boolean_t updatekey = ISC_FALSE;
+ isc_boolean_t deletekey = ISC_FALSE;
+ isc_boolean_t trustkey = ISC_FALSE;
+
+ dns_rdata_reset(&dnskeyrr);
+ dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
+ dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
+
+ /* Skip ZSK's */
+ if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
+ continue;
+
+ revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
+
+ if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
+ dns_rdata_reset(&keydatarr);
+ dns_rdataset_current(&kfetch->keydataset, &keydatarr);
+ dns_rdata_tostruct(&keydatarr, &keydata, NULL);
+
+ if (revoked && revocable(kfetch, &keydata)) {
+ if (keydata.addhd > now) {
+ /*
+ * Key wasn't trusted yet, and now
+ * it's been revoked? Just remove it
+ */
+ deletekey = ISC_TRUE;
+ } else if (keydata.removehd == 0) {
+ /* Remove from secroots */
+ untrust_key(zone->view->viewlist,
+ keyname, mctx, &dnskey);
+
+ /* If initializing, delete now */
+ if (keydata.addhd == 0)
+ deletekey = ISC_TRUE;
+ else
+ keydata.removehd = now + MONTH;
+ } else if (keydata.removehd < now) {
+ /* Scheduled for removal */
+ deletekey = ISC_TRUE;
+ }
+ } else if (revoked) {
+ if (secure && keydata.removehd == 0) {
+ dns_zone_log(zone, ISC_LOG_WARNING,
+ "Active key for zone "
+ "'%s' is revoked but "
+ "did not self-sign; "
+ "ignoring.", namebuf);
+ continue;
+ }
+ } else if (secure) {
+ if (keydata.removehd != 0) {
+ /*
+ * Key isn't revoked--but it
+ * seems it used to be.
+ * Remove it now and add it
+ * back as if it were a fresh key.
+ */
+ deletekey = ISC_TRUE;
+ newkey = ISC_TRUE;
+ } else if (keydata.addhd > now)
+ pending++;
+ else if (keydata.addhd == 0)
+ keydata.addhd = now;
+
+ if (keydata.addhd <= now)
+ trustkey = ISC_TRUE;
+ }
+
+ if (!deletekey && !newkey)
+ updatekey = ISC_TRUE;
+ } else if (secure) {
+ /*
+ * Key wasn't in the key zone but it's
+ * revoked now anyway, so just skip it
+ */
+ if (revoked)
+ continue;
+
+ /* Key wasn't in the key zone: add it */
+ newkey = ISC_TRUE;
+
+ if (initializing) {
+ dns_keytag_t tag = 0;
+ CHECK(compute_tag(keyname, &dnskey,
+ mctx, &tag));
+ dns_zone_log(zone, ISC_LOG_WARNING,
+ "Initializing automatic trust "
+ "anchor management for zone '%s'; "
+ "DNSKEY ID %d is now trusted, "
+ "waiving the normal 30-day "
+ "waiting period.",
+ namebuf, tag);
+ trustkey = ISC_TRUE;
+ }
+ }
+
+ /* Delete old version */
+ if (deletekey || !newkey) {
+ CHECK(update_one_rr(kfetch->db, ver, &diff,
+ DNS_DIFFOP_DEL, keyname, 0,
+ &keydatarr));
+ changed = ISC_TRUE;
+ }
+
+ if (updatekey) {
+ /* Set refresh timer */
+ keydata.refresh = refresh_time(kfetch, ISC_FALSE);
+ dns_rdata_reset(&keydatarr);
+ isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
+ dns_rdata_fromstruct(&keydatarr, zone->rdclass,
+ dns_rdatatype_keydata,
+ &keydata, &keyb);
+
+ /* Insert updated version */
+ CHECK(update_one_rr(kfetch->db, ver, &diff,
+ DNS_DIFFOP_ADD, keyname, 0,
+ &keydatarr));
+ changed = ISC_TRUE;
+ } else if (newkey) {
+ /* Convert DNSKEY to KEYDATA */
+ dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
+ dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
+ NULL);
+ keydata.addhd = initializing ? now : now + MONTH;
+ keydata.refresh = refresh_time(kfetch, ISC_FALSE);
+ dns_rdata_reset(&keydatarr);
+ isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
+ dns_rdata_fromstruct(&keydatarr, zone->rdclass,
+ dns_rdatatype_keydata,
+ &keydata, &keyb);
+
+ /* Insert into key zone */
+ CHECK(update_one_rr(kfetch->db, ver, &diff,
+ DNS_DIFFOP_ADD, keyname, 0,
+ &keydatarr));
+ changed = ISC_TRUE;
+ }
+
+ if (trustkey) {
+ /* Trust this key in all views */
+ dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
+ trust_key(zone->view->viewlist, keyname, &dnskey,
+ mctx);
+ }
+
+ if (!deletekey)
+ set_refreshkeytimer(zone, &keydata, now);
+ }
+
+ /*
+ * RFC5011 says, "A trust point that has all of its trust anchors
+ * revoked is considered deleted and is treated as if the trust
+ * point was never configured." But if someone revoked their
+ * active key before the standby was trusted, that would mean the
+ * zone would suddenly be nonsecured. We avoid this by checking to
+ * see if there's pending keydata. If so, we put a null key in
+ * the security roots; then all queries to the zone will fail.
+ */
+ if (pending != 0)
+ fail_secure(zone->view->viewlist, keyname);
+
+ failure:
+ if (changed) {
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
+ zone_needdump(zone, 30);
+ }
+
+ UNLOCK_ZONE(zone);
+
+ /* Write changes to journal file. */
+ if (alldone) {
+ result = increment_soa_serial(kfetch->db, ver, &diff, mctx);
+ if (result == ISC_R_SUCCESS)
+ result = zone_journal(zone, &diff, "keyfetch_done");
+ }
+
+ dns_diff_clear(&diff);
+ dns_db_closeversion(kfetch->db, &ver, changed);
+ dns_db_detach(&kfetch->db);
+ dns_zone_detach(&kfetch->zone);
+
+ if (dns_rdataset_isassociated(&kfetch->keydataset))
+ dns_rdataset_disassociate(&kfetch->keydataset);
+ if (dns_rdataset_isassociated(&kfetch->dnskeyset))
+ dns_rdataset_disassociate(&kfetch->dnskeyset);
+ if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
+ dns_rdataset_disassociate(&kfetch->dnskeysigset);
+
+ dns_name_free(keyname, mctx);
+ isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
+ isc_mem_detach(&mctx);
+
+ if (secroots != NULL)
+ dns_keytable_detach(&secroots);
+}
+
+/*
+ * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
+ * records from the zone apex.
+ */
+static void
+zone_refreshkeys(dns_zone_t *zone) {
+ const char me[] = "zone_refreshkeys";
+ isc_result_t result;
+ dns_rriterator_t rrit;
+ dns_db_t *db = NULL;
+ dns_dbversion_t *ver = NULL;
+ dns_diff_t diff;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_keydata_t kd;
+ isc_stdtime_t now;
+ isc_boolean_t commit = ISC_FALSE;
+
+ ENTER;
+ REQUIRE(zone->db != NULL);
+
+ isc_stdtime_get(&now);
+
+ ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
+ dns_db_attach(zone->db, &db);
+ ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
+
+ LOCK_ZONE(zone);
+ dns_db_newversion(db, &ver);
+ dns_diff_init(zone->mctx, &diff);
+
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
+
+ dns_rriterator_init(&rrit, db, ver, 0);
+ for (result = dns_rriterator_first(&rrit);
+ result == ISC_R_SUCCESS;
+ result = dns_rriterator_nextrrset(&rrit)) {
+ isc_stdtime_t timer = 0xffffffff;
+ dns_keyfetch_t *kfetch;
+ dns_rdataset_t *kdset;
+ dns_name_t *name = NULL;
+ isc_uint32_t ttl;
+
+ dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
+ if (!dns_rdataset_isassociated(kdset))
+ continue;
+
+ if (kdset->type != dns_rdatatype_keydata)
+ continue;
+
+ /*
+ * Scan the stored keys looking for ones that need
+ * removal or refreshing
+ */
+ for (result = dns_rdataset_first(kdset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(kdset)) {
+ dns_rdata_reset(&rdata);
+ dns_rdataset_current(kdset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &kd, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ /* Removal timer expired? */
+ if (kd.removehd != 0 && kd.removehd < now) {
+ CHECK(update_one_rr(db, ver, &diff,
+ DNS_DIFFOP_DEL, name, ttl,
+ &rdata));
+ continue;
+ }
+
+ /* Acceptance timer expired? */
+ if (kd.addhd != 0 && kd.addhd < now)
+ timer = kd.addhd;
+
+ /* Or do we just need to refresh the keyset? */
+ if (timer > kd.refresh)
+ timer = kd.refresh;
+ }
+
+ if (timer > now)
+ continue;
+
+ zone->refreshkeycount++;
+
+ kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
+ kfetch->zone = NULL;
+ dns_zone_attach(zone, &kfetch->zone);
+ dns_fixedname_init(&kfetch->name);
+ dns_name_dup(name, zone->mctx,
+ dns_fixedname_name(&kfetch->name));
+ dns_rdataset_init(&kfetch->dnskeyset);
+ dns_rdataset_init(&kfetch->dnskeysigset);
+ dns_rdataset_init(&kfetch->keydataset);
+ dns_rdataset_clone(kdset, &kfetch->keydataset);
+ kfetch->db = NULL;
+ dns_db_attach(db, &kfetch->db);
+ kfetch->fetch = NULL;
+
+ dns_resolver_createfetch(zone->view->resolver,
+ dns_fixedname_name(&kfetch->name),
+ dns_rdatatype_dnskey,
+ NULL, NULL, NULL,
+ DNS_FETCHOPT_NOVALIDATE,
+ zone->task, keyfetch_done, kfetch,
+ &kfetch->dnskeyset,
+ &kfetch->dnskeysigset,
+ &kfetch->fetch);
+ }
+ if (!ISC_LIST_EMPTY(diff.tuples)) {
+ CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
+ commit = ISC_TRUE;
+ zone_journal(zone, &diff, "sync_keyzone");
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
+ zone_needdump(zone, 30);
+ }
+ failure:
+ UNLOCK_ZONE(zone);
+
+ dns_rriterator_destroy(&rrit);
+ dns_diff_clear(&diff);
+ dns_db_closeversion(db, &ver, commit);
+ dns_db_detach(&db);
+}
+
+static void
zone_maintenance(dns_zone_t *zone) {
const char me[] = "zone_maintenance";
isc_time_t now;
@@ -5991,7 +7790,7 @@ zone_maintenance(dns_zone_t *zone) {
/*
* Configuring the view of this zone may have
* failed, for example because the config file
- * had a syntax error. In that case, the view
+ * had a syntax error. In that case, the view
* adb or resolver, and we had better not try
* to do maintenance on it.
*/
@@ -6038,6 +7837,7 @@ zone_maintenance(dns_zone_t *zone) {
switch (zone->type) {
case dns_zone_master:
case dns_zone_slave:
+ case dns_zone_key:
LOCK_ZONE(zone);
if (zone->masterfile != NULL &&
isc_time_compare(&now, &zone->dumptime) >= 0 &&
@@ -6059,6 +7859,24 @@ zone_maintenance(dns_zone_t *zone) {
break;
}
+ /*
+ * Do we need to refresh keys?
+ */
+ switch (zone->type) {
+ case dns_zone_key:
+ if (isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
+ DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
+ !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING))
+ zone_refreshkeys(zone);
+ break;
+ case dns_zone_master:
+ if (!isc_time_isepoch(&zone->refreshkeytime) &&
+ isc_time_compare(&now, &zone->refreshkeytime) >= 0)
+ zone_rekey(zone);
+ default:
+ break;
+ }
+
switch (zone->type) {
case dns_zone_master:
case dns_zone_slave:
@@ -6098,7 +7916,8 @@ void
dns_zone_markdirty(dns_zone_t *zone) {
LOCK_ZONE(zone);
- set_resigntime(zone); /* XXXMPA make separate call back */
+ if (zone->type == dns_zone_master)
+ set_resigntime(zone); /* XXXMPA make separate call back */
zone_needdump(zone, DNS_DUMP_DELAY);
UNLOCK_ZONE(zone);
}
@@ -8474,7 +10293,7 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
/*
* We have now canceled everything set the flag to allow exit_check()
- * to succeed. We must not unlock between setting this flag and
+ * to succeed. We must not unlock between setting this flag and
* calling exit_check().
*/
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
@@ -8505,6 +10324,7 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) {
isc_time_t next;
isc_result_t result;
+ ENTER;
REQUIRE(DNS_ZONE_VALID(zone));
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
return;
@@ -8522,6 +10342,12 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) {
isc_time_compare(&zone->dumptime, &next) < 0)
next = zone->dumptime;
}
+ if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
+ !isc_time_isepoch(&zone->refreshkeytime)) {
+ if (isc_time_isepoch(&next) ||
+ isc_time_compare(&zone->refreshkeytime, &next) < 0)
+ next = zone->refreshkeytime;
+ }
if (!isc_time_isepoch(&zone->resigntime)) {
if (isc_time_isepoch(&next) ||
isc_time_compare(&zone->resigntime, &next) < 0)
@@ -8574,6 +10400,22 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) {
}
break;
+ case dns_zone_key:
+ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
+ !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
+ INSIST(!isc_time_isepoch(&zone->dumptime));
+ if (isc_time_isepoch(&next) ||
+ isc_time_compare(&zone->dumptime, &next) < 0)
+ next = zone->dumptime;
+ }
+ if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
+ if (isc_time_isepoch(&next) ||
+ (!isc_time_isepoch(&zone->refreshkeytime) &&
+ isc_time_compare(&zone->refreshkeytime, &next) < 0))
+ next = zone->refreshkeytime;
+ }
+ break;
+
default:
break;
}
@@ -8786,7 +10628,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
REQUIRE(DNS_ZONE_VALID(zone));
/*
- * If type != T_SOA return DNS_R_REFUSED. We don't yet support
+ * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
* ROLLOVER.
*
* SOA: RFC1996
@@ -8905,7 +10747,8 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
NULL, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (isc_serial_le(serial, oldserial)) {
- dns_zone_log(zone, ISC_LOG_INFO,
+ dns_zone_log(zone,
+ ISC_LOG_INFO,
"notify from %s: "
"zone is up to date",
fromtext);
@@ -9309,7 +11152,8 @@ dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
vsnprintf(message, sizeof(message), fmt, ap);
va_end(ap);
isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
- level, "zone %s: %s", zone->strnamerd, message);
+ level, "%s %s: %s", (zone->type == dns_zone_key) ?
+ "managed-keys-zone" : "zone", zone->strnamerd, message);
}
void
@@ -9324,7 +11168,8 @@ dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
vsnprintf(message, sizeof(message), fmt, ap);
va_end(ap);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
- level, "zone %s: %s", zone->strnamerd, message);
+ level, "%s %s: %s", (zone->type == dns_zone_key) ?
+ "managed-keys-zone" : "zone", zone->strnamerd, message);
}
static void
@@ -9342,7 +11187,8 @@ zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
vsnprintf(message, sizeof(message), fmt, ap);
va_end(ap);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
- level, "%s: zone %s: %s", me, zone->strnamerd, message);
+ level, "%s: %s %s: %s", me, zone->type != dns_zone_key ?
+ "zone" : "managed-keys-zone", zone->strnamerd, message);
}
static int
@@ -9499,7 +11345,7 @@ notify_done(isc_task_t *task, isc_event_t *event) {
dns_result_totext(result));
/*
- * Old bind's return formerr if they see a soa record. Retry w/o
+ * Old bind's return formerr if they see a soa record. Retry w/o
* the soa if we see a formerr and had sent a SOA.
*/
isc_event_free(&event);
@@ -9554,7 +11400,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
"has %d SOA records", soacount);
result = DNS_R_BADZONE;
}
- if (nscount == 0) {
+ if (nscount == 0 && zone->type != dns_zone_key) {
dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
result = DNS_R_BADZONE;
}
@@ -9640,24 +11486,27 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
}
} else {
if (dump && zone->masterfile != NULL) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
- "dumping new zone version");
- result = dns_db_dump2(db, ver, zone->masterfile,
- zone->masterformat);
- if (result != ISC_R_SUCCESS)
- goto fail;
-
/*
- * Update the time the zone was updated, so
- * dns_zone_load can avoid loading it when
- * the server is reloaded. If isc_time_now
- * fails for some reason, all that happens is
- * the timestamp is not updated.
+ * If DNS_ZONEFLG_FORCEXFER was set we don't want
+ * to keep the old masterfile.
*/
- TIME_NOW(&zone->loadtime);
+ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
+ remove(zone->masterfile) < 0 && errno != ENOENT) {
+ char strbuf[ISC_STRERRORSIZE];
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(dns_lctx,
+ DNS_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_ZONE,
+ ISC_LOG_WARNING,
+ "unable to remove masterfile "
+ "'%s': '%s'",
+ zone->masterfile, strbuf);
+ }
+ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
+ else
+ zone_needdump(zone, 0);
}
-
if (dump && zone->journal != NULL) {
/*
* The in-memory database just changed, and
@@ -9665,7 +11514,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
* being loaded from disk. Also, we have not
* journaled diffs for this change.
* Therefore, the on-disk journal is missing
- * the deltas for this change. Since it can
+ * the deltas for this change. Since it can
* no longer be used to bring the zone
* up-to-date, it is useless and should be
* removed.
@@ -9853,16 +11702,19 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
&now);
/* Someone removed the file from underneath us! */
if (result == ISC_R_FILENOTFOUND &&
- zone->masterfile != NULL)
- zone_needdump(zone, DNS_DUMP_DELAY);
- else if (result != ISC_R_SUCCESS)
+ zone->masterfile != NULL) {
+ unsigned int delay = DNS_DUMP_DELAY;
+ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY))
+ delay = 0;
+ zone_needdump(zone, delay);
+ } else if (result != ISC_R_SUCCESS)
dns_zone_log(zone, ISC_LOG_ERROR,
"transfer: could not set file "
"modification time of '%s': %s",
zone->masterfile,
dns_result_totext(result));
}
-
+ DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
inc_stats(zone, dns_zonestatscounter_xfrsuccess);
break;
@@ -11313,7 +13165,7 @@ dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
case dns_dialuptype_no:
break;
case dns_dialuptype_yes:
- DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
+ DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
DNS_ZONEFLG_DIALREFRESH |
DNS_ZONEFLG_NOREFRESH));
break;
@@ -11642,3 +13494,778 @@ zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
}
return (result);
}
+
+static void
+logmsg(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
+ ISC_LOG_DEBUG(1), format, args);
+ va_end(args);
+}
+
+static void
+clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
+ dns_dnsseckey_t *key;
+ while (!ISC_LIST_EMPTY(*list)) {
+ key = ISC_LIST_HEAD(*list);
+ ISC_LIST_UNLINK(*list, key, link);
+ dns_dnsseckey_destroy(mctx, &key);
+ }
+}
+
+/* Called once; *timep should be set to the current time. */
+static isc_result_t
+next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
+ isc_result_t result;
+ isc_stdtime_t now, then = 0, event;
+ int i;
+
+ now = *timep;
+
+ for (i = 0; i <= DST_MAX_TIMES; i++) {
+ result = dst_key_gettime(key, i, &event);
+ if (result == ISC_R_SUCCESS && event > now &&
+ (then == 0 || event < then))
+ then = event;
+ }
+
+ if (then != 0) {
+ *timep = then;
+ return (ISC_R_SUCCESS);
+ }
+
+ return (ISC_R_NOTFOUND);
+}
+
+static isc_result_t
+rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
+ const dns_rdata_t *rdata, isc_boolean_t *flag)
+{
+ dns_rdataset_t rdataset;
+ dns_dbnode_t *node = NULL;
+ isc_result_t result;
+
+ dns_rdataset_init(&rdataset);
+ if (rdata->type == dns_rdatatype_nsec3)
+ CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
+ else
+ CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
+ result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
+ (isc_stdtime_t) 0, &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND) {
+ *flag = ISC_FALSE;
+ result = ISC_R_SUCCESS;
+ goto failure;
+ }
+
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t myrdata = DNS_RDATA_INIT;
+ dns_rdataset_current(&rdataset, &myrdata);
+ if (!dns_rdata_compare(&myrdata, rdata))
+ break;
+ }
+ dns_rdataset_disassociate(&rdataset);
+ if (result == ISC_R_SUCCESS) {
+ *flag = ISC_TRUE;
+ } else if (result == ISC_R_NOMORE) {
+ *flag = ISC_FALSE;
+ result = ISC_R_SUCCESS;
+ }
+
+ failure:
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ return (result);
+}
+
+/*
+ * Add records to signal the state of signing or of key removal.
+ */
+static isc_result_t
+add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
+ dns_dbversion_t *ver, dns_diff_t *diff)
+{
+ dns_difftuple_t *tuple, *newtuple = NULL;
+ dns_rdata_dnskey_t dnskey;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ isc_boolean_t flag;
+ isc_region_t r;
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_uint16_t keyid;
+ unsigned char buf[5];
+ dns_name_t *name = dns_db_origin(db);
+
+ for (tuple = ISC_LIST_HEAD(diff->tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_NEXT(tuple, link)) {
+ if (tuple->rdata.type != dns_rdatatype_dnskey)
+ continue;
+
+ result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if ((dnskey.flags &
+ (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
+ != DNS_KEYOWNER_ZONE)
+ continue;
+
+ dns_rdata_toregion(&tuple->rdata, &r);
+
+ keyid = dst_region_computeid(&r, dnskey.algorithm);
+
+ buf[0] = dnskey.algorithm;
+ buf[1] = (keyid & 0xff00) >> 8;
+ buf[2] = (keyid & 0xff);
+ buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
+ buf[4] = 0;
+ rdata.data = buf;
+ rdata.length = sizeof(buf);
+ rdata.type = privatetype;
+ rdata.rdclass = tuple->rdata.rdclass;
+
+ CHECK(rr_exists(db, ver, name, &rdata, &flag));
+ if (flag)
+ continue;
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
+ name, 0, &rdata, &newtuple));
+ CHECK(do_one_tuple(&newtuple, db, ver, diff));
+ INSIST(newtuple == NULL);
+ /*
+ * Remove any record which says this operation has already
+ * completed.
+ */
+ buf[4] = 1;
+ CHECK(rr_exists(db, ver, name, &rdata, &flag));
+ if (flag) {
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
+ name, 0, &rdata, &newtuple));
+ CHECK(do_one_tuple(&newtuple, db, ver, diff));
+ INSIST(newtuple == NULL);
+ }
+ }
+ failure:
+ return (result);
+}
+
+static isc_result_t
+sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
+ dns_diff_t *diff, dns_diff_t *sig_diff)
+{
+ isc_result_t result;
+ isc_stdtime_t now, inception, soaexpire;
+ isc_boolean_t check_ksk, keyset_kskonly;
+ dst_key_t *zone_keys[MAXZONEKEYS];
+ unsigned int nkeys = 0, i;
+ dns_difftuple_t *tuple;
+
+ result = find_zone_keys(zone, db, ver, zone->mctx, MAXZONEKEYS,
+ zone_keys, &nkeys);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "sign_apex:find_zone_keys -> %s\n",
+ dns_result_totext(result));
+ return (result);
+ }
+
+ isc_stdtime_get(&now);
+ inception = now - 3600; /* Allow for clock skew. */
+ soaexpire = now + dns_zone_getsigvalidityinterval(zone);
+
+ check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
+ keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
+
+ /*
+ * See if update_sigs will update DNSKEY signature and if not
+ * cause them to sign so that so that newly activated keys
+ * are used.
+ */
+ for (tuple = ISC_LIST_HEAD(diff->tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_NEXT(tuple, link)) {
+ if (tuple->rdata.type == dns_rdatatype_dnskey &&
+ dns_name_equal(&tuple->name, &zone->origin))
+ break;
+ }
+
+ if (tuple == NULL) {
+ result = del_sigs(zone, db, ver, &zone->origin,
+ dns_rdatatype_dnskey, sig_diff,
+ zone_keys, nkeys, now);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "sign_apex:del_sigs -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+ result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
+ sig_diff, zone_keys, nkeys, zone->mctx,
+ inception, soaexpire, check_ksk,
+ keyset_kskonly);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "sign_apex:add_sigs -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+ }
+
+ result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
+ inception, soaexpire, now, check_ksk,
+ keyset_kskonly, sig_diff);
+
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "sign_apex:update_sigs -> %s\n",
+ dns_result_totext(result));
+ goto failure;
+ }
+
+ failure:
+ for (i = 0; i < nkeys; i++)
+ dst_key_free(&zone_keys[i]);
+ return (result);
+}
+
+/*
+ * Prevent the zone entering a inconsistent state where
+ * NSEC only DNSKEYs are present with NSEC3 chains.
+ * See update.c:check_dnssec()
+ */
+static isc_boolean_t
+dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
+ dns_diff_t *diff)
+{
+ isc_result_t result;
+ dns_difftuple_t *tuple;
+ isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
+
+ /* Scan the tuples for an NSEC-only DNSKEY */
+ for (tuple = ISC_LIST_HEAD(diff->tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_NEXT(tuple, link)) {
+ isc_uint8_t alg;
+ if (tuple->rdata.type != dns_rdatatype_dnskey ||
+ tuple->op != DNS_DIFFOP_ADD)
+ continue;
+
+ alg = tuple->rdata.data[3];
+ if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
+ alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
+ nseconly = ISC_TRUE;
+ break;
+ }
+ }
+
+ /* Check existing DB for NSEC-only DNSKEY */
+ if (!nseconly)
+ CHECK(dns_nsec_nseconly(db, ver, &nseconly));
+
+ /* Check existing DB for NSEC3 */
+ if (!nsec3)
+ CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
+ privatetype, &nsec3));
+
+ /* Refuse to allow NSEC3 with NSEC-only keys */
+ if (nseconly && nsec3) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "NSEC only DNSKEYs and NSEC3 chains not allowed");
+ goto failure;
+ }
+
+ return (ISC_TRUE);
+
+ failure:
+ return (ISC_FALSE);
+}
+
+static isc_result_t
+clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
+ dns_diff_t *diff)
+{
+ isc_result_t result;
+ dns_dbnode_t *node = NULL;
+ dns_rdataset_t rdataset;
+
+ dns_rdataset_init(&rdataset);
+ CHECK(dns_db_getoriginnode(db, &node));
+
+ result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
+ dns_rdatatype_none, 0, &rdataset, NULL);
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (result != ISC_R_NOTFOUND)
+ goto failure;
+
+ result = dns_nsec3param_deletechains(db, ver, zone, diff);
+
+ failure:
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ return (result);
+}
+
+/*
+ * Given an RRSIG rdataset and an algorithm, determine whether there
+ * are any signatures using that algorithm.
+ */
+static isc_boolean_t
+signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_rrsig_t rrsig;
+ isc_result_t result;
+
+ REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
+ if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
+ return (ISC_FALSE);
+ }
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset))
+ {
+ dns_rdataset_current(rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ dns_rdata_reset(&rdata);
+ if (rrsig.algorithm == alg)
+ return (ISC_TRUE);
+ }
+
+ return (ISC_FALSE);
+}
+
+static isc_result_t
+add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
+ dns_diff_t *diff)
+{
+ dns_name_t *origin;
+ isc_boolean_t build_nsec3;
+ isc_result_t result;
+
+ origin = dns_db_origin(db);
+ CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
+ &build_nsec3));
+ if (build_nsec3)
+ CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
+ ISC_FALSE, zone->privatetype, diff));
+ CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
+
+ failure:
+ return (result);
+}
+
+static void
+zone_rekey(dns_zone_t *zone) {
+ isc_result_t result;
+ dns_db_t *db = NULL;
+ dns_dbnode_t *node = NULL;
+ dns_dbversion_t *ver = NULL;
+ dns_rdataset_t soaset, soasigs, keyset, keysigs;
+ dns_dnsseckeylist_t dnskeys, keys, rmkeys;
+ dns_dnsseckey_t *key;
+ dns_diff_t diff, sig_diff;
+ isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
+ isc_boolean_t fullsign;
+ dns_ttl_t ttl = 3600;
+ const char *dir;
+ isc_mem_t *mctx;
+ isc_stdtime_t now;
+ isc_time_t timenow;
+ isc_interval_t ival;
+ char timebuf[80];
+
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ ISC_LIST_INIT(dnskeys);
+ ISC_LIST_INIT(keys);
+ ISC_LIST_INIT(rmkeys);
+ dns_rdataset_init(&soaset);
+ dns_rdataset_init(&soasigs);
+ dns_rdataset_init(&keyset);
+ dns_rdataset_init(&keysigs);
+ dir = dns_zone_getkeydirectory(zone);
+ mctx = zone->mctx;
+ dns_diff_init(mctx, &diff);
+ dns_diff_init(mctx, &sig_diff);
+
+ CHECK(dns_zone_getdb(zone, &db));
+ CHECK(dns_db_newversion(db, &ver));
+ CHECK(dns_db_getoriginnode(db, &node));
+
+ dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
+
+ /* Get the SOA record's TTL */
+ CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
+ dns_rdatatype_none, 0, &soaset, &soasigs));
+ ttl = soaset.ttl;
+ dns_rdataset_disassociate(&soaset);
+
+ /* Get the DNSKEY rdataset */
+ result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
+ dns_rdatatype_none, 0, &keyset, &keysigs);
+ if (result == ISC_R_SUCCESS) {
+ ttl = keyset.ttl;
+ result = dns_dnssec_keylistfromrdataset(&zone->origin, dir,
+ mctx, &keyset,
+ &keysigs, &soasigs,
+ ISC_FALSE, ISC_FALSE,
+ &dnskeys);
+ /* Can't get keys for some reason; try again later. */
+ if (result != ISC_R_SUCCESS)
+ goto trylater;
+ } else if (result != ISC_R_NOTFOUND)
+ goto failure;
+
+ /*
+ * True when called from "rndc sign". Indicates the zone should be
+ * fully signed now.
+ */
+ fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
+
+ result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
+ if (result == ISC_R_SUCCESS) {
+ isc_boolean_t check_ksk;
+ check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
+
+ result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
+ &zone->origin, ttl, &diff,
+ ISC_TF(!check_ksk),
+ mctx, logmsg);
+
+ /* Keys couldn't be updated for some reason;
+ * try again later. */
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
+ "couldn't update zone keys: %s",
+ isc_result_totext(result));
+ goto trylater;
+ }
+
+ /* See if any pre-existing keys have newly become active */
+ for (key = ISC_LIST_HEAD(dnskeys);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ if (key->first_sign) {
+ newactive = ISC_TRUE;
+ break;
+ }
+ }
+
+ if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
+ dnskey_sane(zone, db, ver, &diff)) {
+ CHECK(dns_diff_apply(&diff, db, ver));
+ CHECK(clean_nsec3param(zone, db, ver, &diff));
+ CHECK(add_signing_records(db, zone->privatetype, ver,
+ &diff));
+ CHECK(increment_soa_serial(db, ver, &diff, mctx));
+ CHECK(add_chains(zone, db, ver, &diff));
+ CHECK(sign_apex(zone, db, ver, &diff, &sig_diff));
+ CHECK(zone_journal(zone, &sig_diff, "zone_rekey"));
+ commit = ISC_TRUE;
+ }
+ }
+
+ dns_db_closeversion(db, &ver, commit);
+
+ if (commit) {
+ isc_time_t timenow;
+ dns_difftuple_t *tuple;
+ isc_boolean_t newkey = ISC_FALSE;
+ isc_boolean_t newalg = ISC_FALSE;
+
+ LOCK_ZONE(zone);
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
+
+ zone_needdump(zone, DNS_DUMP_DELAY);
+
+ TIME_NOW(&timenow);
+ zone_settimer(zone, &timenow);
+
+ /*
+ * Has a new key become active? If so, is it for
+ * a new algorithm?
+ */
+ for (tuple = ISC_LIST_HEAD(sig_diff.tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_NEXT(tuple, link)) {
+ dns_rdata_dnskey_t dnskey;
+
+ if (tuple->rdata.type != dns_rdatatype_dnskey)
+ continue;
+
+ newkey = ISC_TRUE;
+ if (!dns_rdataset_isassociated(&keysigs)) {
+ newalg = ISC_TRUE;
+ break;
+ }
+
+ result = dns_rdata_tostruct(&tuple->rdata,
+ &dnskey, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if (!signed_with_alg(&keysigs,
+ dnskey.algorithm)) {
+ newalg = ISC_TRUE;
+ break;
+ }
+ }
+
+ /*
+ * If we found a new algorithm, we need to sign the
+ * zone fully. If there's a new key, but it's for an
+ * already-existing algorithm, then the zone signing
+ * can be handled incrementally.
+ */
+ if (newkey && !newalg)
+ set_resigntime(zone);
+
+ /* Remove any signatures from removed keys. */
+ if (!ISC_LIST_EMPTY(rmkeys)) {
+ for (key = ISC_LIST_HEAD(rmkeys);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ result = zone_signwithkey(zone,
+ dst_key_alg(key->key),
+ dst_key_id(key->key),
+ ISC_TRUE);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone_signwithkey failed: %s",
+ dns_result_totext(result));
+ }
+ }
+ }
+
+
+ if (fullsign) {
+ /*
+ * "rndc sign" was called, so we now sign the zone
+ * with all active keys, whether they're new or not.
+ */
+ for (key = ISC_LIST_HEAD(dnskeys);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ if (!key->force_sign && !key->hint_sign)
+ continue;
+
+ result = zone_signwithkey(zone,
+ dst_key_alg(key->key),
+ dst_key_id(key->key),
+ ISC_FALSE);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone_signwithkey failed: %s",
+ dns_result_totext(result));
+ }
+ }
+ } else if (newalg) {
+ /*
+ * We haven't been told to sign fully, but a new
+ * algorithm was added to the DNSKEY. We sign
+ * the full zone, but only with the newly-added
+ * keys.
+ */
+ for (tuple = ISC_LIST_HEAD(sig_diff.tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_NEXT(tuple, link)) {
+ dns_rdata_dnskey_t dnskey;
+ dns_secalg_t algorithm;
+ isc_region_t r;
+ isc_uint16_t keyid;
+
+ if (tuple->rdata.type != dns_rdatatype_dnskey ||
+ tuple->op == DNS_DIFFOP_DEL)
+ continue;
+
+ result = dns_rdata_tostruct(&tuple->rdata,
+ &dnskey, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ dns_rdata_toregion(&tuple->rdata, &r);
+ algorithm = dnskey.algorithm;
+ keyid = dst_region_computeid(&r, algorithm);
+
+ result = zone_signwithkey(zone, algorithm,
+ keyid, ISC_FALSE);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone_signwithkey failed: %s",
+ dns_result_totext(result));
+ }
+ }
+ }
+
+ /*
+ * Clear fullsign flag, if it was set, so we don't do
+ * another full signing next time
+ */
+ zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
+
+ /*
+ * Cause the zone to add/delete NSEC3 chains for the
+ * deferred NSEC3PARAM changes.
+ */
+ for (tuple = ISC_LIST_HEAD(sig_diff.tuples);
+ tuple != NULL;
+ tuple = ISC_LIST_NEXT(tuple, link)) {
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_nsec3param_t nsec3param;
+
+ if (tuple->rdata.type != zone->privatetype ||
+ tuple->op != DNS_DIFFOP_ADD)
+ continue;
+
+ if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
+ buf, sizeof(buf)))
+ continue;
+ result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if (nsec3param.flags == 0)
+ continue;
+
+ result = zone_addnsec3chain(zone, &nsec3param);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone_addnsec3chain failed: %s",
+ dns_result_totext(result));
+ }
+ }
+ UNLOCK_ZONE(zone);
+ }
+
+ isc_stdtime_get(&now);
+ TIME_NOW(&timenow);
+ isc_time_settoepoch(&zone->refreshkeytime);
+ for (key = ISC_LIST_HEAD(dnskeys);
+ key != NULL;
+ key = ISC_LIST_NEXT(key, link)) {
+ isc_stdtime_t then;
+ isc_time_t timethen;
+
+ /*
+ * If we are doing automatic key maintenance and the
+ * key metadata indicates there is a key change event
+ * scheduled in the future, set the key refresh timer.
+ */
+ if (!DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
+ break;
+
+ then = now;
+ result = next_keyevent(key->key, &then);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
+ LOCK_ZONE(zone);
+ if (isc_time_isepoch(&zone->refreshkeytime) ||
+ isc_time_compare(&timethen, &zone->refreshkeytime) < 0) {
+ zone->refreshkeytime = timethen;
+ zone_settimer(zone, &timenow);
+ }
+ UNLOCK_ZONE(zone);
+ }
+
+ /*
+ * If no key event is scheduled, we should still check the key
+ * repository for updates every so often. (Currently this is
+ * hard-coded to 12 hours, but it could be configurable.)
+ */
+ if (isc_time_isepoch(&zone->refreshkeytime))
+ DNS_ZONE_TIME_ADD(&timenow, (3600 * 12), &zone->refreshkeytime);
+
+ isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
+ dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
+
+ failure:
+ dns_diff_clear(&diff);
+ dns_diff_clear(&sig_diff);
+
+ clear_keylist(&dnskeys, mctx);
+ clear_keylist(&keys, mctx);
+ clear_keylist(&rmkeys, mctx);
+
+ if (ver != NULL)
+ dns_db_closeversion(db, &ver, ISC_FALSE);
+ if (dns_rdataset_isassociated(&keyset))
+ dns_rdataset_disassociate(&keyset);
+ if (dns_rdataset_isassociated(&keysigs))
+ dns_rdataset_disassociate(&keysigs);
+ if (dns_rdataset_isassociated(&soasigs))
+ dns_rdataset_disassociate(&soasigs);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ if (db != NULL)
+ dns_db_detach(&db);
+ return;
+
+ trylater:
+ isc_interval_set(&ival, HOUR, 0);
+ isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
+ goto failure;
+}
+
+void
+dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
+ isc_time_t now;
+
+ if (zone->type == dns_zone_master && zone->task != NULL) {
+ LOCK_ZONE(zone);
+
+ if (fullsign)
+ zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
+
+ TIME_NOW(&now);
+ zone->refreshkeytime = now;
+ zone_settimer(zone, &now);
+
+ UNLOCK_ZONE(zone);
+ }
+}
+
+isc_result_t
+dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
+ unsigned int *errors)
+{
+ isc_result_t result;
+ dns_dbnode_t *node = NULL;
+
+ REQUIRE(DNS_ZONE_VALID(zone));
+ REQUIRE(errors != NULL);
+
+ result = dns_db_getoriginnode(db, &node);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
+ ISC_FALSE);
+ dns_db_detachnode(db, &node);
+ return (result);
+}
+
+void
+dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+ LOCK_ZONE(zone);
+ zone->added = added;
+ UNLOCK_ZONE(zone);
+}
+
+isc_boolean_t
+dns_zone_getadded(dns_zone_t *zone) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+ return (zone->added);
+}
+
+isc_result_t
+dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
+{
+ isc_time_t loadtime;
+ isc_result_t result;
+ TIME_NOW(&loadtime);
+
+ LOCK_ZONE(zone);
+ result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
+ UNLOCK_ZONE(zone);
+ return result;
+}
diff --git a/lib/export/Makefile.in b/lib/export/Makefile.in
new file mode 100644
index 000000000000..5a9e633e4ecc
--- /dev/null
+++ b/lib/export/Makefile.in
@@ -0,0 +1,27 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+# Note: the order of SUBDIRS is important.
+# Attempt to disable parallel processing.
+.NOTPARALLEL:
+.NO_PARALLEL:
+SUBDIRS = isc dns isccfg irs samples
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/dns/Makefile.in b/lib/export/dns/Makefile.in
new file mode 100644
index 000000000000..15b0d3f313ee
--- /dev/null
+++ b/lib/export/dns/Makefile.in
@@ -0,0 +1,179 @@
+# Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.8 2010-12-23 04:07:59 marka Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/dns
+export_srcdir = @top_srcdir@/lib/export
+
+# Attempt to disable parallel processing.
+.NOTPARALLEL:
+.NO_PARALLEL:
+
+@BIND9_VERSION@
+
+@LIBDNS_API@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} -I${export_srcdir}/isc/include \
+ ${ISC_INCLUDES} @DST_OPENSSL_INC@ @DST_GSSAPI_INC@
+
+CDEFINES = -DUSE_MD5 @USE_OPENSSL@ @USE_GSSAPI@
+
+CWARNINGS =
+
+ISCLIBS = ../isc/libisc.@A@
+
+ISCDEPLIBS = ../isc/libisc.@A@
+
+LIBS = @LIBS@
+
+# Alphabetically
+
+OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \
+ opensslgost_link.@O@ opensslrsa_link.@O@
+
+DSTOBJS = @OPENSSLLINKOBJS@ \
+ dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \
+ gssapi_link.@O@ gssapictx.@O@ hmac_link.@O@ key.@O@
+
+DNSOBJS = acl.@O@ adb.@O@ byaddr.@O@ \
+ cache.@O@ callbacks.@O@ client.@O@ compress.@O@ \
+ db.@O@ dbiterator.@O@ diff.@O@ dispatch.@O@ dlz.@O@ dnssec.@O@ \
+ ds.@O@ \
+ forward.@O@ iptable.@O@ \
+ keytable.@O@ \
+ lib.@O@ log.@O@ \
+ master.@O@ masterdump.@O@ message.@O@ \
+ name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ \
+ peer.@O@ portlist.@O@ \
+ rbt.@O@ rbtdb.@O@ rcode.@O@ rdata.@O@ \
+ rdatalist.@O@ rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ \
+ request.@O@ resolver.@O@ result.@O@ soa.@O@ stats.@O@ \
+ tcpmsg.@O@ time.@O@ tsec.@O@ tsig.@O@ ttl.@O@ \
+ validator.@O@ version.@O@ view.@O@
+PORTDNSOBJS = ecdb.@O@
+
+OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} ${PORTDNSOBJS}
+
+# Alphabetically
+
+OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \
+ opensslgost_link.c opensslrsa_link.c
+
+DSTSRCS = @OPENSSLLINKSRCS@ \
+ dst_api.c dst_lib.c dst_parse.c \
+ dst_result.c gssapi_link.c gssapictx.c \
+ hmac_link.c key.c
+
+DNSSRCS = acl.c adb.c byaddr.c \
+ cache.c callbacks.c client.c compress.c \
+ db.c dbiterator.c diff.c dispatch.c dlz.c dnssec.c ds.c \
+ forward.c iptable.c \
+ keytable.c \
+ lib.c log.c \
+ master.c masterdump.c message.c \
+ name.c ncache.c nsec.c nsec3.c \
+ peer.c portlist.c \
+ rbt.c rbtdb.c rcode.c rdata.c \
+ rdatalist.c rdataset.c rdatasetiter.c rdataslab.c \
+ request.c res.c resolver.c result.c soa.c stats.c \
+ tcpmsg.c time.c tsec.c tsig.c ttl.c \
+ validator.c version.c view.c
+PORTDNSSRCS = ecdb.c
+
+SRCS = ${DSTSRCS} ${DNSSRCS} ${PORTDNSSRCS}
+
+SUBDIRS = include
+TARGETS = include/dns/enumtype.h include/dns/enumclass.h \
+ include/dns/rdatastruct.h timestamp
+
+DEPENDEXTRA = ./gen -F include/dns/rdatastruct.h \
+ -s ${srcdir} -d >> Makefile ;
+
+@BIND9_MAKE_RULES@
+
+version.@O@: ${srcdir}/version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libdns.@SA@: ${OBJS}
+ ${AR} ${ARFLAGS} $@ ${OBJS}
+ ${RANLIB} $@
+
+libdns.la: ${OBJS}
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libdns.la \
+ -rpath ${export_libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ ${LIBS}
+
+timestamp: libdns.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libdns.@A@ \
+ ${DESTDIR}${export_libdir}
+
+clean distclean::
+ rm -f libdns.@A@ timestamp
+ rm -f gen code.h include/dns/enumtype.h include/dns/enumclass.h
+ rm -f include/dns/rdatastruct.h
+
+newrr::
+ rm -f code.h include/dns/enumtype.h include/dns/enumclass.h
+ rm -f include/dns/rdatastruct.h
+
+include: include/dns/enumtype.h include/dns/enumclass.h \
+ include/dns/rdatastruct.h
+
+rdata.@O@: code.h
+
+include/dns/enumtype.h: gen
+ ./gen -s ${srcdir} -t > $@
+
+include/dns/enumclass.h: gen
+ ./gen -s ${srcdir} -c > $@
+
+include/dns/rdatastruct.h: gen \
+ ${srcdir}/rdata/rdatastructpre.h \
+ ${srcdir}/rdata/rdatastructsuf.h
+ ./gen -s ${srcdir} -i \
+ -P ${srcdir}/rdata/rdatastructpre.h \
+ -S ${srcdir}/rdata/rdatastructsuf.h > $@
+
+code.h: gen
+ ./gen -s ${srcdir} > code.h
+
+gen: ${srcdir}/gen.c
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ ${srcdir}/gen.c ${LIBS}
+
+#We don't need rbtdb64 for this library
+#rbtdb64.@O@: rbtdb.c
+
+depend: include/dns/enumtype.h include/dns/enumclass.h \
+ include/dns/rdatastruct.h code.h
+subdirs: include/dns/enumtype.h include/dns/enumclass.h \
+ include/dns/rdatastruct.h code.h
+${OBJS}: include/dns/enumtype.h include/dns/enumclass.h \
+ include/dns/rdatastruct.h
diff --git a/lib/export/dns/include/Makefile.in b/lib/export/dns/include/Makefile.in
new file mode 100644
index 000000000000..ecd9c8af6751
--- /dev/null
+++ b/lib/export/dns/include/Makefile.in
@@ -0,0 +1,23 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = dns dst
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/dns/include/dns/Makefile.in b/lib/export/dns/include/dns/Makefile.in
new file mode 100644
index 000000000000..ccaae41c4edf
--- /dev/null
+++ b/lib/export/dns/include/dns/Makefile.in
@@ -0,0 +1,56 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.4 2009-09-18 07:18:04 jinmei Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = acl.h adb.h byaddr.h \
+ cache.h callbacks.h cert.h client.h compress.h \
+ db.h dbiterator.h diff.h dispatch.h dlz.h dnssec.h \
+ ds.h events.h fixedname.h ecdb.h \
+ forward.h iptable.h \
+ keytable.h keyvalues.h \
+ lib.h log.h \
+ master.h masterdump.h message.h \
+ name.h ncache.h nsec.h nsec3.h \
+ peer.h portlist.h \
+ rbt.h rcode.h rdata.h rdataclass.h \
+ rdatalist.h rdataset.h rdatasetiter.h rdataslab.h rdatatype.h \
+ request.h resolver.h result.h \
+ secalg.h secproto.h soa.h stats.h \
+ tcpmsg.h time.h tsec.h tsig.h ttl.h types.h \
+ validator.h version.h view.h
+
+GENHEADERS = enumclass.h enumtype.h rdatastruct.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/dns
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${top_srcdir}/lib/dns/include/dns/$$i \
+ ${DESTDIR}${export_includedir}/dns ; \
+ done
+ for i in ${GENHEADERS}; do \
+ ${INSTALL_DATA} $$i ${DESTDIR}${export_includedir}/dns ; \
+ done
diff --git a/lib/export/dns/include/dst/Makefile.in b/lib/export/dns/include/dst/Makefile.in
new file mode 100644
index 000000000000..cebc7262f603
--- /dev/null
+++ b/lib/export/dns/include/dst/Makefile.in
@@ -0,0 +1,36 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = dst.h gssapi.h lib.h result.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/dst
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${top_srcdir}/lib/dns/include/dst/$$i \
+ ${DESTDIR}${export_includedir}/dst ; \
+ done
diff --git a/lib/export/irs/Makefile.in b/lib/export/irs/Makefile.in
new file mode 100644
index 000000000000..aad94009354e
--- /dev/null
+++ b/lib/export/irs/Makefile.in
@@ -0,0 +1,86 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.4 2009-12-05 23:31:40 each Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/irs
+export_srcdir = @top_srcdir@/lib/export
+
+@BIND9_VERSION@
+
+@LIBIRS_API@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I. -I./include -I${srcdir}/include \
+ ${ISCCFG_INCLUDES} -I../dns/include ${DNS_INCLUDES} \
+ -I${export_srcdir}/isc/include ${ISC_INCLUDES}
+CDEFINES =
+CWARNINGS =
+
+# Alphabetically
+OBJS = context.@O@ \
+ dnsconf.@O@ \
+ gai_strerror.@O@ getaddrinfo.@O@ getnameinfo.@O@ \
+ resconf.@O@
+
+# Alphabetically
+SRCS = context.c \
+ dnsconf.c \
+ gai_sterror.c getaddrinfo.c getnameinfo.c \
+ resconf.c
+
+ISCLIBS = ../isc/libisc.@A@
+DNSLIBS = ../dns/libdns.@A@
+ISCCFGLIBS = ../isccfg/libisccfg.@A@
+
+LIBS = @LIBS@
+
+SUBDIRS = include
+TARGETS = timestamp
+
+@BIND9_MAKE_RULES@
+
+version.@O@: ${srcdir}/version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libirs.@SA@: ${OBJS} version.@O@
+ ${AR} ${ARFLAGS} $@ ${OBJS} version.@O@
+ ${RANLIB} $@
+
+libirs.la: ${OBJS} version.@O@
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libirs.la \
+ -rpath ${export_libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} version.@O@ ${LIBS} ${ISCCFGLIBS} ${DNSLIBS} ${ISCLIBS}
+
+timestamp: libirs.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libirs.@A@ \
+ ${DESTDIR}${export_libdir}
+
+clean distclean::
+ rm -f libirs.@A@ libirs.la timestamp
diff --git a/lib/export/irs/include/Makefile.in b/lib/export/irs/include/Makefile.in
new file mode 100644
index 000000000000..e6d4eae7313f
--- /dev/null
+++ b/lib/export/irs/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.2 2009-09-01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = irs
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/irs/include/irs/Makefile.in b/lib/export/irs/include/irs/Makefile.in
new file mode 100644
index 000000000000..93f420006df8
--- /dev/null
+++ b/lib/export/irs/include/irs/Makefile.in
@@ -0,0 +1,46 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+#
+# Only list headers that are to be installed and are not
+# machine generated. The latter are handled specially in the
+# install target below.
+#
+HEADERS = context.h dnsconf.h resconf.h types.h version.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/irs
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${top_srcdir}/lib/irs/include/irs/$$i \
+ ${DESTDIR}${export_includedir}/irs ; \
+ done
+ ${INSTALL_DATA} ${top_srcdir}/lib/irs/include/irs/netdb.h \
+ ${DESTDIR}${export_includedir}/irs
+ ${INSTALL_DATA} ${top_srcdir}/lib/irs/include/irs/platform.h \
+ ${DESTDIR}${export_includedir}/irs
+
+distclean::
+ rm -f netdb.h platform.h
diff --git a/lib/export/isc/Makefile.in b/lib/export/isc/Makefile.in
new file mode 100644
index 000000000000..fa1c367660e1
--- /dev/null
+++ b/lib/export/isc/Makefile.in
@@ -0,0 +1,139 @@
+# Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.8 2010-06-09 23:50:58 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc
+export_srcdir = @top_srcdir@/lib/export
+
+@BIND9_VERSION@
+
+@LIBISC_API@
+
+CINCLUDES = -I${srcdir}/unix/include \
+ -I${srcdir}/@ISC_THREAD_DIR@/include \
+ -I${srcdir}/@ISC_ARCH_DIR@/include \
+ -I${export_srcdir}/isc/include -I${srcdir}/include \
+ @ISC_OPENSSL_INC@
+CDEFINES = @USE_OPENSSL@ -DUSE_APPIMPREGISTER -DUSE_MEMIMPREGISTER \
+ -DUSE_SOCKETIMPREGISTER -DUSE_TASKIMPREGISTER \
+ -DUSE_TIMERIMPREGISTER
+CWARNINGS =
+
+# Alphabetically
+# {file,dir}.c is necessary for isclog
+# symtab.c is necessary for isccfg
+APIOBJS = app_api.@O@ mem_api.@O@ socket_api.@O@ \
+ task_api.@O@ timer_api.@O@
+
+ISCDRIVEROBJS = mem.@O@ unix/socket.@O@ task.@O@ timer.@O@ lib.@O@ \
+ heap.@O@ #timer module depends on this
+
+UNIXOBJS = @ISC_ISCIPV6_O@ \
+ unix/app.@O@ \
+ unix/dir.@O@ \
+ unix/errno2result.@O@ \
+ unix/file.@O@ \
+ unix/fsaccess.@O@ \
+ unix/stdio.@O@ \
+ unix/stdtime.@O@ unix/strerror.@O@ unix/time.@O@
+
+NLSOBJS = nls/msgcat.@O@
+
+THREADOPTOBJS = @ISC_THREAD_DIR@/condition.@O@ @ISC_THREAD_DIR@/mutex.@O@
+
+THREADOBJS = @THREADOPTOBJS@ @ISC_THREAD_DIR@/thread.@O@
+
+WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \
+ win32/fsaccess.@O@ win32/once.@O@ win32/stdtime.@O@ \
+ win32/thread.@O@ win32/time.@O@
+
+# Alphabetically
+OBJS = @ISC_EXTRA_OBJS@ \
+ assertions.@O@ backtrace.@O@ backtrace-emptytbl.@O@ base32.@O@ \
+ base64.@O@ buffer.@O@ bufferlist.@O@ \
+ error.@O@ event.@O@ \
+ hash.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
+ inet_aton.@O@ iterated_hash.@O@ lex.@O@ lfsr.@O@ log.@O@ \
+ md5.@O@ mutexblock.@O@ \
+ netaddr.@O@ netscope.@O@ \
+ ondestroy.@O@ \
+ parseint.@O@ portset.@O@ radix.@O@ \
+ random.@O@ refcount.@O@ region.@O@ result.@O@ rwlock.@O@ \
+ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ string.@O@ \
+ symtab.@O@ \
+ version.@O@ \
+ ${APIOBJS} ${ISCDRIVEROBJS} \
+ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
+
+# Alphabetically
+APISRCS = app_api.c mem_api.c socket_api.c \
+ task_api.c timer_api.c
+
+ISCDRIVERSRCS = mem.c task.c lib.c timer.c heap.c
+
+SRCS = @ISC_EXTRA_SRCS@ \
+ assertions.c backtrace.c backtrace-emptytbl.c base32.c \
+ base64.c buffer.c bufferlist.c \
+ error.c event.c \
+ hash.c hex.c hmacmd5.c hmacsha.c \
+ inet_aton.c iterated_hash.c lex.c log.c lfsr.c \
+ md5.c mutexblock.c \
+ netaddr.c netscope.c \
+ ondestroy.c \
+ parseint.c portset.c radix.c \
+ random.c refcount.c region.c result.c rwlock.c \
+ serial.c sha1.c sha2.c sockaddr.c stats.c string.c symtab.c \
+ version.c \
+ ${APISRCS} ${ISCDRIVERSRCS}
+
+LIBS = @LIBS@
+
+SUBDIRS = include unix nls @ISC_THREAD_DIR@
+TARGETS = timestamp
+
+@BIND9_MAKE_RULES@
+
+version.@O@: ${srcdir}/version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libisc.@SA@: ${OBJS}
+ ${AR} ${ARFLAGS} $@ ${OBJS}
+ ${RANLIB} $@
+
+libisc.la: ${OBJS}
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc.la \
+ -rpath ${export_libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} ${LIBS}
+
+timestamp: libisc.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisc.@A@ \
+ ${DESTDIR}${export_libdir}
+
+clean distclean::
+ rm -f libisc.@A@ libisc.la timestamp
diff --git a/lib/export/isc/include/Makefile.in b/lib/export/isc/include/Makefile.in
new file mode 100644
index 000000000000..f89628b9c1c3
--- /dev/null
+++ b/lib/export/isc/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.2 2009-09-01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/include/isc/Makefile.in b/lib/export/isc/include/isc/Makefile.in
new file mode 100644
index 000000000000..0336ba22908f
--- /dev/null
+++ b/lib/export/isc/include/isc/Makefile.in
@@ -0,0 +1,66 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-12-05 23:31:41 each Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+export_srcdir = @top_srcdir@/lib/export
+
+@BIND9_VERSION@
+
+#
+# Only list headers that are to be installed and are not
+# machine generated. The latter are handled specially in the
+# install target below.
+#
+HEADERS = app.h assertions.h base64.h bitstring.h boolean.h \
+ buffer.h bufferlist.h commandline.h entropy.h error.h event.h \
+ eventclass.h file.h formatcheck.h fsaccess.h \
+ hash.h heap.h hex.h hmacmd5.h \
+ httpd.h \
+ interfaceiter.h @ISC_IPV6_H@ iterated_hash.h lang.h lex.h \
+ lfsr.h lib.h list.h log.h \
+ magic.h md5.h mem.h msgcat.h msgs.h \
+ mutexblock.h namespace.h netaddr.h ondestroy.h os.h parseint.h \
+ print.h quota.h radix.h random.h ratelimiter.h \
+ refcount.h region.h resource.h \
+ result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \
+ sockaddr.h socket.h stdio.h stdlib.h string.h \
+ symtab.h \
+ task.h taskpool.h timer.h types.h util.h version.h \
+ xml.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${top_srcdir}/lib/isc/include/isc/$$i \
+ ${DESTDIR}${export_includedir}/isc ; \
+ done
+ ${INSTALL_DATA} ${top_srcdir}/lib/isc/include/isc/platform.h \
+ ${DESTDIR}${export_includedir}/isc
+ ${INSTALL_DATA} ${top_srcdir}/lib/isc/@ISC_ARCH_DIR@/include/isc/atomic.h \
+ ${DESTDIR}${export_includedir}/isc
+ ${INSTALL_DATA} ${export_srcdir}/isc/include/isc/bind9.h \
+ ${DESTDIR}${export_includedir}/isc
+
+distclean::
+ rm -f platform.h
diff --git a/lib/export/isc/include/isc/bind9.h b/lib/export/isc/include/isc/bind9.h
new file mode 100644
index 000000000000..380ca85f2c1f
--- /dev/null
+++ b/lib/export/isc/include/isc/bind9.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: bind9.h,v 1.2 2009-12-05 23:31:41 each Exp $ */
+
+#ifndef ISC_BIND9_H
+#define ISC_BIND9_H 1
+
+/*
+ * This determines whether we are building BIND9 or using the exported
+ * libisc/libdns libraries. The version of this file included in the
+ * standard BIND9 build defines BIND9; the version included with the
+ * exportable libraries does not.
+ */
+#undef BIND9
+
+#endif /* ISC_BIND9_H */
diff --git a/lib/export/isc/nls/Makefile.in b/lib/export/isc/nls/Makefile.in
new file mode 100644
index 000000000000..da2513f2abb2
--- /dev/null
+++ b/lib/export/isc/nls/Makefile.in
@@ -0,0 +1,35 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc/nls
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/unix/include \
+ ${ISC_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+OBJS = msgcat.@O@
+
+SRCS = msgcat.c
+
+SUBDIRS =
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/nothreads/Makefile.in b/lib/export/isc/nothreads/Makefile.in
new file mode 100644
index 000000000000..3bffb4e82b54
--- /dev/null
+++ b/lib/export/isc/nothreads/Makefile.in
@@ -0,0 +1,40 @@
+# Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.5 2010-06-09 23:50:58 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc/nothreads
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/include \
+ -I${srcdir}/../unix/include \
+ -I../include \
+ -I${srcdir}/../include \
+ -I${srcdir}/..
+
+CDEFINES =
+CWARNINGS =
+
+THREADOPTOBJS = condition.@O@ mutex.@O@
+OBJS = @THREADOPTOBJS@ thread.@O@
+
+THREADOPTSRCS = condition.c mutex.c
+SRCS = @THREADOPTSRCS@ thread.c
+
+SUBDIRS = include
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/nothreads/include/Makefile.in b/lib/export/isc/nothreads/include/Makefile.in
new file mode 100644
index 000000000000..f89628b9c1c3
--- /dev/null
+++ b/lib/export/isc/nothreads/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.2 2009-09-01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/nothreads/include/isc/Makefile.in b/lib/export/isc/nothreads/include/isc/Makefile.in
new file mode 100644
index 000000000000..423f10ab03de
--- /dev/null
+++ b/lib/export/isc/nothreads/include/isc/Makefile.in
@@ -0,0 +1,36 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.2 2009-09-01 00:22:27 jinmei Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = condition.h mutex.h once.h thread.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} $(top_srcdir)/lib/isc/nothreads/include/isc/$$i \
+ ${DESTDIR}${export_includedir}/isc ; \
+ done
diff --git a/lib/export/isc/pthreads/Makefile.in b/lib/export/isc/pthreads/Makefile.in
new file mode 100644
index 000000000000..5fac018504ea
--- /dev/null
+++ b/lib/export/isc/pthreads/Makefile.in
@@ -0,0 +1,38 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc/pthreads
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/include \
+ -I${srcdir}/../unix/include \
+ -I../include \
+ -I${srcdir}/../include \
+ -I${srcdir}/..
+
+CDEFINES =
+CWARNINGS =
+
+OBJS = condition.@O@ mutex.@O@ thread.@O@
+
+SRCS = condition.c mutex.c thread.c
+
+SUBDIRS = include
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/pthreads/include/Makefile.in b/lib/export/isc/pthreads/include/Makefile.in
new file mode 100644
index 000000000000..f89628b9c1c3
--- /dev/null
+++ b/lib/export/isc/pthreads/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.2 2009-09-01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/pthreads/include/isc/Makefile.in b/lib/export/isc/pthreads/include/isc/Makefile.in
new file mode 100644
index 000000000000..807de9436239
--- /dev/null
+++ b/lib/export/isc/pthreads/include/isc/Makefile.in
@@ -0,0 +1,36 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.2 2009-09-01 00:22:27 jinmei Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = condition.h mutex.h once.h thread.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} $(top_srcdir)/lib/isc/pthreads/include/isc/$$i \
+ ${DESTDIR}${export_includedir}/isc ; \
+ done
diff --git a/lib/export/isc/unix/Makefile.in b/lib/export/isc/unix/Makefile.in
new file mode 100644
index 000000000000..81746a4a78d9
--- /dev/null
+++ b/lib/export/isc/unix/Makefile.in
@@ -0,0 +1,57 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc/unix
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/include \
+ -I${srcdir}/../@ISC_THREAD_DIR@/include \
+ -I../include \
+ -I${srcdir}/../include \
+ -I${srcdir}/..
+
+CDEFINES = -DUSE_SOCKETIMPREGISTER -DUSE_APPIMPREGISTER
+
+CWARNINGS =
+
+# Alphabetically
+ISCDRIVEROBJS = app.@O@ socket.@O@
+
+OBJS = @ISC_IPV6_O@ \
+ dir.@O@ \
+ errno2result.@O@ \
+ file.@O@ fsaccess.@O@ \
+ stdio.@O@ stdtime.@O@ strerror.@O@ \
+ time.@O@ \
+ ${ISCDRIVEROBJS}
+
+# Alphabetically
+ISCDRIVERSRCS = app.c socket.c
+
+SRCS = @ISC_IPV6_C@ \
+ dir.c \
+ errno2result.c \
+ file.c fsaccess.c \
+ stdio.c stdtime.c strerror.c \
+ time.c \
+ ${ISCDRIVERSRCS}
+
+SUBDIRS = include
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/unix/include/Makefile.in b/lib/export/isc/unix/include/Makefile.in
new file mode 100644
index 000000000000..f89628b9c1c3
--- /dev/null
+++ b/lib/export/isc/unix/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.2 2009-09-01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isc/unix/include/isc/Makefile.in b/lib/export/isc/unix/include/isc/Makefile.in
new file mode 100644
index 000000000000..21ce049a6b4a
--- /dev/null
+++ b/lib/export/isc/unix/include/isc/Makefile.in
@@ -0,0 +1,37 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.2 2009-09-01 00:22:27 jinmei Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = dir.h int.h net.h netdb.h offset.h stdtime.h \
+ syslog.h time.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} $(top_srcdir)/lib/isc/unix/include/isc/$$i \
+ ${DESTDIR}${export_includedir}/isc ; \
+ done
diff --git a/lib/export/isccfg/Makefile.in b/lib/export/isccfg/Makefile.in
new file mode 100644
index 000000000000..ed2b2cf56ffd
--- /dev/null
+++ b/lib/export/isccfg/Makefile.in
@@ -0,0 +1,83 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.4 2009-12-05 23:31:41 each Exp $
+
+top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isccfg
+export_srcdir = @top_srcdir@/lib/export
+
+@BIND9_VERSION@
+
+@LIBISCCFG_API@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I. ${DNS_INCLUDES} -I${export_srcdir}/isc/include \
+ ${ISC_INCLUDES} ${ISCCFG_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+ISCLIBS = ../isc/libisc.@A@
+DNSLIBS = ../dns/libdns.@A@
+
+ISCDEPLIBS = ../../lib/isc/libisc.@A@
+ISCCFGDEPLIBS = libisccfg.@A@
+
+LIBS = @LIBS@
+
+SUBDIRS = include
+
+# Alphabetically
+OBJS = dnsconf.@O@ log.@O@ parser.@O@ version.@O@
+
+# Alphabetically
+SRCS = dnsconf.c log.c parser.c version.c
+
+TARGETS = timestamp
+
+@BIND9_MAKE_RULES@
+
+version.@O@: ${srcdir}/version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libisccfg.@SA@: ${OBJS}
+ ${AR} ${ARFLAGS} $@ ${OBJS}
+ ${RANLIB} $@
+
+libisccfg.la: ${OBJS}
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccfg.la \
+ -rpath ${export_libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} ${LIBS} ${DNSLIBS} ${ISCLIBS}
+
+timestamp: libisccfg.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisccfg.@A@ \
+ ${DESTDIR}${export_libdir}
+
+clean distclean::
+ rm -f libisccfg.@A@ timestamp
diff --git a/lib/export/isccfg/include/Makefile.in b/lib/export/isccfg/include/Makefile.in
new file mode 100644
index 000000000000..896c4671e187
--- /dev/null
+++ b/lib/export/isccfg/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.2 2009-09-01 00:22:27 jinmei Exp $
+
+srcdir = @srdir@
+top_srcdir = @top_srcdir@
+
+
+SUBDIRS = isccfg
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/export/isccfg/include/isccfg/Makefile.in b/lib/export/isccfg/include/isccfg/Makefile.in
new file mode 100644
index 000000000000..3f97894780fd
--- /dev/null
+++ b/lib/export/isccfg/include/isccfg/Makefile.in
@@ -0,0 +1,42 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+#
+# Only list headers that are to be installed and are not
+# machine generated. The latter are handled specially in the
+# install target below.
+#
+HEADERS = cfg.h grammar.h log.h dnsconf.h version.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs \
+ ${DESTDIR}${export_includedir}/isccfg
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${top_srcdir}/lib/isccfg/include/isccfg/$$i \
+ ${DESTDIR}${export_includedir}/isccfg ; \
+ done
diff --git a/lib/export/samples/Makefile-postinstall.in b/lib/export/samples/Makefile-postinstall.in
new file mode 100644
index 000000000000..10a26f47a9c0
--- /dev/null
+++ b/lib/export/samples/Makefile-postinstall.in
@@ -0,0 +1,78 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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-postinstall.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+#prefix = @prefix@
+#exec_prefix = @exec_prefix@
+
+CDEFINES =
+CWARNINGS =
+
+DNSLIBS = -ldns @DNS_CRYPTO_LIBS@
+ISCLIBS = -lisc
+ISCCFGLIBS = -lisccfg
+IRSLIBS = -lirs
+
+LIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@
+
+SUBDIRS =
+
+TARGETS = sample@EXEEXT@ sample-async@EXEEXT@ sample-gai@EXEEXT@ \
+ sample-update@EXEEXT@ sample-request@EXEEXT@ nsprobe@EXEEXT@ \
+ dlvchecks@EXEEXT@
+
+OBJS = sample.@O@ sample-async.@O@ sample-gai.@O@ sample-update.@O@ \
+ sample-request.@O@ nsprobe.@O@ dlvchecks.@O@
+
+SRCS = sample.c sample-async.c sample-gai.c sample-update.c \
+ sample-request.c nsprobe.c dlvchecks..c
+
+@BIND9_MAKE_RULES@
+
+# The following two may depend on BIND9_MAKE_RULES
+CINCLUDES = -I@export_includedir@
+LDFLAGS = -L@export_libdir@
+
+sample@EXEEXT@: sample.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample.@O@ ${LIBS}
+
+sample-async@EXEEXT@: sample-async.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-async.@O@ ${LIBS}
+
+sample-gai@EXEEXT@: sample-gai.@O@ ${IRSDEPLIBS} ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-gai.@O@ ${IRSLIBS} ${LIBS}
+
+sample-update@EXEEXT@: sample-update.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-update.@O@ ${LIBS}
+
+sample-request@EXEEXT@: sample-request.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-request.@O@ ${LIBS}
+
+nsprobe@EXEEXT@: nsprobe.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ nsprobe.@O@ ${LIBS}
+
+dlvchecks@EXEEXT@: dlvchecks.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ dlvchecks.@O@ ${LIBS}
+
+clean distclean maintainer-clean::
+ rm -f ${TARGETS}
diff --git a/lib/export/samples/Makefile.in b/lib/export/samples/Makefile.in
new file mode 100644
index 000000000000..ff8e916a589d
--- /dev/null
+++ b/lib/export/samples/Makefile.in
@@ -0,0 +1,98 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.4 2009-12-05 23:31:41 each Exp $
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+export_srcdir = @top_srcdir@/lib/export
+
+@BIND9_VERSION@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I${srcdir}/include -I../dns/include \
+ -I${export_srcdir}/isc/include \
+ ${DNS_INCLUDES} ${ISC_INCLUDES} \
+ -I${top_srcdir}/lib/irs/include
+
+CDEFINES =
+CWARNINGS =
+
+DNSLIBS = ../dns/libdns.@A@ @DNS_CRYPTO_LIBS@
+ISCLIBS = ../isc/libisc.@A@
+ISCCFGLIBS = ../isccfg/libisccfg.@A@
+IRSLIBS = ../irs/libirs.@A@
+
+DNSDEPLIBS = ../dns/libdns.@A@
+ISCDEPLIBS = ../isc/libisc.@A@
+ISCCFGDEPLIBS = ../isccfg/libisccfg.@A@
+IRSDEPLIBS = ../irs/libirs.@A@
+
+DEPLIBS = ${DNSDEPLIBS} ${ISCCFGDEPLIBS} ${ISCDEPLIBS}
+
+LIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@
+
+SUBDIRS =
+
+TARGETS = sample@EXEEXT@ sample-async@EXEEXT@ sample-gai@EXEEXT@ \
+ sample-update@EXEEXT@ sample-request@EXEEXT@ nsprobe@EXEEXT@
+
+OBJS = sample.@O@ sample-async.@O@ sample-gai.@O@ sample-update.@O@ \
+ sample-request.@O@ nsprobe.@O@
+
+UOBJS =
+
+SRCS = sample.c sample-async.c sample-gai.c sample-update.c \
+ sample-request.c nsprobe.c
+
+MANPAGES =
+
+HTMLPAGES =
+
+MANOBJS = ${MANPAGES} ${HTMLPAGES}
+
+@BIND9_MAKE_RULES@
+
+sample@EXEEXT@: sample.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample.@O@ ${LIBS}
+
+sample-async@EXEEXT@: sample-async.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-async.@O@ ${LIBS}
+
+sample-gai@EXEEXT@: sample-gai.@O@ ${IRSDEPLIBS} ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-gai.@O@ ${IRSLIBS} ${LIBS}
+
+sample-update@EXEEXT@: sample-update.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-update.@O@ ${LIBS}
+
+sample-request@EXEEXT@: sample-request.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ sample-request.@O@ ${LIBS}
+
+nsprobe@EXEEXT@: nsprobe.@O@ ${DEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ nsprobe.@O@ ${LIBS}
+
+doc man:: ${MANOBJS}
+
+docclean manclean maintainer-clean::
+ rm -f ${MANOBJS}
+
+clean distclean maintainer-clean::
+ rm -f ${TARGETS}
diff --git a/lib/export/samples/nsprobe.c b/lib/export/samples/nsprobe.c
new file mode 100644
index 000000000000..85c572d0edfb
--- /dev/null
+++ b/lib/export/samples/nsprobe.c
@@ -0,0 +1,1220 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: nsprobe.c,v 1.7 2010-01-07 23:48:54 tbox Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+
+#include <isc/app.h>
+#include <isc/buffer.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/socket.h>
+#include <isc/sockaddr.h>
+#include <isc/string.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/lib.h>
+#include <dns/message.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+
+#define MAX_PROBES 1000
+
+static dns_client_t *client = NULL;
+static isc_task_t *probe_task = NULL;
+static isc_appctx_t *actx = NULL;
+static isc_mem_t *mctx = NULL;
+static unsigned int outstanding_probes = 0;
+const char *cacheserver = "127.0.0.1";
+static FILE *fp;
+
+typedef enum {
+ none,
+ exist,
+ nxdomain,
+ othererr,
+ multiplesoa,
+ multiplecname,
+ brokenanswer,
+ lame,
+ timedout,
+ notype,
+ unexpected
+} query_result_t;
+
+struct server {
+ ISC_LINK(struct server) link;
+
+ isc_sockaddr_t address;
+ query_result_t result_a;
+ query_result_t result_aaaa;
+};
+
+struct probe_ns {
+ ISC_LINK(struct probe_ns) link;
+
+ dns_fixedname_t fixedname;
+ dns_name_t *name;
+ struct server *current_server;
+ ISC_LIST(struct server) servers;
+};
+
+struct probe_trans {
+ isc_boolean_t inuse;
+ char *domain;
+ dns_fixedname_t fixedname;
+ dns_name_t *qname;
+ const char **qlabel;
+ isc_boolean_t qname_found;
+ dns_clientrestrans_t *resid;
+ dns_message_t *qmessage;
+ dns_message_t *rmessage;
+ dns_clientreqtrans_t *reqid;
+
+ /* NS list */
+ struct probe_ns *current_ns;
+ ISC_LIST(struct probe_ns) nslist;
+};
+
+struct lcl_stat {
+ unsigned long valid;
+ unsigned long ignore;
+ unsigned long nxdomain;
+ unsigned long othererr;
+ unsigned long multiplesoa;
+ unsigned long multiplecname;
+ unsigned long brokenanswer;
+ unsigned long lame;
+ unsigned long unknown;
+} server_stat, domain_stat;
+
+static unsigned long number_of_domains = 0;
+static unsigned long number_of_servers = 0;
+static unsigned long multiple_error_domains = 0;
+static isc_boolean_t debug_mode = ISC_FALSE;
+static int verbose_level = 0;
+static const char *qlabels[] = {"www.", "ftp.", NULL};
+static struct probe_trans probes[MAX_PROBES];
+
+static isc_result_t probe_domain(struct probe_trans *trans);
+static void reset_probe(struct probe_trans *trans);
+static isc_result_t fetch_nsaddress(struct probe_trans *trans);
+static isc_result_t probe_name(struct probe_trans *trans,
+ dns_rdatatype_t type);
+
+/* Dump an rdataset for debug */
+static isc_result_t
+print_rdataset(dns_rdataset_t *rdataset, dns_name_t *owner) {
+ isc_buffer_t target;
+ isc_result_t result;
+ isc_region_t r;
+ char t[4096];
+
+ if (!debug_mode)
+ return (ISC_R_SUCCESS);
+
+ isc_buffer_init(&target, t, sizeof(t));
+
+ if (!dns_rdataset_isassociated(rdataset))
+ return (ISC_R_SUCCESS);
+ result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE,
+ &target);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_buffer_usedregion(&target, &r);
+ printf("%.*s", (int)r.length, (char *)r.base);
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+print_name(dns_name_t *name) {
+ isc_result_t result;
+ isc_buffer_t target;
+ isc_region_t r;
+ char t[4096];
+
+ isc_buffer_init(&target, t, sizeof(t));
+ result = dns_name_totext(name, ISC_TRUE, &target);
+ if (result == ISC_R_SUCCESS) {
+ isc_buffer_usedregion(&target, &r);
+ printf("%.*s", (int)r.length, (char *)r.base);
+ } else
+ printf("(invalid name)");
+
+ return (result);
+}
+
+static isc_result_t
+print_address(FILE *fp, isc_sockaddr_t *addr) {
+ char buf[NI_MAXHOST];
+
+ if (getnameinfo(&addr->type.sa, addr->length, buf, sizeof(buf),
+ NULL, 0, NI_NUMERICHOST) == 0) {
+ fprintf(fp, "%s", buf);
+ } else {
+ fprintf(fp, "(invalid address)");
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+ctxs_destroy(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ if (*taskmgrp != NULL)
+ isc_taskmgr_destroy(taskmgrp);
+
+ if (*timermgrp != NULL)
+ isc_timermgr_destroy(timermgrp);
+
+ if (*socketmgrp != NULL)
+ isc_socketmgr_destroy(socketmgrp);
+
+ if (*actxp != NULL)
+ isc_appctx_destroy(actxp);
+
+ if (*mctxp != NULL)
+ isc_mem_destroy(mctxp);
+}
+
+static isc_result_t
+ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ isc_result_t result;
+
+ result = isc_mem_create(0, 0, mctxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_appctx_create(*mctxp, actxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_socketmgr_createinctx(*mctxp, *actxp, socketmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_timermgr_createinctx(*mctxp, *actxp, timermgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ ctxs_destroy(mctxp, actxp, taskmgrp, socketmgrp, timermgrp);
+
+ return (result);
+}
+
+/*
+ * Common routine to make query data
+ */
+static isc_result_t
+make_querymessage(dns_message_t *message, dns_name_t *qname0,
+ dns_rdatatype_t rdtype)
+{
+ dns_name_t *qname = NULL;
+ dns_rdataset_t *qrdataset = NULL;
+ isc_result_t result;
+
+ message->opcode = dns_opcode_query;
+ message->rdclass = dns_rdataclass_in;
+
+ result = dns_message_gettempname(message, &qname);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_message_gettemprdataset(message, &qrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ dns_name_init(qname, NULL);
+ dns_name_clone(qname0, qname);
+ dns_rdataset_init(qrdataset);
+ dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype);
+ ISC_LIST_APPEND(qname->list, qrdataset, link);
+ dns_message_addname(message, qname, DNS_SECTION_QUESTION);
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (qname != NULL)
+ dns_message_puttempname(message, &qname);
+ if (qrdataset != NULL)
+ dns_message_puttemprdataset(message, &qrdataset);
+ if (message != NULL)
+ dns_message_destroy(&message);
+ return (result);
+}
+
+/*
+ * Update statistics
+ */
+static inline void
+increment_entry(unsigned long *entryp) {
+ (*entryp)++;
+ INSIST(*entryp != 0); /* check overflow */
+}
+
+static void
+update_stat(struct probe_trans *trans) {
+ struct probe_ns *pns;
+ struct server *server;
+ struct lcl_stat local_stat;
+ unsigned int err_count = 0;
+ const char *stattype;
+
+ increment_entry(&number_of_domains);
+ memset(&local_stat, 0, sizeof(local_stat));
+
+ /* Update per sever statistics */
+ for (pns = ISC_LIST_HEAD(trans->nslist); pns != NULL;
+ pns = ISC_LIST_NEXT(pns, link)) {
+ for (server = ISC_LIST_HEAD(pns->servers); server != NULL;
+ server = ISC_LIST_NEXT(server, link)) {
+ increment_entry(&number_of_servers);
+
+ if (server->result_aaaa == exist ||
+ server->result_aaaa == notype) {
+ /*
+ * Don't care about the result of A query if
+ * the answer to AAAA query was expected.
+ */
+ stattype = "valid";
+ increment_entry(&server_stat.valid);
+ increment_entry(&local_stat.valid);
+ } else if (server->result_a == exist) {
+ switch (server->result_aaaa) {
+ case exist:
+ case notype:
+ stattype = "valid";
+ increment_entry(&server_stat.valid);
+ increment_entry(&local_stat.valid);
+ break;
+ case timedout:
+ stattype = "ignore";
+ increment_entry(&server_stat.ignore);
+ increment_entry(&local_stat.ignore);
+ break;
+ case nxdomain:
+ stattype = "nxdomain";
+ increment_entry(&server_stat.nxdomain);
+ increment_entry(&local_stat.nxdomain);
+ break;
+ case othererr:
+ stattype = "othererr";
+ increment_entry(&server_stat.othererr);
+ increment_entry(&local_stat.othererr);
+ break;
+ case multiplesoa:
+ stattype = "multiplesoa";
+ increment_entry(&server_stat.multiplesoa);
+ increment_entry(&local_stat.multiplesoa);
+ break;
+ case multiplecname:
+ stattype = "multiplecname";
+ increment_entry(&server_stat.multiplecname);
+ increment_entry(&local_stat.multiplecname);
+ break;
+ case brokenanswer:
+ stattype = "brokenanswer";
+ increment_entry(&server_stat.brokenanswer);
+ increment_entry(&local_stat.brokenanswer);
+ break;
+ case lame:
+ stattype = "lame";
+ increment_entry(&server_stat.lame);
+ increment_entry(&local_stat.lame);
+ break;
+ default:
+ stattype = "unknown";
+ increment_entry(&server_stat.unknown);
+ increment_entry(&local_stat.unknown);
+ break;
+ }
+ } else {
+ stattype = "unknown";
+ increment_entry(&server_stat.unknown);
+ increment_entry(&local_stat.unknown);
+ }
+
+ if (verbose_level > 1 ||
+ (verbose_level == 1 &&
+ strcmp(stattype, "valid") != 0 &&
+ strcmp(stattype, "unknown") != 0)) {
+ print_name(pns->name);
+ putchar('(');
+ print_address(stdout, &server->address);
+ printf(") for %s:%s\n", trans->domain,
+ stattype);
+ }
+ }
+ }
+
+ /* Update per domain statistics */
+ if (local_stat.ignore > 0) {
+ if (verbose_level > 0)
+ printf("%s:ignore\n", trans->domain);
+ increment_entry(&domain_stat.ignore);
+ err_count++;
+ }
+ if (local_stat.nxdomain > 0) {
+ if (verbose_level > 0)
+ printf("%s:nxdomain\n", trans->domain);
+ increment_entry(&domain_stat.nxdomain);
+ err_count++;
+ }
+ if (local_stat.othererr > 0) {
+ if (verbose_level > 0)
+ printf("%s:othererr\n", trans->domain);
+ increment_entry(&domain_stat.othererr);
+ err_count++;
+ }
+ if (local_stat.multiplesoa > 0) {
+ if (verbose_level > 0)
+ printf("%s:multiplesoa\n", trans->domain);
+ increment_entry(&domain_stat.multiplesoa);
+ err_count++;
+ }
+ if (local_stat.multiplecname > 0) {
+ if (verbose_level > 0)
+ printf("%s:multiplecname\n", trans->domain);
+ increment_entry(&domain_stat.multiplecname);
+ err_count++;
+ }
+ if (local_stat.brokenanswer > 0) {
+ if (verbose_level > 0)
+ printf("%s:brokenanswer\n", trans->domain);
+ increment_entry(&domain_stat.brokenanswer);
+ err_count++;
+ }
+ if (local_stat.lame > 0) {
+ if (verbose_level > 0)
+ printf("%s:lame\n", trans->domain);
+ increment_entry(&domain_stat.lame);
+ err_count++;
+ }
+
+ if (err_count > 1)
+ increment_entry(&multiple_error_domains);
+
+ /*
+ * We regard the domain as valid if and only if no authoritative server
+ * has a problem and at least one server is known to be valid.
+ */
+ if (local_stat.valid > 0 && err_count == 0) {
+ if (verbose_level > 1)
+ printf("%s:valid\n", trans->domain);
+ increment_entry(&domain_stat.valid);
+ }
+
+ /*
+ * If the domain has no available server or all servers have the
+ * 'unknown' result, the domain's result is also regarded as unknown.
+ */
+ if (local_stat.valid == 0 && err_count == 0) {
+ if (verbose_level > 1)
+ printf("%s:unknown\n", trans->domain);
+ increment_entry(&domain_stat.unknown);
+ }
+}
+
+/*
+ * Search for an existent name with an A RR
+ */
+
+static isc_result_t
+set_nextqname(struct probe_trans *trans) {
+ isc_result_t result;
+ size_t domainlen;
+ isc_buffer_t b;
+ char buf[4096]; /* XXX ad-hoc constant, but should be enough */
+
+ if (*trans->qlabel == NULL)
+ return (ISC_R_NOMORE);
+
+ result = isc_string_copy(buf, sizeof(buf), *trans->qlabel);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_string_append(buf, sizeof(buf), trans->domain);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ domainlen = strlen(buf);
+ isc_buffer_init(&b, buf, domainlen);
+ isc_buffer_add(&b, domainlen);
+ dns_fixedname_init(&trans->fixedname);
+ trans->qname = dns_fixedname_name(&trans->fixedname);
+ result = dns_name_fromtext(trans->qname, &b, dns_rootname,
+ 0, NULL);
+
+ trans->qlabel++;
+
+ return (result);
+}
+
+static void
+request_done(isc_task_t *task, isc_event_t *event) {
+ struct probe_trans *trans = event->ev_arg;
+ dns_clientreqevent_t *rev = (dns_clientreqevent_t *)event;
+ dns_message_t *rmessage;
+ struct probe_ns *pns;
+ struct server *server;
+ isc_result_t result;
+ query_result_t *resultp;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ dns_rdatatype_t type;
+
+ REQUIRE(task == probe_task);
+ REQUIRE(trans != NULL && trans->inuse == ISC_TRUE);
+ rmessage = rev->rmessage;
+ REQUIRE(rmessage == trans->rmessage);
+ INSIST(outstanding_probes > 0);
+
+ server = trans->current_ns->current_server;
+ INSIST(server != NULL);
+
+ if (server->result_a == none) {
+ type = dns_rdatatype_a;
+ resultp = &server->result_a;
+ } else {
+ resultp = &server->result_aaaa;
+ type = dns_rdatatype_aaaa;
+ }
+
+ if (rev->result == ISC_R_SUCCESS) {
+ if ((rmessage->flags & DNS_MESSAGEFLAG_AA) == 0)
+ *resultp = lame;
+ else if (rmessage->rcode == dns_rcode_nxdomain)
+ *resultp = nxdomain;
+ else if (rmessage->rcode != dns_rcode_noerror)
+ *resultp = othererr;
+ else if (rmessage->counts[DNS_SECTION_ANSWER] == 0) {
+ /* no error but empty answer */
+ *resultp = notype;
+ } else {
+ result = dns_message_firstname(rmessage,
+ DNS_SECTION_ANSWER);
+ while (result == ISC_R_SUCCESS) {
+ name = NULL;
+ dns_message_currentname(rmessage,
+ DNS_SECTION_ANSWER,
+ &name);
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset,
+ link)) {
+ (void)print_rdataset(rdataset, name);
+
+ if (rdataset->type ==
+ dns_rdatatype_cname ||
+ rdataset->type ==
+ dns_rdatatype_dname) {
+ /* Should chase the chain? */
+ *resultp = exist;
+ goto found;
+ } else if (rdataset->type == type) {
+ *resultp = exist;
+ goto found;
+ }
+ }
+ result = dns_message_nextname(rmessage,
+ DNS_SECTION_ANSWER);
+ }
+
+ /*
+ * Something unexpected happened: the response
+ * contained a non-empty authoritative answer, but we
+ * could not find an expected result.
+ */
+ *resultp = unexpected;
+ }
+ } else if (rev->result == DNS_R_RECOVERABLE ||
+ rev->result == DNS_R_BADLABELTYPE) {
+ /* Broken response. Try identifying known cases. */
+ *resultp = brokenanswer;
+
+ if (rmessage->counts[DNS_SECTION_ANSWER] > 0) {
+ result = dns_message_firstname(rmessage,
+ DNS_SECTION_ANSWER);
+ while (result == ISC_R_SUCCESS) {
+ /*
+ * Check to see if the response has multiple
+ * CNAME RRs. Update the result code if so.
+ */
+ name = NULL;
+ dns_message_currentname(rmessage,
+ DNS_SECTION_ANSWER,
+ &name);
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset,
+ link)) {
+ if (rdataset->type ==
+ dns_rdatatype_cname &&
+ dns_rdataset_count(rdataset) > 1) {
+ *resultp = multiplecname;
+ goto found;
+ }
+ }
+ result = dns_message_nextname(rmessage,
+ DNS_SECTION_ANSWER);
+ }
+ }
+
+ if (rmessage->counts[DNS_SECTION_AUTHORITY] > 0) {
+ result = dns_message_firstname(rmessage,
+ DNS_SECTION_AUTHORITY);
+ while (result == ISC_R_SUCCESS) {
+ /*
+ * Check to see if the response has multiple
+ * SOA RRs. Update the result code if so.
+ */
+ name = NULL;
+ dns_message_currentname(rmessage,
+ DNS_SECTION_AUTHORITY,
+ &name);
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset,
+ link)) {
+ if (rdataset->type ==
+ dns_rdatatype_soa &&
+ dns_rdataset_count(rdataset) > 1) {
+ *resultp = multiplesoa;
+ goto found;
+ }
+ }
+ result = dns_message_nextname(rmessage,
+ DNS_SECTION_AUTHORITY);
+ }
+ }
+ } else if (rev->result == ISC_R_TIMEDOUT)
+ *resultp = timedout;
+ else {
+ fprintf(stderr, "unexpected result: %d (domain=%s, server=",
+ rev->result, trans->domain);
+ print_address(stderr, &server->address);
+ fputc('\n', stderr);
+ *resultp = unexpected;
+ }
+
+ found:
+ INSIST(*resultp != none);
+ if (type == dns_rdatatype_a && *resultp == exist)
+ trans->qname_found = ISC_TRUE;
+
+ dns_client_destroyreqtrans(&trans->reqid);
+ isc_event_free(&event);
+ dns_message_reset(trans->rmessage, DNS_MESSAGE_INTENTPARSE);
+
+ result = probe_name(trans, type);
+ if (result == ISC_R_NOMORE) {
+ /* We've tried all addresses of all servers. */
+ if (type == dns_rdatatype_a && trans->qname_found) {
+ /*
+ * If we've explored A RRs and found an existent
+ * record, we can move to AAAA.
+ */
+ trans->current_ns = ISC_LIST_HEAD(trans->nslist);
+ probe_name(trans, dns_rdatatype_aaaa);
+ result = ISC_R_SUCCESS;
+ } else if (type == dns_rdatatype_a) {
+ /*
+ * No server provided an existent A RR of this name.
+ * Try next label.
+ */
+ dns_fixedname_invalidate(&trans->fixedname);
+ trans->qname = NULL;
+ result = set_nextqname(trans);
+ if (result == ISC_R_SUCCESS) {
+ trans->current_ns =
+ ISC_LIST_HEAD(trans->nslist);
+ for (pns = trans->current_ns; pns != NULL;
+ pns = ISC_LIST_NEXT(pns, link)) {
+ for (server = ISC_LIST_HEAD(pns->servers);
+ server != NULL;
+ server = ISC_LIST_NEXT(server,
+ link)) {
+ INSIST(server->result_aaaa ==
+ none);
+ server->result_a = none;
+ }
+ }
+ result = probe_name(trans, dns_rdatatype_a);
+ }
+ }
+ if (result != ISC_R_SUCCESS) {
+ /*
+ * We've explored AAAA RRs or failed to find a valid
+ * query label. Wrap up the result and move to the
+ * next domain.
+ */
+ reset_probe(trans);
+ }
+ } else if (result != ISC_R_SUCCESS)
+ reset_probe(trans); /* XXX */
+}
+
+static isc_result_t
+probe_name(struct probe_trans *trans, dns_rdatatype_t type) {
+ isc_result_t result;
+ struct probe_ns *pns;
+ struct server *server;
+
+ REQUIRE(trans->reqid == NULL);
+ REQUIRE(type == dns_rdatatype_a || type == dns_rdatatype_aaaa);
+
+ for (pns = trans->current_ns; pns != NULL;
+ pns = ISC_LIST_NEXT(pns, link)) {
+ for (server = ISC_LIST_HEAD(pns->servers); server != NULL;
+ server = ISC_LIST_NEXT(server, link)) {
+ if ((type == dns_rdatatype_a &&
+ server->result_a == none) ||
+ (type == dns_rdatatype_aaaa &&
+ server->result_aaaa == none)) {
+ pns->current_server = server;
+ goto found;
+ }
+ }
+ }
+
+ found:
+ trans->current_ns = pns;
+ if (pns == NULL)
+ return (ISC_R_NOMORE);
+
+ INSIST(pns->current_server != NULL);
+ dns_message_reset(trans->qmessage, DNS_MESSAGE_INTENTRENDER);
+ result = make_querymessage(trans->qmessage, trans->qname, type);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = dns_client_startrequest(client, trans->qmessage,
+ trans->rmessage,
+ &pns->current_server->address,
+ 0, DNS_MESSAGEPARSE_BESTEFFORT,
+ NULL, 120, 0, 4,
+ probe_task, request_done, trans,
+ &trans->reqid);
+
+ return (result);
+}
+
+/*
+ * Get IP addresses of NSes
+ */
+
+static void
+resolve_nsaddress(isc_task_t *task, isc_event_t *event) {
+ struct probe_trans *trans = event->ev_arg;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ struct probe_ns *pns = trans->current_ns;
+ isc_result_t result;
+
+ REQUIRE(task == probe_task);
+ REQUIRE(trans->inuse == ISC_TRUE);
+ REQUIRE(pns != NULL);
+ INSIST(outstanding_probes > 0);
+
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ (void)print_rdataset(rdataset, name);
+
+ if (rdataset->type != dns_rdatatype_a)
+ continue;
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_in_a_t rdata_a;
+ struct server *server;
+
+ dns_rdataset_current(rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &rdata_a,
+ NULL);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ server = isc_mem_get(mctx, sizeof(*server));
+ if (server == NULL) {
+ fprintf(stderr, "resolve_nsaddress: "
+ "mem_get failed");
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ isc_sockaddr_fromin(&server->address,
+ &rdata_a.in_addr, 53);
+ ISC_LINK_INIT(server, link);
+ server->result_a = none;
+ server->result_aaaa = none;
+ ISC_LIST_APPEND(pns->servers, server, link);
+ }
+ }
+ }
+
+ cleanup:
+ dns_client_freeresanswer(client, &rev->answerlist);
+ dns_client_destroyrestrans(&trans->resid);
+ isc_event_free(&event);
+
+ next_ns:
+ trans->current_ns = ISC_LIST_NEXT(pns, link);
+ if (trans->current_ns == NULL) {
+ trans->current_ns = ISC_LIST_HEAD(trans->nslist);
+ dns_fixedname_invalidate(&trans->fixedname);
+ trans->qname = NULL;
+ result = set_nextqname(trans);
+ if (result == ISC_R_SUCCESS)
+ result = probe_name(trans, dns_rdatatype_a);
+ } else {
+ result = fetch_nsaddress(trans);
+ if (result != ISC_R_SUCCESS)
+ goto next_ns; /* XXX: this is unlikely to succeed */
+ }
+
+ if (result != ISC_R_SUCCESS)
+ reset_probe(trans);
+}
+
+static isc_result_t
+fetch_nsaddress(struct probe_trans *trans) {
+ struct probe_ns *pns;
+
+ pns = trans->current_ns;
+ REQUIRE(pns != NULL);
+
+ return (dns_client_startresolve(client, pns->name, dns_rdataclass_in,
+ dns_rdatatype_a, 0, probe_task,
+ resolve_nsaddress, trans,
+ &trans->resid));
+}
+
+/*
+ * Get NS RRset for a given domain
+ */
+
+static void
+reset_probe(struct probe_trans *trans) {
+ struct probe_ns *pns;
+ struct server *server;
+ isc_result_t result;
+
+ REQUIRE(trans->resid == NULL);
+ REQUIRE(trans->reqid == NULL);
+
+ update_stat(trans);
+
+ dns_message_reset(trans->qmessage, DNS_MESSAGE_INTENTRENDER);
+ dns_message_reset(trans->rmessage, DNS_MESSAGE_INTENTPARSE);
+
+ trans->inuse = ISC_FALSE;
+ if (trans->domain != NULL)
+ isc_mem_free(mctx, trans->domain);
+ trans->domain = NULL;
+ if (trans->qname != NULL)
+ dns_fixedname_invalidate(&trans->fixedname);
+ trans->qname = NULL;
+ trans->qlabel = qlabels;
+ trans->qname_found = ISC_FALSE;
+ trans->current_ns = NULL;
+
+ while ((pns = ISC_LIST_HEAD(trans->nslist)) != NULL) {
+ ISC_LIST_UNLINK(trans->nslist, pns, link);
+ while ((server = ISC_LIST_HEAD(pns->servers)) != NULL) {
+ ISC_LIST_UNLINK(pns->servers, server, link);
+ isc_mem_put(mctx, server, sizeof(*server));
+ }
+ isc_mem_put(mctx, pns, sizeof(*pns));
+ }
+
+ outstanding_probes--;
+
+ result = probe_domain(trans);
+ if (result == ISC_R_NOMORE && outstanding_probes == 0)
+ isc_app_ctxshutdown(actx);
+}
+
+static void
+resolve_ns(isc_task_t *task, isc_event_t *event) {
+ struct probe_trans *trans = event->ev_arg;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ isc_result_t result = ISC_R_SUCCESS;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ struct probe_ns *pns;
+
+ REQUIRE(task == probe_task);
+ REQUIRE(trans->inuse == ISC_TRUE);
+ INSIST(outstanding_probes > 0);
+
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ (void)print_rdataset(rdataset, name);
+
+ if (rdataset->type != dns_rdatatype_ns)
+ continue;
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_rdata_ns_t ns;
+
+ dns_rdataset_current(rdataset, &rdata);
+ /*
+ * Extract the name from the NS record.
+ */
+ result = dns_rdata_tostruct(&rdata, &ns, NULL);
+ if (result != ISC_R_SUCCESS)
+ continue;
+
+ pns = isc_mem_get(mctx, sizeof(*pns));
+ if (pns == NULL) {
+ fprintf(stderr,
+ "resolve_ns: mem_get failed");
+ result = ISC_R_NOMEMORY;
+ /*
+ * XXX: should we continue with the
+ * available servers anyway?
+ */
+ goto cleanup;
+ }
+
+ dns_fixedname_init(&pns->fixedname);
+ pns->name =
+ dns_fixedname_name(&pns->fixedname);
+ ISC_LINK_INIT(pns, link);
+ ISC_LIST_APPEND(trans->nslist, pns, link);
+ ISC_LIST_INIT(pns->servers);
+
+ dns_name_copy(&ns.name, pns->name, NULL);
+ dns_rdata_reset(&rdata);
+ dns_rdata_freestruct(&ns);
+ }
+ }
+ }
+
+ cleanup:
+ dns_client_freeresanswer(client, &rev->answerlist);
+ dns_client_destroyrestrans(&trans->resid);
+ isc_event_free(&event);
+
+ if (!ISC_LIST_EMPTY(trans->nslist)) {
+ /* Go get addresses of NSes */
+ trans->current_ns = ISC_LIST_HEAD(trans->nslist);
+ result = fetch_nsaddress(trans);
+ } else
+ result = ISC_R_FAILURE;
+
+ if (result == ISC_R_SUCCESS)
+ return;
+
+ reset_probe(trans);
+}
+
+static isc_result_t
+probe_domain(struct probe_trans *trans) {
+ isc_result_t result;
+ size_t domainlen;
+ isc_buffer_t b;
+ char buf[4096]; /* XXX ad hoc constant, but should be enough */
+ char *cp;
+
+ REQUIRE(trans != NULL);
+ REQUIRE(trans->inuse == ISC_FALSE);
+ REQUIRE(outstanding_probes < MAX_PROBES);
+
+ /* Construct domain */
+ cp = fgets(buf, sizeof(buf), fp);
+ if (cp == NULL)
+ return (ISC_R_NOMORE);
+ if ((cp = strchr(buf, '\n')) != NULL) /* zap NL if any */
+ *cp = '\0';
+ trans->domain = isc_mem_strdup(mctx, buf);
+ if (trans->domain == NULL) {
+ fprintf(stderr,
+ "failed to allocate memory for domain: %s", cp);
+ return (ISC_R_NOMEMORY);
+ }
+
+ /* Start getting NS for the domain */
+ domainlen = strlen(buf);
+ isc_buffer_init(&b, buf, domainlen);
+ isc_buffer_add(&b, domainlen);
+ dns_fixedname_init(&trans->fixedname);
+ trans->qname = dns_fixedname_name(&trans->fixedname);
+ result = dns_name_fromtext(trans->qname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_client_startresolve(client, trans->qname,
+ dns_rdataclass_in, dns_rdatatype_ns,
+ 0, probe_task, resolve_ns, trans,
+ &trans->resid);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ trans->inuse = ISC_TRUE;
+ outstanding_probes++;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ isc_mem_free(mctx, trans->domain);
+ dns_fixedname_invalidate(&trans->fixedname);
+
+ return (result);
+}
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "usage: nsprobe [-d] [-v [-v...]] [-c cache_address] "
+ "[input_file]\n");
+
+ exit(1);
+}
+
+int
+main(int argc, char *argv[]) {
+ int i, ch, error;
+ struct addrinfo hints, *res;
+ isc_result_t result;
+ isc_sockaddr_t sa;
+ isc_sockaddrlist_t servers;
+ isc_taskmgr_t *taskmgr = NULL;
+ isc_socketmgr_t *socketmgr = NULL;
+ isc_timermgr_t *timermgr = NULL;
+
+ while ((ch = getopt(argc, argv, "c:dhv")) != -1) {
+ switch (ch) {
+ case 'c':
+ cacheserver = optarg;
+ break;
+ case 'd':
+ debug_mode = ISC_TRUE;
+ break;
+ case 'h':
+ usage();
+ break;
+ case 'v':
+ verbose_level++;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ /* Common set up */
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_lib_init failed: %d\n", result);
+ exit(1);
+ }
+
+ result = ctxs_init(&mctx, &actx, &taskmgr, &socketmgr,
+ &timermgr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "ctx create failed: %d\n", result);
+ exit(1);
+ }
+
+ isc_app_ctxstart(actx);
+
+ result = dns_client_createx(mctx, actx, taskmgr, socketmgr,
+ timermgr, 0, &client);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_client_createx failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Set local cache server */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ error = getaddrinfo(cacheserver, "53", &hints, &res);
+ if (error != 0) {
+ fprintf(stderr, "failed to convert server name (%s): %s\n",
+ cacheserver, gai_strerror(error));
+ exit(1);
+ }
+
+ if (res->ai_addrlen > sizeof(sa.type)) {
+ fprintf(stderr,
+ "assumption failure: addrlen is too long: %d\n",
+ res->ai_addrlen);
+ exit(1);
+ }
+ memcpy(&sa.type.sa, res->ai_addr, res->ai_addrlen);
+ sa.length = res->ai_addrlen;
+ freeaddrinfo(res);
+ ISC_LINK_INIT(&sa, link);
+ ISC_LIST_INIT(servers);
+ ISC_LIST_APPEND(servers, &sa, link);
+ result = dns_client_setservers(client, dns_rdataclass_in, NULL,
+ &servers);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to set server: %d\n", result);
+ exit(1);
+ }
+
+ /* Create the main task */
+ probe_task = NULL;
+ result = isc_task_create(taskmgr, 0, &probe_task);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to create task: %d\n", result);
+ exit(1);
+ }
+
+ /* Open input file */
+ if (argc == 0)
+ fp = stdin;
+ else {
+ fp = fopen(argv[0], "r");
+ if (fp == NULL) {
+ fprintf(stderr, "failed to open input file: %s\n",
+ argv[0]);
+ exit(1);
+ }
+ }
+
+ /* Set up and start probe */
+ for (i = 0; i < MAX_PROBES; i++) {
+ probes[i].inuse = ISC_FALSE;
+ probes[i].domain = NULL;
+ dns_fixedname_init(&probes[i].fixedname);
+ probes[i].qname = NULL;
+ probes[i].qlabel = qlabels;
+ probes[i].qname_found = ISC_FALSE;
+ probes[i].resid = NULL;
+ ISC_LIST_INIT(probes[i].nslist);
+ probes[i].reqid = NULL;
+
+ probes[i].qmessage = NULL;
+ result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER,
+ &probes[i].qmessage);
+ if (result == ISC_R_SUCCESS) {
+ result = dns_message_create(mctx,
+ DNS_MESSAGE_INTENTPARSE,
+ &probes[i].rmessage);
+ }
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "initialization failure\n");
+ exit(1);
+ }
+ }
+ for (i = 0; i < MAX_PROBES; i++) {
+ result = probe_domain(&probes[i]);
+ if (result == ISC_R_NOMORE)
+ break;
+ else if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to issue an initial probe\n");
+ exit(1);
+ }
+ }
+
+ /* Start event loop */
+ isc_app_ctxrun(actx);
+
+ /* Dump results */
+ printf("Per domain results (out of %lu domains):\n",
+ number_of_domains);
+ printf(" valid: %lu\n"
+ " ignore: %lu\n"
+ " nxdomain: %lu\n"
+ " othererr: %lu\n"
+ " multiplesoa: %lu\n"
+ " multiplecname: %lu\n"
+ " brokenanswer: %lu\n"
+ " lame: %lu\n"
+ " unknown: %lu\n"
+ " multiple errors: %lu\n",
+ domain_stat.valid, domain_stat.ignore, domain_stat.nxdomain,
+ domain_stat.othererr, domain_stat.multiplesoa,
+ domain_stat.multiplecname, domain_stat.brokenanswer,
+ domain_stat.lame, domain_stat.unknown, multiple_error_domains);
+ printf("Per server results (out of %lu servers):\n",
+ number_of_servers);
+ printf(" valid: %lu\n"
+ " ignore: %lu\n"
+ " nxdomain: %lu\n"
+ " othererr: %lu\n"
+ " multiplesoa: %lu\n"
+ " multiplecname: %lu\n"
+ " brokenanswer: %lu\n"
+ " lame: %lu\n"
+ " unknown: %lu\n",
+ server_stat.valid, server_stat.ignore, server_stat.nxdomain,
+ server_stat.othererr, server_stat.multiplesoa,
+ server_stat.multiplecname, server_stat.brokenanswer,
+ server_stat.lame, server_stat.unknown);
+
+ /* Cleanup */
+ for (i = 0; i < MAX_PROBES; i++) {
+ dns_message_destroy(&probes[i].qmessage);
+ dns_message_destroy(&probes[i].rmessage);
+ }
+ isc_task_detach(&probe_task);
+ dns_client_destroy(&client);
+ dns_lib_shutdown();
+ isc_app_ctxfinish(actx);
+ ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
+
+ exit(0);
+}
diff --git a/lib/export/samples/sample-async.c b/lib/export/samples/sample-async.c
new file mode 100644
index 000000000000..19c0bbaefa14
--- /dev/null
+++ b/lib/export/samples/sample-async.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: sample-async.c,v 1.5 2009-09-29 15:06:07 fdupont Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <isc/app.h>
+#include <isc/buffer.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/socket.h>
+#include <isc/sockaddr.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/lib.h>
+#include <dns/name.h>
+#include <dns/rdataset.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+
+#define MAX_SERVERS 10
+#define MAX_QUERIES 100
+
+static dns_client_t *client = NULL;
+static isc_task_t *query_task = NULL;
+static isc_appctx_t *query_actx = NULL;
+static unsigned int outstanding_queries = 0;
+static const char *def_server = "127.0.0.1";
+static FILE *fp;
+
+struct query_trans {
+ int id;
+ isc_boolean_t inuse;
+ dns_rdatatype_t type;
+ dns_fixedname_t fixedname;
+ dns_name_t *qname;
+ dns_namelist_t answerlist;
+ dns_clientrestrans_t *xid;
+};
+
+static struct query_trans query_array[MAX_QUERIES];
+
+static isc_result_t dispatch_query(struct query_trans *trans);
+
+static void
+ctxs_destroy(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ if (*taskmgrp != NULL)
+ isc_taskmgr_destroy(taskmgrp);
+
+ if (*timermgrp != NULL)
+ isc_timermgr_destroy(timermgrp);
+
+ if (*socketmgrp != NULL)
+ isc_socketmgr_destroy(socketmgrp);
+
+ if (*actxp != NULL)
+ isc_appctx_destroy(actxp);
+
+ if (*mctxp != NULL)
+ isc_mem_destroy(mctxp);
+}
+
+static isc_result_t
+ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ isc_result_t result;
+
+ result = isc_mem_create(0, 0, mctxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_appctx_create(*mctxp, actxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_socketmgr_createinctx(*mctxp, *actxp, socketmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_timermgr_createinctx(*mctxp, *actxp, timermgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ ctxs_destroy(mctxp, actxp, taskmgrp, socketmgrp, timermgrp);
+
+ return (result);
+}
+
+static isc_result_t
+printdata(dns_rdataset_t *rdataset, dns_name_t *owner) {
+ isc_buffer_t target;
+ isc_result_t result;
+ isc_region_t r;
+ char t[4096];
+
+ isc_buffer_init(&target, t, sizeof(t));
+
+ if (!dns_rdataset_isassociated(rdataset))
+ return (ISC_R_SUCCESS);
+ result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE,
+ &target);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_buffer_usedregion(&target, &r);
+ printf(" %.*s", (int)r.length, (char *)r.base);
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+process_answer(isc_task_t *task, isc_event_t *event) {
+ struct query_trans *trans = event->ev_arg;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_name_t *name;
+ dns_rdataset_t *rdataset;
+ isc_result_t result;
+
+ REQUIRE(task == query_task);
+ REQUIRE(trans->inuse == ISC_TRUE);
+ REQUIRE(outstanding_queries > 0);
+
+ printf("answer[%2d]\n", trans->id);
+
+ if (rev->result != ISC_R_SUCCESS)
+ printf(" failed: %d(%s)\n", rev->result,
+ dns_result_totext(rev->result));
+
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ (void)printdata(rdataset, name);
+ }
+ }
+
+ dns_client_freeresanswer(client, &rev->answerlist);
+ dns_client_destroyrestrans(&trans->xid);
+
+ isc_event_free(&event);
+
+ trans->inuse = ISC_FALSE;
+ dns_fixedname_invalidate(&trans->fixedname);
+ trans->qname = NULL;
+ outstanding_queries--;
+
+ result = dispatch_query(trans);
+#if 0 /* for cancel test */
+ if (result == ISC_R_SUCCESS) {
+ static int count = 0;
+
+ if ((++count) % 10 == 0)
+ dns_client_cancelresolve(trans->xid);
+ }
+#endif
+ if (result == ISC_R_NOMORE && outstanding_queries == 0)
+ isc_app_ctxshutdown(query_actx);
+}
+
+static isc_result_t
+dispatch_query(struct query_trans *trans) {
+ isc_result_t result;
+ size_t namelen;
+ isc_buffer_t b;
+ char buf[4096]; /* XXX ad hoc constant, but should be enough */
+ char *cp;
+
+ REQUIRE(trans != NULL);
+ REQUIRE(trans->inuse == ISC_FALSE);
+ REQUIRE(ISC_LIST_EMPTY(trans->answerlist));
+ REQUIRE(outstanding_queries < MAX_QUERIES);
+
+ /* Construct qname */
+ cp = fgets(buf, sizeof(buf), fp);
+ if (cp == NULL)
+ return (ISC_R_NOMORE);
+ /* zap NL if any */
+ if ((cp = strchr(buf, '\n')) != NULL)
+ *cp = '\0';
+ namelen = strlen(buf);
+ isc_buffer_init(&b, buf, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&trans->fixedname);
+ trans->qname = dns_fixedname_name(&trans->fixedname);
+ result = dns_name_fromtext(trans->qname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Start resolution */
+ result = dns_client_startresolve(client, trans->qname,
+ dns_rdataclass_in, trans->type, 0,
+ query_task, process_answer, trans,
+ &trans->xid);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ trans->inuse = ISC_TRUE;
+ outstanding_queries++;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ dns_fixedname_invalidate(&trans->fixedname);
+
+ return (result);
+}
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "usage: sample-async [-s server_address] [-t RR type] "
+ "input_file\n");
+
+ exit(1);
+}
+
+int
+main(int argc, char *argv[]) {
+ int ch;
+ isc_textregion_t tr;
+ isc_mem_t *mctx = NULL;
+ isc_taskmgr_t *taskmgr = NULL;
+ isc_socketmgr_t *socketmgr = NULL;
+ isc_timermgr_t *timermgr = NULL;
+ int nservers = 0;
+ const char *serveraddr[MAX_SERVERS];
+ isc_sockaddr_t sa[MAX_SERVERS];
+ isc_sockaddrlist_t servers;
+ dns_rdatatype_t type = dns_rdatatype_a;
+ struct in_addr inaddr;
+ isc_result_t result;
+ int i;
+
+ while ((ch = getopt(argc, argv, "s:t:")) != -1) {
+ switch (ch) {
+ case 't':
+ tr.base = optarg;
+ tr.length = strlen(optarg);
+ result = dns_rdatatype_fromtext(&type, &tr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr,
+ "invalid RRtype: %s\n", optarg);
+ exit(1);
+ }
+ break;
+ case 's':
+ if (nservers == MAX_SERVERS) {
+ fprintf(stderr,
+ "too many servers (up to %d)\n",
+ MAX_SERVERS);
+ exit(1);
+ }
+ serveraddr[nservers++] = (const char *)optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc < 1)
+ usage();
+
+ if (nservers == 0) {
+ nservers = 1;
+ serveraddr[0] = def_server;
+ }
+
+ for (i = 0; i < MAX_QUERIES; i++) {
+ query_array[i].id = i;
+ query_array[i].inuse = ISC_FALSE;
+ query_array[i].type = type;
+ dns_fixedname_init(&query_array[i].fixedname);
+ query_array[i].qname = NULL;
+ ISC_LIST_INIT(query_array[i].answerlist);
+ query_array[i].xid = NULL;
+ }
+
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_lib_init failed: %d\n", result);
+ exit(1);
+ }
+
+ result = ctxs_init(&mctx, &query_actx, &taskmgr, &socketmgr,
+ &timermgr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "ctx create failed: %d\n", result);
+ exit(1);
+ }
+
+ isc_app_ctxstart(query_actx);
+
+ result = dns_client_createx(mctx, query_actx, taskmgr, socketmgr,
+ timermgr, 0, &client);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_client_createx failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Set nameservers */
+ ISC_LIST_INIT(servers);
+ for (i = 0; i < nservers; i++) {
+ if (inet_pton(AF_INET, serveraddr[i], &inaddr) != 1) {
+ fprintf(stderr, "failed to parse IPv4 address %s\n",
+ serveraddr[i]);
+ exit(1);
+ }
+ isc_sockaddr_fromin(&sa[i], &inaddr, 53);
+ ISC_LIST_APPEND(servers, &sa[i], link);
+ }
+ result = dns_client_setservers(client, dns_rdataclass_in, NULL,
+ &servers);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "set server failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Create the main task */
+ query_task = NULL;
+ result = isc_task_create(taskmgr, 0, &query_task);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to create task: %d\n", result);
+ exit(1);
+ }
+
+ /* Open input file */
+ fp = fopen(argv[0], "r");
+ if (fp == NULL) {
+ fprintf(stderr, "failed to open input file: %s\n", argv[1]);
+ exit(1);
+ }
+
+ /* Dispatch initial queries */
+ for (i = 0; i < MAX_QUERIES; i++) {
+ result = dispatch_query(&query_array[i]);
+ if (result == ISC_R_NOMORE)
+ break;
+ }
+
+ /* Start event loop */
+ isc_app_ctxrun(query_actx);
+
+ /* Sanity check */
+ for (i = 0; i < MAX_QUERIES; i++)
+ INSIST(query_array[i].inuse == ISC_FALSE);
+
+ /* Cleanup */
+ isc_task_detach(&query_task);
+ dns_client_destroy(&client);
+ dns_lib_shutdown();
+ isc_app_ctxfinish(query_actx);
+ ctxs_destroy(&mctx, &query_actx, &taskmgr, &socketmgr, &timermgr);
+
+ exit(0);
+}
diff --git a/lib/export/samples/sample-gai.c b/lib/export/samples/sample-gai.c
new file mode 100644
index 000000000000..7c07f1bcbc0a
--- /dev/null
+++ b/lib/export/samples/sample-gai.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: sample-gai.c,v 1.4 2009-09-02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <irs/netdb.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+static void
+do_gai(int family, char *hostname) {
+ struct addrinfo hints, *res, *res0;
+ int error;
+ char namebuf[1024], addrbuf[1024], servbuf[1024];
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_CANONNAME;
+ error = getaddrinfo(hostname, "http", &hints, &res0);
+ if (error) {
+ fprintf(stderr, "getaddrinfo failed for %s,family=%d: %s\n",
+ hostname, family, gai_strerror(error));
+ return;
+ }
+
+ for (res = res0; res; res = res->ai_next) {
+ error = getnameinfo(res->ai_addr, res->ai_addrlen,
+ addrbuf, sizeof(addrbuf),
+ NULL, 0, NI_NUMERICHOST);
+ if (error == 0)
+ error = getnameinfo(res->ai_addr, res->ai_addrlen,
+ namebuf, sizeof(namebuf),
+ servbuf, sizeof(servbuf), 0);
+ if (error != 0) {
+ fprintf(stderr, "getnameinfo failed: %s\n",
+ gai_strerror(error));
+ } else {
+ printf("%s(%s/%s)=%s:%s\n", hostname,
+ res->ai_canonname, addrbuf, namebuf, servbuf);
+ }
+ }
+
+ freeaddrinfo(res);
+}
+
+int
+main(int argc, char *argv[]) {
+ if (argc < 2)
+ exit(1);
+
+ do_gai(AF_INET, argv[1]);
+ do_gai(AF_INET6, argv[1]);
+ do_gai(AF_UNSPEC, argv[1]);
+
+ exit(0);
+}
diff --git a/lib/export/samples/sample-request.c b/lib/export/samples/sample-request.c
new file mode 100644
index 000000000000..433149862ec1
--- /dev/null
+++ b/lib/export/samples/sample-request.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: sample-request.c,v 1.5 2009-09-29 15:06:07 fdupont Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/keyvalues.h>
+#include <dns/lib.h>
+#include <dns/masterdump.h>
+#include <dns/message.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+#include <dns/secalg.h>
+
+#include <dst/dst.h>
+
+static isc_mem_t *mctx;
+static dns_fixedname_t fixedqname;
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "sample-request [-t RRtype] server_address hostname\n");
+
+ exit(1);
+}
+
+static isc_result_t
+make_querymessage(dns_message_t *message, const char *namestr,
+ dns_rdatatype_t rdtype)
+{
+ dns_name_t *qname = NULL, *qname0;
+ dns_rdataset_t *qrdataset = NULL;
+ isc_result_t result;
+ isc_buffer_t b;
+ size_t namelen;
+
+ /* Construct qname */
+ namelen = strlen(namestr);
+ isc_buffer_init(&b, namestr, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&fixedqname);
+ qname0 = dns_fixedname_name(&fixedqname);
+ result = dns_name_fromtext(qname0, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to convert qname: %d\n", result);
+ return (result);
+ }
+
+ /* Construct query message */
+ message->opcode = dns_opcode_query;
+ message->rdclass = dns_rdataclass_in;
+
+ result = dns_message_gettempname(message, &qname);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = dns_message_gettemprdataset(message, &qrdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ dns_name_init(qname, NULL);
+ dns_name_clone(qname0, qname);
+ dns_rdataset_init(qrdataset);
+ dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype);
+ ISC_LIST_APPEND(qname->list, qrdataset, link);
+ dns_message_addname(message, qname, DNS_SECTION_QUESTION);
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (qname != NULL)
+ dns_message_puttempname(message, &qname);
+ if (qrdataset != NULL)
+ dns_message_puttemprdataset(message, &qrdataset);
+ if (message != NULL)
+ dns_message_destroy(&message);
+ return (result);
+}
+
+static void
+print_section(dns_message_t *message, int section, isc_buffer_t *buf) {
+ isc_result_t result;
+ isc_region_t r;
+
+ result = dns_message_sectiontotext(message, section,
+ &dns_master_style_full, 0, buf);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ isc_buffer_usedregion(buf, &r);
+ printf("%.*s", (int)r.length, (char *)r.base);
+
+ return;
+
+ fail:
+ fprintf(stderr, "failed to convert a section\n");
+}
+
+int
+main(int argc, char *argv[]) {
+ int ch, i, gai_error;
+ struct addrinfo hints, *res;
+ isc_textregion_t tr;
+ dns_client_t *client = NULL;
+ isc_result_t result;
+ isc_sockaddr_t sa;
+ dns_message_t *qmessage, *rmessage;
+ dns_rdatatype_t type = dns_rdatatype_a;
+ isc_buffer_t *outputbuf;
+
+ while ((ch = getopt(argc, argv, "t:")) != -1) {
+ switch (ch) {
+ case 't':
+ tr.base = optarg;
+ tr.length = strlen(optarg);
+ result = dns_rdatatype_fromtext(&type, &tr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr,
+ "invalid RRtype: %s\n", optarg);
+ exit(1);
+ }
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc < 2)
+ usage();
+
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_lib_init failed: %d\n", result);
+ exit(1);
+ }
+
+ result = dns_client_create(&client, 0);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_client_create failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Prepare message structures */
+ mctx = NULL;
+ qmessage = NULL;
+ rmessage = NULL;
+
+ result = isc_mem_create(0, 0, &mctx);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to create a memory context\n");
+ exit(1);
+ }
+ result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &qmessage);
+ if (result == ISC_R_SUCCESS) {
+ result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
+ &rmessage);
+ }
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to create messages\n");
+ exit(1);
+ }
+
+ /* Initialize the nameserver address */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST;
+ gai_error = getaddrinfo(argv[0], "53", &hints, &res);
+ if (gai_error != 0) {
+ fprintf(stderr, "getaddrinfo failed: %s\n",
+ gai_strerror(gai_error));
+ exit(1);
+ }
+ INSIST(res->ai_addrlen <= sizeof(sa.type));
+ memcpy(&sa.type, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ sa.length = res->ai_addrlen;
+ ISC_LINK_INIT(&sa, link);
+
+ /* Construct qname */
+ result = make_querymessage(qmessage, argv[1], type);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to create a query\n");
+ exit(1);
+ }
+
+ /* Send request and wait for a response */
+ result = dns_client_request(client, qmessage, rmessage, &sa, 0, 0,
+ NULL, 60, 0, 3);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to get a response: %s\n",
+ dns_result_totext(result));
+ }
+
+ /* Dump the response */
+ outputbuf = NULL;
+ result = isc_buffer_allocate(mctx, &outputbuf, 65535);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to allocate a result buffer\n");
+ exit(1);
+ }
+ for (i = 0; i < DNS_SECTION_MAX; i++) {
+ print_section(rmessage, i, outputbuf);
+ isc_buffer_clear(outputbuf);
+ }
+ isc_buffer_free(&outputbuf);
+
+ /* Cleanup */
+ dns_message_destroy(&qmessage);
+ dns_message_destroy(&rmessage);
+ isc_mem_destroy(&mctx);
+ dns_client_destroy(&client);
+ dns_lib_shutdown();
+
+ exit(0);
+}
diff --git a/lib/export/samples/sample-update.c b/lib/export/samples/sample-update.c
new file mode 100644
index 000000000000..eef0a587d2af
--- /dev/null
+++ b/lib/export/samples/sample-update.c
@@ -0,0 +1,755 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: sample-update.c,v 1.10 2010-12-09 00:54:34 marka Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <unistd.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <isc/buffer.h>
+#include <isc/lex.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/parseint.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <dns/callbacks.h>
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/lib.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+#include <dns/rdatalist.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+#include <dns/secalg.h>
+#include <dns/tsec.h>
+
+#include <dst/dst.h>
+
+static dns_tsec_t *tsec = NULL;
+static const dns_rdataclass_t default_rdataclass = dns_rdataclass_in;
+static isc_bufferlist_t usedbuffers;
+static ISC_LIST(dns_rdatalist_t) usedrdatalists;
+
+static void setup_tsec(char *keyfile, isc_mem_t *mctx);
+static void update_addordelete(isc_mem_t *mctx, char *cmdline,
+ isc_boolean_t isdelete, dns_name_t *name);
+static void evaluate_prereq(isc_mem_t *mctx, char *cmdline, dns_name_t *name);
+
+ISC_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "sample-update "
+ "[-a auth_server] "
+ "[-k keyfile] "
+ "[-p prerequisite] "
+ "[-r recursive_server] "
+ "[-z zonename] "
+ "(add|delete) \"name TTL RRtype RDATA\"\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[]) {
+ int ch;
+ struct addrinfo hints, *res;
+ int gai_error;
+ dns_client_t *client = NULL;
+ char *zonenamestr = NULL;
+ char *keyfilename = NULL;
+ char *prereqstr = NULL;
+ isc_sockaddrlist_t auth_servers;
+ char *auth_server = NULL;
+ char *recursive_server = NULL;
+ isc_sockaddr_t sa_auth, sa_recursive;
+ isc_sockaddrlist_t rec_servers;
+ isc_result_t result;
+ isc_boolean_t isdelete;
+ isc_buffer_t b, *buf;
+ dns_fixedname_t zname0, pname0, uname0;
+ size_t namelen;
+ dns_name_t *zname = NULL, *uname, *pname;
+ dns_rdataset_t *rdataset;
+ dns_rdatalist_t *rdatalist;
+ dns_rdata_t *rdata;
+ dns_namelist_t updatelist, prereqlist, *prereqlistp = NULL;
+ isc_mem_t *umctx = NULL;
+
+ while ((ch = getopt(argc, argv, "a:k:p:r:z:")) != -1) {
+ switch (ch) {
+ case 'k':
+ keyfilename = optarg;
+ break;
+ case 'a':
+ auth_server = optarg;
+ break;
+ case 'p':
+ prereqstr = optarg;
+ break;
+ case 'r':
+ recursive_server = optarg;
+ break;
+ case 'z':
+ zonenamestr = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc < 2)
+ usage();
+
+ /* command line argument validation */
+ if (strcmp(argv[0], "delete") == 0)
+ isdelete = ISC_TRUE;
+ else if (strcmp(argv[0], "add") == 0)
+ isdelete = ISC_FALSE;
+ else {
+ fprintf(stderr, "invalid update command: %s\n", argv[0]);
+ exit(1);
+ }
+
+ if (auth_server == NULL && recursive_server == NULL) {
+ fprintf(stderr, "authoritative or recursive server "
+ "must be specified\n");
+ usage();
+ }
+
+ /* Initialization */
+ ISC_LIST_INIT(usedbuffers);
+ ISC_LIST_INIT(usedrdatalists);
+ ISC_LIST_INIT(prereqlist);
+ ISC_LIST_INIT(auth_servers);
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_lib_init failed: %d\n", result);
+ exit(1);
+ }
+ result = isc_mem_create(0, 0, &umctx);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to crate mctx\n");
+ exit(1);
+ }
+
+ result = dns_client_create(&client, 0);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_client_create failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Set the authoritative server */
+ if (auth_server != NULL) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST;
+ gai_error = getaddrinfo(auth_server, "53", &hints, &res);
+ if (gai_error != 0) {
+ fprintf(stderr, "getaddrinfo failed: %s\n",
+ gai_strerror(gai_error));
+ exit(1);
+ }
+ INSIST(res->ai_addrlen <= sizeof(sa_auth.type));
+ memcpy(&sa_auth.type, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ sa_auth.length = res->ai_addrlen;
+ ISC_LINK_INIT(&sa_auth, link);
+
+ ISC_LIST_APPEND(auth_servers, &sa_auth, link);
+ }
+
+ /* Set the recursive server */
+ if (recursive_server != NULL) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST;
+ gai_error = getaddrinfo(recursive_server, "53", &hints, &res);
+ if (gai_error != 0) {
+ fprintf(stderr, "getaddrinfo failed: %s\n",
+ gai_strerror(gai_error));
+ exit(1);
+ }
+ INSIST(res->ai_addrlen <= sizeof(sa_recursive.type));
+ memcpy(&sa_recursive.type, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ sa_recursive.length = res->ai_addrlen;
+ ISC_LINK_INIT(&sa_recursive, link);
+ ISC_LIST_INIT(rec_servers);
+ ISC_LIST_APPEND(rec_servers, &sa_recursive, link);
+ result = dns_client_setservers(client, dns_rdataclass_in,
+ NULL, &rec_servers);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "set server failed: %d\n", result);
+ exit(1);
+ }
+ }
+
+ /* Construct zone name */
+ zname = NULL;
+ if (zonenamestr != NULL) {
+ namelen = strlen(zonenamestr);
+ isc_buffer_init(&b, zonenamestr, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&zname0);
+ zname = dns_fixedname_name(&zname0);
+ result = dns_name_fromtext(zname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ fprintf(stderr, "failed to convert zone name: %d\n",
+ result);
+ }
+
+ /* Construct prerequisite name (if given) */
+ if (prereqstr != NULL) {
+ dns_fixedname_init(&pname0);
+ pname = dns_fixedname_name(&pname0);
+ evaluate_prereq(umctx, prereqstr, pname);
+ ISC_LIST_APPEND(prereqlist, pname, link);
+ prereqlistp = &prereqlist;
+ }
+
+ /* Construct update name */
+ ISC_LIST_INIT(updatelist);
+ dns_fixedname_init(&uname0);
+ uname = dns_fixedname_name(&uname0);
+ update_addordelete(umctx, argv[1], isdelete, uname);
+ ISC_LIST_APPEND(updatelist, uname, link);
+
+ /* Set up TSIG/SIG(0) key (if given) */
+ if (keyfilename != NULL)
+ setup_tsec(keyfilename, umctx);
+
+ /* Perform update */
+ result = dns_client_update(client,
+ default_rdataclass, /* XXX: fixed */
+ zname, prereqlistp, &updatelist,
+ (auth_server == NULL) ? NULL :
+ &auth_servers, tsec, 0);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr,
+ "update failed: %s\n", dns_result_totext(result));
+ } else
+ fprintf(stderr, "update succeeded\n");
+
+ /* Cleanup */
+ while ((pname = ISC_LIST_HEAD(prereqlist)) != NULL) {
+ while ((rdataset = ISC_LIST_HEAD(pname->list)) != NULL) {
+ ISC_LIST_UNLINK(pname->list, rdataset, link);
+ dns_rdataset_disassociate(rdataset);
+ isc_mem_put(umctx, rdataset, sizeof(*rdataset));
+ }
+ ISC_LIST_UNLINK(prereqlist, pname, link);
+ }
+ while ((uname = ISC_LIST_HEAD(updatelist)) != NULL) {
+ while ((rdataset = ISC_LIST_HEAD(uname->list)) != NULL) {
+ ISC_LIST_UNLINK(uname->list, rdataset, link);
+ dns_rdataset_disassociate(rdataset);
+ isc_mem_put(umctx, rdataset, sizeof(*rdataset));
+ }
+ ISC_LIST_UNLINK(updatelist, uname, link);
+ }
+ while ((rdatalist = ISC_LIST_HEAD(usedrdatalists)) != NULL) {
+ while ((rdata = ISC_LIST_HEAD(rdatalist->rdata)) != NULL) {
+ ISC_LIST_UNLINK(rdatalist->rdata, rdata, link);
+ isc_mem_put(umctx, rdata, sizeof(*rdata));
+ }
+ ISC_LIST_UNLINK(usedrdatalists, rdatalist, link);
+ isc_mem_put(umctx, rdatalist, sizeof(*rdatalist));
+ }
+ while ((buf = ISC_LIST_HEAD(usedbuffers)) != NULL) {
+ ISC_LIST_UNLINK(usedbuffers, buf, link);
+ isc_buffer_free(&buf);
+ }
+ if (tsec != NULL)
+ dns_tsec_destroy(&tsec);
+ isc_mem_destroy(&umctx);
+ dns_client_destroy(&client);
+ dns_lib_shutdown();
+
+ exit(0);
+}
+
+/*
+ * Subroutines borrowed from nsupdate.c
+ */
+#define MAXWIRE (64 * 1024)
+#define TTL_MAX 2147483647U /* Maximum signed 32 bit integer. */
+
+static char *
+nsu_strsep(char **stringp, const char *delim) {
+ char *string = *stringp;
+ char *s;
+ const char *d;
+ char sc, dc;
+
+ if (string == NULL)
+ return (NULL);
+
+ for (; *string != '\0'; string++) {
+ sc = *string;
+ for (d = delim; (dc = *d) != '\0'; d++) {
+ if (sc == dc)
+ break;
+ }
+ if (dc == 0)
+ break;
+ }
+
+ for (s = string; *s != '\0'; s++) {
+ sc = *s;
+ for (d = delim; (dc = *d) != '\0'; d++) {
+ if (sc == dc) {
+ *s++ = '\0';
+ *stringp = s;
+ return (string);
+ }
+ }
+ }
+ *stringp = NULL;
+ return (string);
+}
+
+static void
+fatal(const char *format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+static inline void
+check_result(isc_result_t result, const char *msg) {
+ if (result != ISC_R_SUCCESS)
+ fatal("%s: %s", msg, isc_result_totext(result));
+}
+
+static void
+parse_name(char **cmdlinep, dns_name_t *name) {
+ isc_result_t result;
+ char *word;
+ isc_buffer_t source;
+
+ word = nsu_strsep(cmdlinep, " \t\r\n");
+ if (*word == 0) {
+ fprintf(stderr, "could not read owner name\n");
+ exit(1);
+ }
+
+ isc_buffer_init(&source, word, strlen(word));
+ isc_buffer_add(&source, strlen(word));
+ result = dns_name_fromtext(name, &source, dns_rootname, 0, NULL);
+ check_result(result, "dns_name_fromtext");
+ isc_buffer_invalidate(&source);
+}
+
+static void
+parse_rdata(isc_mem_t *mctx, char **cmdlinep, dns_rdataclass_t rdataclass,
+ dns_rdatatype_t rdatatype, dns_rdata_t *rdata)
+{
+ char *cmdline = *cmdlinep;
+ isc_buffer_t source, *buf = NULL, *newbuf = NULL;
+ isc_region_t r;
+ isc_lex_t *lex = NULL;
+ dns_rdatacallbacks_t callbacks;
+ isc_result_t result;
+
+ while (cmdline != NULL && *cmdline != 0 &&
+ isspace((unsigned char)*cmdline))
+ cmdline++;
+
+ if (cmdline != NULL && *cmdline != 0) {
+ dns_rdatacallbacks_init(&callbacks);
+ result = isc_lex_create(mctx, strlen(cmdline), &lex);
+ check_result(result, "isc_lex_create");
+ isc_buffer_init(&source, cmdline, strlen(cmdline));
+ isc_buffer_add(&source, strlen(cmdline));
+ result = isc_lex_openbuffer(lex, &source);
+ check_result(result, "isc_lex_openbuffer");
+ result = isc_buffer_allocate(mctx, &buf, MAXWIRE);
+ check_result(result, "isc_buffer_allocate");
+ result = dns_rdata_fromtext(rdata, rdataclass, rdatatype, lex,
+ dns_rootname, 0, mctx, buf,
+ &callbacks);
+ isc_lex_destroy(&lex);
+ if (result == ISC_R_SUCCESS) {
+ isc_buffer_usedregion(buf, &r);
+ result = isc_buffer_allocate(mctx, &newbuf, r.length);
+ check_result(result, "isc_buffer_allocate");
+ isc_buffer_putmem(newbuf, r.base, r.length);
+ isc_buffer_usedregion(newbuf, &r);
+ dns_rdata_reset(rdata);
+ dns_rdata_fromregion(rdata, rdataclass, rdatatype, &r);
+ isc_buffer_free(&buf);
+ ISC_LIST_APPEND(usedbuffers, newbuf, link);
+ } else {
+ fprintf(stderr, "invalid rdata format: %s\n",
+ isc_result_totext(result));
+ isc_buffer_free(&buf);
+ exit(1);
+ }
+ } else {
+ rdata->flags = DNS_RDATA_UPDATE;
+ }
+ *cmdlinep = cmdline;
+}
+
+static void
+update_addordelete(isc_mem_t *mctx, char *cmdline, isc_boolean_t isdelete,
+ dns_name_t *name)
+{
+ isc_result_t result;
+ isc_uint32_t ttl;
+ char *word;
+ dns_rdataclass_t rdataclass;
+ dns_rdatatype_t rdatatype;
+ dns_rdata_t *rdata = NULL;
+ dns_rdatalist_t *rdatalist = NULL;
+ dns_rdataset_t *rdataset = NULL;
+ isc_textregion_t region;
+
+ /*
+ * Read the owner name.
+ */
+ parse_name(&cmdline, name);
+
+ rdata = isc_mem_get(mctx, sizeof(*rdata));
+ if (rdata == NULL) {
+ fprintf(stderr, "memory allocation for rdata failed\n");
+ exit(1);
+ }
+ dns_rdata_init(rdata);
+
+ /*
+ * If this is an add, read the TTL and verify that it's in range.
+ * If it's a delete, ignore a TTL if present (for compatibility).
+ */
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ if (word == NULL || *word == 0) {
+ if (!isdelete) {
+ fprintf(stderr, "could not read owner ttl\n");
+ exit(1);
+ }
+ else {
+ ttl = 0;
+ rdataclass = dns_rdataclass_any;
+ rdatatype = dns_rdatatype_any;
+ rdata->flags = DNS_RDATA_UPDATE;
+ goto doneparsing;
+ }
+ }
+ result = isc_parse_uint32(&ttl, word, 10);
+ if (result != ISC_R_SUCCESS) {
+ if (isdelete) {
+ ttl = 0;
+ goto parseclass;
+ } else {
+ fprintf(stderr, "ttl '%s': %s\n", word,
+ isc_result_totext(result));
+ exit(1);
+ }
+ }
+
+ if (isdelete)
+ ttl = 0;
+ else if (ttl > TTL_MAX) {
+ fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n",
+ word, TTL_MAX);
+ exit(1);
+ }
+
+ /*
+ * Read the class or type.
+ */
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ parseclass:
+ if (word == NULL || *word == 0) {
+ if (isdelete) {
+ rdataclass = dns_rdataclass_any;
+ rdatatype = dns_rdatatype_any;
+ rdata->flags = DNS_RDATA_UPDATE;
+ goto doneparsing;
+ } else {
+ fprintf(stderr, "could not read class or type\n");
+ exit(1);
+ }
+ }
+ region.base = word;
+ region.length = strlen(word);
+ result = dns_rdataclass_fromtext(&rdataclass, &region);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * Now read the type.
+ */
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ if (word == NULL || *word == 0) {
+ if (isdelete) {
+ rdataclass = dns_rdataclass_any;
+ rdatatype = dns_rdatatype_any;
+ rdata->flags = DNS_RDATA_UPDATE;
+ goto doneparsing;
+ } else {
+ fprintf(stderr, "could not read type\n");
+ exit(1);
+ }
+ }
+ region.base = word;
+ region.length = strlen(word);
+ result = dns_rdatatype_fromtext(&rdatatype, &region);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "'%s' is not a valid type: %s\n",
+ word, isc_result_totext(result));
+ exit(1);
+ }
+ } else {
+ rdataclass = default_rdataclass;
+ result = dns_rdatatype_fromtext(&rdatatype, &region);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "'%s' is not a valid class or type: "
+ "%s\n", word, isc_result_totext(result));
+ exit(1);
+ }
+ }
+
+ parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata);
+
+ if (isdelete) {
+ if ((rdata->flags & DNS_RDATA_UPDATE) != 0)
+ rdataclass = dns_rdataclass_any;
+ else
+ rdataclass = dns_rdataclass_none;
+ } else {
+ if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
+ fprintf(stderr, "could not read rdata\n");
+ exit(1);
+ }
+ }
+
+ doneparsing:
+
+ rdatalist = isc_mem_get(mctx, sizeof(*rdatalist));
+ if (rdatalist == NULL) {
+ fprintf(stderr, "memory allocation for rdatalist failed\n");
+ exit(1);
+ }
+ dns_rdatalist_init(rdatalist);
+ rdatalist->type = rdatatype;
+ rdatalist->rdclass = rdataclass;
+ rdatalist->covers = rdatatype;
+ rdatalist->ttl = (dns_ttl_t)ttl;
+ ISC_LIST_INIT(rdatalist->rdata);
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ ISC_LIST_APPEND(usedrdatalists, rdatalist, link);
+
+ rdataset = isc_mem_get(mctx, sizeof(*rdataset));
+ if (rdataset == NULL) {
+ fprintf(stderr, "memory allocation for rdataset failed\n");
+ exit(1);
+ }
+ dns_rdataset_init(rdataset);
+ dns_rdatalist_tordataset(rdatalist, rdataset);
+ ISC_LIST_INIT(name->list);
+ ISC_LIST_APPEND(name->list, rdataset, link);
+}
+
+static void
+make_prereq(isc_mem_t *mctx, char *cmdline, isc_boolean_t ispositive,
+ isc_boolean_t isrrset, dns_name_t *name)
+{
+ isc_result_t result;
+ char *word;
+ isc_textregion_t region;
+ dns_rdataset_t *rdataset = NULL;
+ dns_rdatalist_t *rdatalist = NULL;
+ dns_rdataclass_t rdataclass;
+ dns_rdatatype_t rdatatype;
+ dns_rdata_t *rdata = NULL;
+
+ /*
+ * Read the owner name
+ */
+ parse_name(&cmdline, name);
+
+ /*
+ * If this is an rrset prereq, read the class or type.
+ */
+ if (isrrset) {
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ if (word == NULL || *word == 0) {
+ fprintf(stderr, "could not read class or type\n");
+ exit(1);
+ }
+ region.base = word;
+ region.length = strlen(word);
+ result = dns_rdataclass_fromtext(&rdataclass, &region);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * Now read the type.
+ */
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ if (word == NULL || *word == 0) {
+ fprintf(stderr, "could not read type\n");
+ exit(1);
+ }
+ region.base = word;
+ region.length = strlen(word);
+ result = dns_rdatatype_fromtext(&rdatatype, &region);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "invalid type: %s\n", word);
+ exit(1);
+ }
+ } else {
+ rdataclass = default_rdataclass;
+ result = dns_rdatatype_fromtext(&rdatatype, &region);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "invalid type: %s\n", word);
+ exit(1);
+ }
+ }
+ } else
+ rdatatype = dns_rdatatype_any;
+
+ rdata = isc_mem_get(mctx, sizeof(*rdata));
+ if (rdata == NULL) {
+ fprintf(stderr, "memory allocation for rdata failed\n");
+ exit(1);
+ }
+ dns_rdata_init(rdata);
+
+ if (isrrset && ispositive)
+ parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata);
+ else
+ rdata->flags = DNS_RDATA_UPDATE;
+
+ rdatalist = isc_mem_get(mctx, sizeof(*rdatalist));
+ if (rdatalist == NULL) {
+ fprintf(stderr, "memory allocation for rdatalist failed\n");
+ exit(1);
+ }
+ dns_rdatalist_init(rdatalist);
+ rdatalist->type = rdatatype;
+ if (ispositive) {
+ if (isrrset && rdata->data != NULL)
+ rdatalist->rdclass = rdataclass;
+ else
+ rdatalist->rdclass = dns_rdataclass_any;
+ } else
+ rdatalist->rdclass = dns_rdataclass_none;
+ rdatalist->covers = 0;
+ rdatalist->ttl = 0;
+ rdata->rdclass = rdatalist->rdclass;
+ rdata->type = rdatatype;
+ ISC_LIST_INIT(rdatalist->rdata);
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ ISC_LIST_APPEND(usedrdatalists, rdatalist, link);
+
+ rdataset = isc_mem_get(mctx, sizeof(*rdataset));
+ if (rdataset == NULL) {
+ fprintf(stderr, "memory allocation for rdataset failed\n");
+ exit(1);
+ }
+ dns_rdataset_init(rdataset);
+ dns_rdatalist_tordataset(rdatalist, rdataset);
+ ISC_LIST_INIT(name->list);
+ ISC_LIST_APPEND(name->list, rdataset, link);
+}
+
+static void
+evaluate_prereq(isc_mem_t *mctx, char *cmdline, dns_name_t *name) {
+ char *word;
+ isc_boolean_t ispositive, isrrset;
+
+ word = nsu_strsep(&cmdline, " \t\r\n");
+ if (word == NULL || *word == 0) {
+ fprintf(stderr, "could not read operation code\n");
+ exit(1);
+ }
+ if (strcasecmp(word, "nxdomain") == 0) {
+ ispositive = ISC_FALSE;
+ isrrset = ISC_FALSE;
+ } else if (strcasecmp(word, "yxdomain") == 0) {
+ ispositive = ISC_TRUE;
+ isrrset = ISC_FALSE;
+ } else if (strcasecmp(word, "nxrrset") == 0) {
+ ispositive = ISC_FALSE;
+ isrrset = ISC_TRUE;
+ } else if (strcasecmp(word, "yxrrset") == 0) {
+ ispositive = ISC_TRUE;
+ isrrset = ISC_TRUE;
+ } else {
+ fprintf(stderr, "incorrect operation code: %s\n", word);
+ exit(1);
+ }
+
+ make_prereq(mctx, cmdline, ispositive, isrrset, name);
+}
+
+static void
+setup_tsec(char *keyfile, isc_mem_t *mctx) {
+ dst_key_t *dstkey = NULL;
+ isc_result_t result;
+ dns_tsectype_t tsectype;
+
+ result = dst_key_fromnamedfile(keyfile, NULL,
+ DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "could not read key from %s: %s\n",
+ keyfile, isc_result_totext(result));
+ exit(1);
+ }
+
+ if (dst_key_alg(dstkey) == DST_ALG_HMACMD5)
+ tsectype = dns_tsectype_tsig;
+ else
+ tsectype = dns_tsectype_sig0;
+
+ result = dns_tsec_create(mctx, tsectype, dstkey, &tsec);
+ dst_key_free(&dstkey);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "could not create tsec: %s\n",
+ isc_result_totext(result));
+ exit(1);
+ }
+}
diff --git a/lib/export/samples/sample.c b/lib/export/samples/sample.c
new file mode 100644
index 000000000000..6564f0ec2ecf
--- /dev/null
+++ b/lib/export/samples/sample.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: sample.c,v 1.5 2009-09-29 15:06:07 fdupont Exp $ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/keyvalues.h>
+#include <dns/lib.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+#include <dns/secalg.h>
+
+#include <dst/dst.h>
+
+static char *algname;
+
+static isc_result_t
+printdata(dns_rdataset_t *rdataset, dns_name_t *owner) {
+ isc_buffer_t target;
+ isc_result_t result;
+ isc_region_t r;
+ char t[4096];
+
+ if (!dns_rdataset_isassociated(rdataset)) {
+ printf("[WARN: empty]\n");
+ return (ISC_R_SUCCESS);
+ }
+
+ 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_PLATFORM_NORETURN_PRE static void
+usage(void) ISC_PLATFORM_NORETURN_POST;
+
+static void
+usage(void) {
+ fprintf(stderr, "sample [-t RRtype] "
+ "[[-a algorithm] [-e] -k keyname -K keystring] "
+ "[-s domain:serveraddr_for_domain ] "
+ "server_address hostname\n");
+
+ exit(1);
+}
+
+static void
+set_key(dns_client_t *client, char *keynamestr, char *keystr,
+ isc_boolean_t is_sep, isc_mem_t **mctxp)
+{
+ isc_result_t result;
+ dns_fixedname_t fkeyname;
+ size_t namelen;
+ dns_name_t *keyname;
+ dns_rdata_dnskey_t keystruct;
+ unsigned char keydata[4096];
+ isc_buffer_t keydatabuf;
+ unsigned char rrdata[4096];
+ isc_buffer_t rrdatabuf;
+ isc_buffer_t b;
+ isc_textregion_t tr;
+ isc_region_t r;
+ dns_secalg_t alg;
+
+ result = isc_mem_create(0, 0, mctxp);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to crate mctx\n");
+ exit(1);
+ }
+
+ if (algname != NULL) {
+ tr.base = algname;
+ tr.length = strlen(algname);
+ result = dns_secalg_fromtext(&alg, &tr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to identify the algorithm\n");
+ exit(1);
+ }
+ } else
+ alg = DNS_KEYALG_RSASHA1;
+
+ keystruct.common.rdclass = dns_rdataclass_in;
+ keystruct.common.rdtype = dns_rdatatype_dnskey;
+ keystruct.flags = DNS_KEYOWNER_ZONE; /* fixed */
+ if (is_sep)
+ keystruct.flags |= DNS_KEYFLAG_KSK;
+ keystruct.protocol = DNS_KEYPROTO_DNSSEC; /* fixed */
+ keystruct.algorithm = alg;
+
+ isc_buffer_init(&keydatabuf, keydata, sizeof(keydata));
+ isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
+ result = isc_base64_decodestring(keystr, &keydatabuf);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "base64 decode failed\n");
+ exit(1);
+ }
+ isc_buffer_usedregion(&keydatabuf, &r);
+ keystruct.datalen = r.length;
+ keystruct.data = r.base;
+
+ result = dns_rdata_fromstruct(NULL, keystruct.common.rdclass,
+ keystruct.common.rdtype,
+ &keystruct, &rrdatabuf);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to construct key rdata\n");
+ exit(1);
+ }
+ namelen = strlen(keynamestr);
+ isc_buffer_init(&b, keynamestr, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&fkeyname);
+ keyname = dns_fixedname_name(&fkeyname);
+ result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to construct key name\n");
+ exit(1);
+ }
+ result = dns_client_addtrustedkey(client, dns_rdataclass_in,
+ keyname, &rrdatabuf);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to add key for %s\n",
+ keynamestr);
+ exit(1);
+ }
+}
+
+static void
+addserver(dns_client_t *client, const char *addrstr, const char *namespace) {
+ struct addrinfo hints, *res;
+ int gai_error;
+ isc_sockaddr_t sa;
+ isc_sockaddrlist_t servers;
+ isc_result_t result;
+ size_t namelen;
+ isc_buffer_t b;
+ dns_fixedname_t fname;
+ dns_name_t *name = NULL;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST;
+ gai_error = getaddrinfo(addrstr, "53", &hints, &res);
+ if (gai_error != 0) {
+ fprintf(stderr, "getaddrinfo failed: %s\n",
+ gai_strerror(gai_error));
+ exit(1);
+ }
+ INSIST(res->ai_addrlen <= sizeof(sa.type));
+ memcpy(&sa.type, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ sa.length = res->ai_addrlen;
+ ISC_LINK_INIT(&sa, link);
+ ISC_LIST_INIT(servers);
+ ISC_LIST_APPEND(servers, &sa, link);
+
+ if (namespace != NULL) {
+ namelen = strlen(namespace);
+ isc_buffer_init(&b, namespace, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "failed to convert qname: %d\n",
+ result);
+ exit(1);
+ }
+ }
+
+ result = dns_client_setservers(client, dns_rdataclass_in, name,
+ &servers);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "set server failed: %d\n", result);
+ exit(1);
+ }
+}
+
+int
+main(int argc, char *argv[]) {
+ int ch;
+ isc_textregion_t tr;
+ char *altserver = NULL;
+ char *altserveraddr = NULL;
+ char *altservername = NULL;
+ dns_client_t *client = NULL;
+ char *keynamestr = NULL;
+ char *keystr = NULL;
+ isc_result_t result;
+ isc_buffer_t b;
+ dns_fixedname_t qname0;
+ size_t namelen;
+ dns_name_t *qname, *name;
+ dns_rdatatype_t type = dns_rdatatype_a;
+ dns_rdataset_t *rdataset;
+ dns_namelist_t namelist;
+ isc_mem_t *keymctx = NULL;
+ unsigned int clientopt, resopt;
+ isc_boolean_t is_sep = ISC_FALSE;
+
+ while ((ch = getopt(argc, argv, "a:es:t:k:K:")) != -1) {
+ switch (ch) {
+ case 't':
+ tr.base = optarg;
+ tr.length = strlen(optarg);
+ result = dns_rdatatype_fromtext(&type, &tr);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr,
+ "invalid RRtype: %s\n", optarg);
+ exit(1);
+ }
+ break;
+ case 'a':
+ algname = optarg;
+ break;
+ case 'e':
+ is_sep = ISC_TRUE;
+ break;
+ case 's':
+ if (altserver != NULL) {
+ fprintf(stderr, "alternate server "
+ "already defined: %s\n",
+ altserver);
+ exit(1);
+ }
+ altserver = optarg;
+ break;
+ case 'k':
+ keynamestr = optarg;
+ break;
+ case 'K':
+ keystr = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc < 2)
+ usage();
+
+ if (altserver != NULL) {
+ char *cp;
+
+ cp = strchr(altserver, ':');
+ if (cp == NULL) {
+ fprintf(stderr, "invalid alternate server: %s\n",
+ altserver);
+ exit(1);
+ }
+ *cp = '\0';
+ altservername = altserver;
+ altserveraddr = cp + 1;
+ }
+
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_lib_init failed: %d\n", result);
+ exit(1);
+ }
+
+ clientopt = 0;
+ result = dns_client_create(&client, clientopt);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "dns_client_create failed: %d\n", result);
+ exit(1);
+ }
+
+ /* Set the nameserver */
+ addserver(client, argv[0], NULL);
+
+ /* Set the alternate nameserver (when specified) */
+ if (altserver != NULL)
+ addserver(client, altserveraddr, altservername);
+
+ /* Install DNSSEC key (if given) */
+ if (keynamestr != NULL) {
+ if (keystr == NULL) {
+ fprintf(stderr,
+ "key string is missing "
+ "while key name is provided\n");
+ exit(1);
+ }
+ set_key(client, keynamestr, keystr, is_sep, &keymctx);
+ }
+
+ /* Construct qname */
+ namelen = strlen(argv[1]);
+ isc_buffer_init(&b, argv[1], namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&qname0);
+ qname = dns_fixedname_name(&qname0);
+ result = dns_name_fromtext(qname, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ fprintf(stderr, "failed to convert qname: %d\n", result);
+
+ /* Perform resolution */
+ resopt = 0;
+ if (keynamestr == NULL)
+ resopt |= DNS_CLIENTRESOPT_NODNSSEC;
+ ISC_LIST_INIT(namelist);
+ result = dns_client_resolve(client, qname, dns_rdataclass_in, type,
+ resopt, &namelist);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr,
+ "resolution failed: %s\n", dns_result_totext(result));
+ }
+ for (name = ISC_LIST_HEAD(namelist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (printdata(rdataset, name) != ISC_R_SUCCESS)
+ fprintf(stderr, "print data failed\n");
+ }
+ }
+
+ dns_client_freeresanswer(client, &namelist);
+
+ /* Cleanup */
+ dns_client_destroy(&client);
+ if (keynamestr != NULL)
+ isc_mem_destroy(&keymctx);
+ dns_lib_shutdown();
+
+ exit(0);
+}
diff --git a/lib/irs/Makefile.in b/lib/irs/Makefile.in
new file mode 100644
index 000000000000..3f9bfb325a04
--- /dev/null
+++ b/lib/irs/Makefile.in
@@ -0,0 +1,80 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+@LIBIRS_API@
+
+@BIND9_MAKE_INCLUDES@
+
+CINCLUDES = -I. -I./include -I${srcdir}/include \
+ ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+# Alphabetically
+OBJS = context.@O@ \
+ dnsconf.@O@ \
+ gai_strerror.@O@ getaddrinfo.@O@ getnameinfo.@O@ \
+ resconf.@O@
+
+# Alphabetically
+SRCS = context.c \
+ dnsconf.c \
+ gai_sterror.c getaddrinfo.c getnameinfo.c \
+ resconf.c
+
+LIBS = @LIBS@
+
+SUBDIRS = include
+TARGETS = timestamp
+
+@BIND9_MAKE_RULES@
+
+version.@O@: version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libirs.@SA@: ${OBJS} version.@O@
+ ${AR} ${ARFLAGS} $@ ${OBJS} version.@O@
+ ${RANLIB} $@
+
+libirs.la: ${OBJS} version.@O@
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libirs.la -rpath ${libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} version.@O@ ${LIBS}
+
+timestamp: libirs.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libirs.@A@ ${DESTDIR}${libdir}
+
+clean distclean::
+ rm -f libirs.@A@ libirs.la timestamp
diff --git a/lib/irs/api b/lib/irs/api
new file mode 100644
index 000000000000..94575eb4ef20
--- /dev/null
+++ b/lib/irs/api
@@ -0,0 +1,3 @@
+LIBINTERFACE = 80
+LIBREVISION = 0
+LIBAGE = 0
diff --git a/lib/irs/context.c b/lib/irs/context.c
new file mode 100644
index 000000000000..0c6d856e1847
--- /dev/null
+++ b/lib/irs/context.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: context.c,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <isc/app.h>
+#include <isc/lib.h>
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/once.h>
+#include <isc/socket.h>
+#include <isc/task.h>
+#include <isc/thread.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/lib.h>
+
+#include <irs/context.h>
+#include <irs/dnsconf.h>
+#include <irs/resconf.h>
+
+#define IRS_CONTEXT_MAGIC ISC_MAGIC('I', 'R', 'S', 'c')
+#define IRS_CONTEXT_VALID(c) ISC_MAGIC_VALID(c, IRS_CONTEXT_MAGIC)
+
+#ifndef RESOLV_CONF
+/*% location of resolve.conf */
+#define RESOLV_CONF "/etc/resolv.conf"
+#endif
+
+#ifndef DNS_CONF
+/*% location of dns.conf */
+#define DNS_CONF "/etc/dns.conf"
+#endif
+
+#ifndef ISC_PLATFORM_USETHREADS
+irs_context_t *irs_g_context = NULL;
+#else
+static isc_boolean_t thread_key_initialized = ISC_FALSE;
+static isc_mutex_t thread_key_mutex;
+static isc_thread_key_t irs_context_key;
+static isc_once_t once = ISC_ONCE_INIT;
+#endif
+
+
+struct irs_context {
+ /*
+ * An IRS context is a thread-specific object, and does not need to
+ * be locked.
+ */
+ unsigned int magic;
+ isc_mem_t *mctx;
+ isc_appctx_t *actx;
+ isc_taskmgr_t *taskmgr;
+ isc_task_t *task;
+ isc_socketmgr_t *socketmgr;
+ isc_timermgr_t *timermgr;
+ dns_client_t *dnsclient;
+ irs_resconf_t *resconf;
+ irs_dnsconf_t *dnsconf;
+};
+
+static void
+ctxs_destroy(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ if (taskmgrp != NULL)
+ isc_taskmgr_destroy(taskmgrp);
+
+ if (timermgrp != NULL)
+ isc_timermgr_destroy(timermgrp);
+
+ if (socketmgrp != NULL)
+ isc_socketmgr_destroy(socketmgrp);
+
+ if (actxp != NULL)
+ isc_appctx_destroy(actxp);
+
+ if (mctxp != NULL)
+ isc_mem_destroy(mctxp);
+}
+
+static isc_result_t
+ctxs_init(isc_mem_t **mctxp, isc_appctx_t **actxp,
+ isc_taskmgr_t **taskmgrp, isc_socketmgr_t **socketmgrp,
+ isc_timermgr_t **timermgrp)
+{
+ isc_result_t result;
+
+ result = isc_mem_create(0, 0, mctxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_appctx_create(*mctxp, actxp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_taskmgr_createinctx(*mctxp, *actxp, 1, 0, taskmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_socketmgr_createinctx(*mctxp, *actxp, socketmgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ result = isc_timermgr_createinctx(*mctxp, *actxp, timermgrp);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ ctxs_destroy(mctxp, actxp, taskmgrp, socketmgrp, timermgrp);
+
+ return (result);
+}
+
+#ifdef ISC_PLATFORM_USETHREADS
+static void
+free_specific_context(void *arg) {
+ irs_context_t *context = arg;
+
+ irs_context_destroy(&context);
+
+ isc_thread_key_setspecific(irs_context_key, NULL);
+}
+
+static void
+thread_key_mutex_init(void) {
+ RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS);
+}
+
+static isc_result_t
+thread_key_init() {
+ isc_result_t result;
+
+ result = isc_once_do(&once, thread_key_mutex_init);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ if (!thread_key_initialized) {
+ LOCK(&thread_key_mutex);
+
+ if (!thread_key_initialized &&
+ isc_thread_key_create(&irs_context_key,
+ free_specific_context) != 0) {
+ result = ISC_R_FAILURE;
+ } else
+ thread_key_initialized = ISC_TRUE;
+
+ UNLOCK(&thread_key_mutex);
+ }
+
+ return (result);
+}
+#endif /* ISC_PLATFORM_USETHREADS */
+
+isc_result_t
+irs_context_get(irs_context_t **contextp) {
+ irs_context_t *context;
+ isc_result_t result;
+
+ REQUIRE(contextp != NULL && *contextp == NULL);
+
+#ifndef ISC_PLATFORM_USETHREADS
+ if (irs_g_context == NULL) {
+ result = irs_context_create(&irs_g_context);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+
+ context = irs_g_context;
+#else
+ result = thread_key_init();
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ context = isc_thread_key_getspecific(irs_context_key);
+ if (context == NULL) {
+ result = irs_context_create(&context);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_thread_key_setspecific(irs_context_key, context);
+ if (result != ISC_R_SUCCESS) {
+ irs_context_destroy(&context);
+ return (result);
+ }
+ }
+#endif /* ISC_PLATFORM_USETHREADS */
+
+ *contextp = context;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+irs_context_create(irs_context_t **contextp) {
+ isc_result_t result;
+ irs_context_t *context;
+ isc_appctx_t *actx = NULL;
+ isc_mem_t *mctx = NULL;
+ isc_taskmgr_t *taskmgr = NULL;
+ isc_socketmgr_t *socketmgr = NULL;
+ isc_timermgr_t *timermgr = NULL;
+ dns_client_t *client = NULL;
+ isc_sockaddrlist_t *nameservers;
+ irs_dnsconf_dnskeylist_t *trustedkeys;
+ irs_dnsconf_dnskey_t *trustedkey;
+
+ isc_lib_register();
+ result = dns_lib_init();
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = ctxs_init(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = isc_app_ctxstart(actx);
+ if (result != ISC_R_SUCCESS) {
+ ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
+ return (result);
+ }
+
+ context = isc_mem_get(mctx, sizeof(*context));
+ if (context == NULL) {
+ ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
+ return (ISC_R_NOMEMORY);
+ }
+
+ context->mctx = mctx;
+ context->actx = actx;
+ context->taskmgr = taskmgr;
+ context->socketmgr = socketmgr;
+ context->timermgr = timermgr;
+ context->resconf = NULL;
+ context->dnsconf = NULL;
+ context->task = NULL;
+ result = isc_task_create(taskmgr, 0, &context->task);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ /* Create a DNS client object */
+ result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr,
+ 0, &client);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ context->dnsclient = client;
+
+ /* Read resolver configuration file */
+ result = irs_resconf_load(mctx, RESOLV_CONF, &context->resconf);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ /* Set nameservers */
+ nameservers = irs_resconf_getnameservers(context->resconf);
+ result = dns_client_setservers(client, dns_rdataclass_in, NULL,
+ nameservers);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+
+ /* Read advanced DNS configuration (if any) */
+ result = irs_dnsconf_load(mctx, DNS_CONF, &context->dnsconf);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ trustedkeys = irs_dnsconf_gettrustedkeys(context->dnsconf);
+ for (trustedkey = ISC_LIST_HEAD(*trustedkeys);
+ trustedkey != NULL;
+ trustedkey = ISC_LIST_NEXT(trustedkey, link)) {
+ result = dns_client_addtrustedkey(client, dns_rdataclass_in,
+ trustedkey->keyname,
+ trustedkey->keydatabuf);
+ if (result != ISC_R_SUCCESS)
+ goto fail;
+ }
+
+ context->magic = IRS_CONTEXT_MAGIC;
+ *contextp = context;
+
+ return (ISC_R_SUCCESS);
+
+ fail:
+ if (context->task != NULL)
+ isc_task_detach(&context->task);
+ if (context->resconf != NULL)
+ irs_resconf_destroy(&context->resconf);
+ if (context->dnsconf != NULL)
+ irs_dnsconf_destroy(&context->dnsconf);
+ if (client != NULL)
+ dns_client_destroy(&client);
+ ctxs_destroy(NULL, &actx, &taskmgr, &socketmgr, &timermgr);
+ isc_mem_putanddetach(&mctx, context, sizeof(*context));
+
+ return (result);
+}
+
+void
+irs_context_destroy(irs_context_t **contextp) {
+ irs_context_t *context;
+
+ REQUIRE(contextp != NULL);
+ context = *contextp;
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ isc_task_detach(&context->task);
+ irs_dnsconf_destroy(&context->dnsconf);
+ irs_resconf_destroy(&context->resconf);
+ dns_client_destroy(&context->dnsclient);
+
+ ctxs_destroy(NULL, &context->actx, &context->taskmgr,
+ &context->socketmgr, &context->timermgr);
+
+ context->magic = 0;
+
+ isc_mem_putanddetach(&context->mctx, context, sizeof(*context));
+
+ *contextp = NULL;
+
+#ifndef ISC_PLATFORM_USETHREADS
+ irs_g_context = NULL;
+#else
+ (void)isc_thread_key_setspecific(irs_context_key, NULL);
+#endif
+}
+
+isc_mem_t *
+irs_context_getmctx(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->mctx);
+}
+
+isc_appctx_t *
+irs_context_getappctx(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->actx);
+}
+
+isc_taskmgr_t *
+irs_context_gettaskmgr(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->taskmgr);
+}
+
+isc_timermgr_t *
+irs_context_gettimermgr(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->timermgr);
+}
+
+isc_task_t *
+irs_context_gettask(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->task);
+}
+
+dns_client_t *
+irs_context_getdnsclient(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->dnsclient);
+}
+
+irs_resconf_t *
+irs_context_getresconf(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->resconf);
+}
+
+irs_dnsconf_t *
+irs_context_getdnsconf(irs_context_t *context) {
+ REQUIRE(IRS_CONTEXT_VALID(context));
+
+ return (context->dnsconf);
+}
diff --git a/lib/irs/dnsconf.c b/lib/irs/dnsconf.c
new file mode 100644
index 000000000000..8464d6d729ad
--- /dev/null
+++ b/lib/irs/dnsconf.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: dnsconf.c,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/file.h>
+#include <isc/mem.h>
+#include <isc/util.h>
+
+#include <isccfg/dnsconf.h>
+
+#include <dns/fixedname.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdatastruct.h>
+
+#include <irs/dnsconf.h>
+
+#define IRS_DNSCONF_MAGIC ISC_MAGIC('D', 'c', 'f', 'g')
+#define IRS_DNSCONF_VALID(c) ISC_MAGIC_VALID(c, IRS_DNSCONF_MAGIC)
+
+/*!
+ * configuration data structure
+ */
+
+struct irs_dnsconf {
+ unsigned int magic;
+ isc_mem_t *mctx;
+ irs_dnsconf_dnskeylist_t trusted_keylist;
+};
+
+static isc_result_t
+configure_dnsseckeys(irs_dnsconf_t *conf, cfg_obj_t *cfgobj,
+ dns_rdataclass_t rdclass)
+{
+ isc_mem_t *mctx = conf->mctx;
+ const cfg_obj_t *keys = NULL;
+ const cfg_obj_t *key, *keylist;
+ dns_fixedname_t fkeyname;
+ dns_name_t *keyname_base, *keyname;
+ const cfg_listelt_t *element, *element2;
+ isc_result_t result;
+ isc_uint32_t flags, proto, alg;
+ const char *keystr, *keynamestr;
+ unsigned char keydata[4096];
+ isc_buffer_t keydatabuf_base, *keydatabuf;
+ dns_rdata_dnskey_t keystruct;
+ unsigned char rrdata[4096];
+ isc_buffer_t rrdatabuf;
+ isc_region_t r;
+ isc_buffer_t namebuf;
+ irs_dnsconf_dnskey_t *keyent;
+
+ cfg_map_get(cfgobj, "trusted-keys", &keys);
+ if (keys == NULL)
+ return (ISC_R_SUCCESS);
+
+ for (element = cfg_list_first(keys);
+ element != NULL;
+ element = cfg_list_next(element)) {
+ keylist = cfg_listelt_value(element);
+ for (element2 = cfg_list_first(keylist);
+ element2 != NULL;
+ element2 = cfg_list_next(element2))
+ {
+ keydatabuf = NULL;
+ keyname = NULL;
+
+ key = cfg_listelt_value(element2);
+
+ flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
+ proto = cfg_obj_asuint32(cfg_tuple_get(key,
+ "protocol"));
+ alg = cfg_obj_asuint32(cfg_tuple_get(key,
+ "algorithm"));
+ keynamestr = cfg_obj_asstring(cfg_tuple_get(key,
+ "name"));
+
+ keystruct.common.rdclass = rdclass;
+ keystruct.common.rdtype = dns_rdatatype_dnskey;
+ keystruct.mctx = NULL;
+ ISC_LINK_INIT(&keystruct.common, link);
+
+ if (flags > 0xffff)
+ return (ISC_R_RANGE);
+ if (proto > 0xff)
+ return (ISC_R_RANGE);
+ if (alg > 0xff)
+ return (ISC_R_RANGE);
+ keystruct.flags = (isc_uint16_t)flags;
+ keystruct.protocol = (isc_uint8_t)proto;
+ keystruct.algorithm = (isc_uint8_t)alg;
+
+ isc_buffer_init(&keydatabuf_base, keydata,
+ sizeof(keydata));
+ isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
+
+ /* Configure key value */
+ keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
+ result = isc_base64_decodestring(keystr,
+ &keydatabuf_base);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_buffer_usedregion(&keydatabuf_base, &r);
+ keystruct.datalen = r.length;
+ keystruct.data = r.base;
+
+ result = dns_rdata_fromstruct(NULL,
+ keystruct.common.rdclass,
+ keystruct.common.rdtype,
+ &keystruct, &rrdatabuf);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_buffer_usedregion(&rrdatabuf, &r);
+ result = isc_buffer_allocate(mctx, &keydatabuf,
+ r.length);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_buffer_copyregion(keydatabuf, &r);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Configure key name */
+ dns_fixedname_init(&fkeyname);
+ keyname_base = dns_fixedname_name(&fkeyname);
+ isc_buffer_init(&namebuf, keynamestr,
+ strlen(keynamestr));
+ isc_buffer_add(&namebuf, strlen(keynamestr));
+ result = dns_name_fromtext(keyname_base, &namebuf,
+ dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ keyname = isc_mem_get(mctx, sizeof(*keyname));
+ if (keyname == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ dns_name_init(keyname, NULL);
+ result = dns_name_dup(keyname_base, mctx, keyname);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ /* Add the key data to the list */
+ keyent = isc_mem_get(mctx, sizeof(*keyent));
+ if (keyent == NULL) {
+ dns_name_free(keyname, mctx);
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ keyent->keyname = keyname;
+ keyent->keydatabuf = keydatabuf;
+
+ ISC_LIST_APPEND(conf->trusted_keylist, keyent, link);
+ }
+ }
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (keydatabuf != NULL)
+ isc_buffer_free(&keydatabuf);
+ if (keyname != NULL)
+ isc_mem_put(mctx, keyname, sizeof(*keyname));
+
+ return (result);
+}
+
+isc_result_t
+irs_dnsconf_load(isc_mem_t *mctx, const char *filename, irs_dnsconf_t **confp)
+{
+ irs_dnsconf_t *conf;
+ cfg_parser_t *parser = NULL;
+ cfg_obj_t *cfgobj = NULL;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ REQUIRE(confp != NULL && *confp == NULL);
+
+ conf = isc_mem_get(mctx, sizeof(*conf));
+ if (conf == NULL)
+ return (ISC_R_NOMEMORY);
+
+ conf->mctx = mctx;
+ ISC_LIST_INIT(conf->trusted_keylist);
+
+ /*
+ * If the specified file does not exist, we'll simply with an empty
+ * configuration.
+ */
+ if (!isc_file_exists(filename))
+ goto cleanup;
+
+ result = cfg_parser_create(mctx, NULL, &parser);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = cfg_parse_file(parser, filename, &cfg_type_dnsconf,
+ &cfgobj);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ result = configure_dnsseckeys(conf, cfgobj, dns_rdataclass_in);
+
+ cleanup:
+ if (parser != NULL) {
+ if (cfgobj != NULL)
+ cfg_obj_destroy(parser, &cfgobj);
+ cfg_parser_destroy(&parser);
+ }
+
+ conf->magic = IRS_DNSCONF_MAGIC;
+
+ if (result == ISC_R_SUCCESS)
+ *confp = conf;
+ else
+ irs_dnsconf_destroy(&conf);
+
+ return (result);
+}
+
+void
+irs_dnsconf_destroy(irs_dnsconf_t **confp) {
+ irs_dnsconf_t *conf;
+ irs_dnsconf_dnskey_t *keyent;
+
+ REQUIRE(confp != NULL);
+ conf = *confp;
+ REQUIRE(IRS_DNSCONF_VALID(conf));
+
+ while ((keyent = ISC_LIST_HEAD(conf->trusted_keylist)) != NULL) {
+ ISC_LIST_UNLINK(conf->trusted_keylist, keyent, link);
+
+ isc_buffer_free(&keyent->keydatabuf);
+ dns_name_free(keyent->keyname, conf->mctx);
+ isc_mem_put(conf->mctx, keyent->keyname, sizeof(dns_name_t));
+ isc_mem_put(conf->mctx, keyent, sizeof(*keyent));
+ }
+
+ isc_mem_put(conf->mctx, conf, sizeof(*conf));
+
+ *confp = NULL;
+}
+
+irs_dnsconf_dnskeylist_t *
+irs_dnsconf_gettrustedkeys(irs_dnsconf_t *conf) {
+ REQUIRE(IRS_DNSCONF_VALID(conf));
+
+ return (&conf->trusted_keylist);
+}
diff --git a/lib/irs/gai_strerror.c b/lib/irs/gai_strerror.c
new file mode 100644
index 000000000000..aa021ef264fa
--- /dev/null
+++ b/lib/irs/gai_strerror.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: gai_strerror.c,v 1.5 2009-09-02 23:48:02 tbox Exp $ */
+
+/*! \file gai_strerror.c
+ * gai_strerror() returns an error message corresponding to an
+ * error code returned by getaddrinfo() and getnameinfo(). The following error
+ * codes and their meaning are defined in
+ * \link netdb.h include/irs/netdb.h.\endlink
+ * This implementation is almost an exact copy of lwres/gai_sterror.c except
+ * that it catches up the latest API standard, RFC3493.
+ *
+ * \li #EAI_ADDRFAMILY address family for hostname not supported
+ * \li #EAI_AGAIN temporary failure in name resolution
+ * \li #EAI_BADFLAGS invalid value for ai_flags
+ * \li #EAI_FAIL non-recoverable failure in name resolution
+ * \li #EAI_FAMILY ai_family not supported
+ * \li #EAI_MEMORY memory allocation failure
+ * \li #EAI_NODATA no address associated with hostname (obsoleted in RFC3493)
+ * \li #EAI_NONAME hostname nor servname provided, or not known
+ * \li #EAI_SERVICE servname not supported for ai_socktype
+ * \li #EAI_SOCKTYPE ai_socktype not supported
+ * \li #EAI_SYSTEM system error returned in errno
+ * \li #EAI_BADHINTS Invalid value for hints (non-standard)
+ * \li #EAI_PROTOCOL Resolved protocol is unknown (non-standard)
+ * \li #EAI_OVERFLOW Argument buffer overflow
+ * \li #EAI_INSECUREDATA Insecure Data (experimental)
+ *
+ * The message invalid error code is returned if ecode is out of range.
+ *
+ * ai_flags, ai_family and ai_socktype are elements of the struct
+ * addrinfo used by lwres_getaddrinfo().
+ *
+ * \section gai_strerror_see See Also
+ *
+ * strerror(), getaddrinfo(), getnameinfo(), RFC3493.
+ */
+#include <config.h>
+
+#include <irs/netdb.h>
+
+/*% Text of error messages. */
+static const char *gai_messages[] = {
+ "no error",
+ "address family for hostname not supported",
+ "temporary failure in name resolution",
+ "invalid value for ai_flags",
+ "non-recoverable failure in name resolution",
+ "ai_family not supported",
+ "memory allocation failure",
+ "no address associated with hostname",
+ "hostname nor servname provided, or not known",
+ "servname not supported for ai_socktype",
+ "ai_socktype not supported",
+ "system error returned in errno",
+ "bad hints",
+ "bad protocol",
+ "argument buffer overflow",
+ "insecure data provided"
+};
+
+/*%
+ * Returns an error message corresponding to an error code returned by
+ * getaddrinfo() and getnameinfo()
+ */
+IRS_GAISTRERROR_RETURN_T
+gai_strerror(int ecode) {
+ union {
+ const char *const_ptr;
+ char *deconst_ptr;
+ } ptr;
+
+ if ((ecode < 0) ||
+ (ecode >= (int)(sizeof(gai_messages)/sizeof(*gai_messages))))
+ ptr.const_ptr = "invalid error code";
+ else
+ ptr.const_ptr = gai_messages[ecode];
+ return (ptr.deconst_ptr);
+}
diff --git a/lib/irs/getaddrinfo.c b/lib/irs/getaddrinfo.c
new file mode 100644
index 000000000000..e7075da8e9f4
--- /dev/null
+++ b/lib/irs/getaddrinfo.c
@@ -0,0 +1,1295 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: getaddrinfo.c,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+/**
+ * getaddrinfo() is used to get a list of IP addresses and port
+ * numbers for host hostname and service servname as defined in RFC3493.
+ * hostname and servname are pointers to null-terminated strings
+ * or NULL. hostname is either a host name or a numeric host address
+ * string: a dotted decimal IPv4 address or an IPv6 address. servname is
+ * either a decimal port number or a service name as listed in
+ * /etc/services.
+ *
+ * If the operating system does not provide a struct addrinfo, the
+ * following structure is used:
+ *
+ * \code
+ * struct addrinfo {
+ * int ai_flags; // AI_PASSIVE, AI_CANONNAME
+ * int ai_family; // PF_xxx
+ * int ai_socktype; // SOCK_xxx
+ * int ai_protocol; // 0 or IPPROTO_xxx for IPv4 and IPv6
+ * size_t ai_addrlen; // length of ai_addr
+ * char *ai_canonname; // canonical name for hostname
+ * struct sockaddr *ai_addr; // binary address
+ * struct addrinfo *ai_next; // next structure in linked list
+ * };
+ * \endcode
+ *
+ *
+ * hints is an optional pointer to a struct addrinfo. This structure can
+ * be used to provide hints concerning the type of socket that the caller
+ * supports or wishes to use. The caller can supply the following
+ * structure elements in *hints:
+ *
+ * <ul>
+ * <li>ai_family:
+ * The protocol family that should be used. When ai_family is set
+ * to PF_UNSPEC, it means the caller will accept any protocol
+ * family supported by the operating system.</li>
+ *
+ * <li>ai_socktype:
+ * denotes the type of socket -- SOCK_STREAM, SOCK_DGRAM or
+ * SOCK_RAW -- that is wanted. When ai_socktype is zero the caller
+ * will accept any socket type.</li>
+ *
+ * <li>ai_protocol:
+ * indicates which transport protocol is wanted: IPPROTO_UDP or
+ * IPPROTO_TCP. If ai_protocol is zero the caller will accept any
+ * protocol.</li>
+ *
+ * <li>ai_flags:
+ * Flag bits. If the AI_CANONNAME bit is set, a successful call to
+ * getaddrinfo() will return a null-terminated string
+ * containing the canonical name of the specified hostname in
+ * ai_canonname of the first addrinfo structure returned. Setting
+ * the AI_PASSIVE bit indicates that the returned socket address
+ * structure is intended for used in a call to bind(2). In this
+ * case, if the hostname argument is a NULL pointer, then the IP
+ * address portion of the socket address structure will be set to
+ * INADDR_ANY for an IPv4 address or IN6ADDR_ANY_INIT for an IPv6
+ * address.<br /><br />
+ *
+ * When ai_flags does not set the AI_PASSIVE bit, the returned
+ * socket address structure will be ready for use in a call to
+ * connect(2) for a connection-oriented protocol or connect(2),
+ * sendto(2), or sendmsg(2) if a connectionless protocol was
+ * chosen. The IP address portion of the socket address structure
+ * will be set to the loopback address if hostname is a NULL
+ * pointer and AI_PASSIVE is not set in ai_flags.<br /><br />
+ *
+ * If ai_flags is set to AI_NUMERICHOST it indicates that hostname
+ * should be treated as a numeric string defining an IPv4 or IPv6
+ * address and no name resolution should be attempted.
+ * </li></ul>
+ *
+ * All other elements of the struct addrinfo passed via hints must be
+ * zero.
+ *
+ * A hints of NULL is treated as if the caller provided a struct addrinfo
+ * initialized to zero with ai_familyset to PF_UNSPEC.
+ *
+ * After a successful call to getaddrinfo(), *res is a pointer to a
+ * linked list of one or more addrinfo structures. Each struct addrinfo
+ * in this list cn be processed by following the ai_next pointer, until a
+ * NULL pointer is encountered. The three members ai_family, ai_socktype,
+ * and ai_protocol in each returned addrinfo structure contain the
+ * corresponding arguments for a call to socket(2). For each addrinfo
+ * structure in the list, the ai_addr member points to a filled-in socket
+ * address structure of length ai_addrlen.
+ *
+ * All of the information returned by getaddrinfo() is dynamically
+ * allocated: the addrinfo structures, and the socket address structures
+ * and canonical host name strings pointed to by the addrinfostructures.
+ * Memory allocated for the dynamically allocated structures created by a
+ * successful call to getaddrinfo() is released by freeaddrinfo().
+ * ai is a pointer to a struct addrinfo created by a call to getaddrinfo().
+ *
+ * \section irsreturn RETURN VALUES
+ *
+ * getaddrinfo() returns zero on success or one of the error codes
+ * listed in gai_strerror() if an error occurs. If both hostname and
+ * servname are NULL getaddrinfo() returns #EAI_NONAME.
+ *
+ * \section irssee SEE ALSO
+ *
+ * getaddrinfo(), freeaddrinfo(),
+ * gai_strerror(), RFC3493, getservbyname(3), connect(2),
+ * sendto(2), sendmsg(2), socket(2).
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <isc/app.h>
+#include <isc/buffer.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
+#include <dns/result.h>
+
+#include <irs/context.h>
+#include <irs/netdb.h>
+#include <irs/resconf.h>
+
+#define SA(addr) ((struct sockaddr *)(addr))
+#define SIN(addr) ((struct sockaddr_in *)(addr))
+#define SIN6(addr) ((struct sockaddr_in6 *)(addr))
+#define SLOCAL(addr) ((struct sockaddr_un *)(addr))
+
+/*! \struct addrinfo
+ */
+static struct addrinfo
+ *ai_concat(struct addrinfo *ai1, struct addrinfo *ai2),
+ *ai_reverse(struct addrinfo *oai),
+ *ai_clone(struct addrinfo *oai, int family),
+ *ai_alloc(int family, int addrlen);
+#ifdef AF_LOCAL
+static int get_local(const char *name, int socktype, struct addrinfo **res);
+#endif
+
+static int
+resolve_name(int family, const char *hostname, int flags,
+ struct addrinfo **aip, int socktype, int port);
+
+static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port);
+static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port);
+static void set_order(int, int (**)(const char *, int, struct addrinfo **,
+ int, int));
+
+#define FOUND_IPV4 0x1
+#define FOUND_IPV6 0x2
+#define FOUND_MAX 2
+
+#define ISC_AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)
+/*%
+ * Get a list of IP addresses and port numbers for host hostname and
+ * service servname.
+ */
+int
+getaddrinfo(const char *hostname, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ struct servent *sp;
+ const char *proto;
+ int family, socktype, flags, protocol;
+ struct addrinfo *ai, *ai_list;
+ int err = 0;
+ int port, i;
+ int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **,
+ int, int);
+
+ if (hostname == NULL && servname == NULL)
+ return (EAI_NONAME);
+
+ proto = NULL;
+ if (hints != NULL) {
+ if ((hints->ai_flags & ~(ISC_AI_MASK)) != 0)
+ return (EAI_BADFLAGS);
+ if (hints->ai_addrlen || hints->ai_canonname ||
+ hints->ai_addr || hints->ai_next) {
+ errno = EINVAL;
+ return (EAI_SYSTEM);
+ }
+ family = hints->ai_family;
+ socktype = hints->ai_socktype;
+ protocol = hints->ai_protocol;
+ flags = hints->ai_flags;
+ switch (family) {
+ case AF_UNSPEC:
+ switch (hints->ai_socktype) {
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ }
+ break;
+ case AF_INET:
+ case AF_INET6:
+ switch (hints->ai_socktype) {
+ case 0:
+ break;
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ case SOCK_RAW:
+ break;
+ default:
+ return (EAI_SOCKTYPE);
+ }
+ break;
+#ifdef AF_LOCAL
+ case AF_LOCAL:
+ switch (hints->ai_socktype) {
+ case 0:
+ break;
+ case SOCK_STREAM:
+ break;
+ case SOCK_DGRAM:
+ break;
+ default:
+ return (EAI_SOCKTYPE);
+ }
+ break;
+#endif
+ default:
+ return (EAI_FAMILY);
+ }
+ } else {
+ protocol = 0;
+ family = 0;
+ socktype = 0;
+ flags = 0;
+ }
+
+#ifdef AF_LOCAL
+ /*!
+ * First, deal with AF_LOCAL. If the family was not set,
+ * then assume AF_LOCAL if the first character of the
+ * hostname/servname is '/'.
+ */
+
+ if (hostname != NULL &&
+ (family == AF_LOCAL || (family == 0 && *hostname == '/')))
+ return (get_local(hostname, socktype, res));
+
+ if (servname != NULL &&
+ (family == AF_LOCAL || (family == 0 && *servname == '/')))
+ return (get_local(servname, socktype, res));
+#endif
+
+ /*
+ * Ok, only AF_INET and AF_INET6 left.
+ */
+ ai_list = NULL;
+
+ /*
+ * First, look up the service name (port) if it was
+ * requested. If the socket type wasn't specified, then
+ * try and figure it out.
+ */
+ if (servname != NULL) {
+ char *e;
+
+ port = strtol(servname, &e, 10);
+ if (*e == '\0') {
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+ if (port < 0 || port > 65535)
+ return (EAI_SERVICE);
+ port = htons((unsigned short) port);
+ } else {
+ sp = getservbyname(servname, proto);
+ if (sp == NULL)
+ return (EAI_SERVICE);
+ port = sp->s_port;
+ if (socktype == 0) {
+ if (strcmp(sp->s_proto, "tcp") == 0)
+ socktype = SOCK_STREAM;
+ else if (strcmp(sp->s_proto, "udp") == 0)
+ socktype = SOCK_DGRAM;
+ }
+ }
+ } else
+ port = 0;
+
+ /*
+ * Next, deal with just a service name, and no hostname.
+ * (we verified that one of them was non-null up above).
+ */
+ if (hostname == NULL && (flags & AI_PASSIVE) != 0) {
+ if (family == AF_INET || family == 0) {
+ ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = protocol;
+ SIN(ai->ai_addr)->sin_port = port;
+ ai->ai_next = ai_list;
+ ai_list = ai;
+ }
+
+ if (family == AF_INET6 || family == 0) {
+ ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6));
+ if (ai == NULL) {
+ freeaddrinfo(ai_list);
+ return (EAI_MEMORY);
+ }
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = protocol;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ ai->ai_next = ai_list;
+ ai_list = ai;
+ }
+
+ *res = ai_list;
+ return (0);
+ }
+
+ /*
+ * If the family isn't specified or AI_NUMERICHOST specified, check
+ * first to see if it is a numeric address.
+ * Though the gethostbyname2() routine will recognize numeric addresses,
+ * it will only recognize the format that it is being called for. Thus,
+ * a numeric AF_INET address will be treated by the AF_INET6 call as
+ * a domain name, and vice versa. Checking for both numerics here
+ * avoids that.
+ */
+ if (hostname != NULL &&
+ (family == 0 || (flags & AI_NUMERICHOST) != 0)) {
+ char abuf[sizeof(struct in6_addr)];
+ char nbuf[NI_MAXHOST];
+ int addrsize, addroff;
+#ifdef IRS_HAVE_SIN6_SCOPE_ID
+ char *p, *ep;
+ char ntmp[NI_MAXHOST];
+ isc_uint32_t scopeid;
+#endif
+
+#ifdef IRS_HAVE_SIN6_SCOPE_ID
+ /*
+ * Scope identifier portion.
+ */
+ ntmp[0] = '\0';
+ if (strchr(hostname, '%') != NULL) {
+ strncpy(ntmp, hostname, sizeof(ntmp) - 1);
+ ntmp[sizeof(ntmp) - 1] = '\0';
+ p = strchr(ntmp, '%');
+ ep = NULL;
+
+ /*
+ * Vendors may want to support non-numeric
+ * scopeid around here.
+ */
+
+ if (p != NULL)
+ scopeid = (isc_uint32_t)strtoul(p + 1,
+ &ep, 10);
+ if (p != NULL && ep != NULL && ep[0] == '\0')
+ *p = '\0';
+ else {
+ ntmp[0] = '\0';
+ scopeid = 0;
+ }
+ } else
+ scopeid = 0;
+#endif
+
+ if (inet_pton(AF_INET, hostname, (struct in_addr *)abuf)
+ == 1) {
+ if (family == AF_INET6) {
+ /*
+ * Convert to a V4 mapped address.
+ */
+ struct in6_addr *a6 = (struct in6_addr *)abuf;
+ memcpy(&a6->s6_addr[12], &a6->s6_addr[0], 4);
+ memset(&a6->s6_addr[10], 0xff, 2);
+ memset(&a6->s6_addr[0], 0, 10);
+ goto inet6_addr;
+ }
+ addrsize = sizeof(struct in_addr);
+ addroff = (char *)(&SIN(0)->sin_addr) - (char *)0;
+ family = AF_INET;
+ goto common;
+#ifdef IRS_HAVE_SIN6_SCOPE_ID
+ } else if (ntmp[0] != '\0' &&
+ inet_pton(AF_INET6, ntmp, abuf) == 1) {
+ if (family && family != AF_INET6)
+ return (EAI_NONAME);
+ addrsize = sizeof(struct in6_addr);
+ addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ family = AF_INET6;
+ goto common;
+#endif
+ } else if (inet_pton(AF_INET6, hostname, abuf) == 1) {
+ if (family != 0 && family != AF_INET6)
+ return (EAI_NONAME);
+ inet6_addr:
+ addrsize = sizeof(struct in6_addr);
+ addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ family = AF_INET6;
+
+ common:
+ ai = ai_alloc(family,
+ ((family == AF_INET6) ?
+ sizeof(struct sockaddr_in6) :
+ sizeof(struct sockaddr_in)));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+ ai_list = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy((char *)ai->ai_addr + addroff, abuf, addrsize);
+ if ((flags & AI_CANONNAME) != 0) {
+#ifdef IRS_HAVE_SIN6_SCOPE_ID
+ if (ai->ai_family == AF_INET6)
+ SIN6(ai->ai_addr)->sin6_scope_id =
+ scopeid;
+#endif
+ if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
+ nbuf, sizeof(nbuf), NULL, 0,
+ NI_NUMERICHOST) == 0) {
+ ai->ai_canonname = strdup(nbuf);
+ if (ai->ai_canonname == NULL) {
+ freeaddrinfo(ai);
+ return (EAI_MEMORY);
+ }
+ } else {
+ /* XXX raise error? */
+ ai->ai_canonname = NULL;
+ }
+ }
+ goto done;
+ } else if ((flags & AI_NUMERICHOST) != 0) {
+ return (EAI_NONAME);
+ }
+ }
+
+ if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
+ set_order(family, net_order);
+ for (i = 0; i < FOUND_MAX; i++) {
+ if (net_order[i] == NULL)
+ break;
+ err = (net_order[i])(hostname, flags, &ai_list,
+ socktype, port);
+ if (err != 0) {
+ if (ai_list != NULL)
+ freeaddrinfo(ai_list);
+ break;
+ }
+ }
+ } else
+ err = resolve_name(family, hostname, flags, &ai_list,
+ socktype, port);
+
+ if (ai_list == NULL) {
+ if (err == 0)
+ err = EAI_NONAME;
+ return (err);
+ }
+
+done:
+ ai_list = ai_reverse(ai_list);
+
+ *res = ai_list;
+ return (0);
+}
+
+typedef struct gai_restrans {
+ dns_clientrestrans_t *xid;
+ isc_boolean_t is_inprogress;
+ int error;
+ struct addrinfo ai_sentinel;
+ struct gai_resstate *resstate;
+} gai_restrans_t;
+
+typedef struct gai_resstate {
+ isc_mem_t *mctx;
+ struct gai_statehead *head;
+ dns_fixedname_t fixedname;
+ dns_name_t *qname;
+ gai_restrans_t *trans4;
+ gai_restrans_t *trans6;
+ ISC_LINK(struct gai_resstate) link;
+} gai_resstate_t;
+
+typedef struct gai_statehead {
+ int ai_family;
+ int ai_flags;
+ int ai_socktype;
+ int ai_port;
+ isc_appctx_t *actx;
+ dns_client_t *dnsclient;
+ ISC_LIST(struct gai_resstate) resstates;
+ unsigned int activestates;
+} gai_statehead_t;
+
+static isc_result_t
+make_resstate(isc_mem_t *mctx, gai_statehead_t *head, const char *hostname,
+ const char *domain, gai_resstate_t **statep)
+{
+ isc_result_t result;
+ gai_resstate_t *state;
+ dns_fixedname_t fixeddomain;
+ dns_name_t *qdomain;
+ size_t namelen;
+ isc_buffer_t b;
+ isc_boolean_t need_v4 = ISC_FALSE;
+ isc_boolean_t need_v6 = ISC_FALSE;
+
+ state = isc_mem_get(mctx, sizeof(*state));
+ if (state == NULL)
+ return (ISC_R_NOMEMORY);
+
+ /* Construct base domain name */
+ namelen = strlen(domain);
+ isc_buffer_init(&b, domain, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&fixeddomain);
+ qdomain = dns_fixedname_name(&fixeddomain);
+ result = dns_name_fromtext(qdomain, &b, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, state, sizeof(*state));
+ return (result);
+ }
+
+ /* Construct query name */
+ namelen = strlen(hostname);
+ isc_buffer_init(&b, hostname, namelen);
+ isc_buffer_add(&b, namelen);
+ dns_fixedname_init(&state->fixedname);
+ state->qname = dns_fixedname_name(&state->fixedname);
+ result = dns_name_fromtext(state->qname, &b, qdomain, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, state, sizeof(*state));
+ return (result);
+ }
+
+ if (head->ai_family == AF_UNSPEC || head->ai_family == AF_INET)
+ need_v4 = ISC_TRUE;
+ if (head->ai_family == AF_UNSPEC || head->ai_family == AF_INET6)
+ need_v6 = ISC_TRUE;
+
+ state->trans6 = NULL;
+ state->trans4 = NULL;
+ if (need_v4) {
+ state->trans4 = isc_mem_get(mctx, sizeof(gai_restrans_t));
+ if (state->trans4 == NULL) {
+ isc_mem_put(mctx, state, sizeof(*state));
+ return (ISC_R_NOMEMORY);
+ }
+ state->trans4->error = 0;
+ state->trans4->xid = NULL;
+ state->trans4->resstate = state;
+ state->trans4->is_inprogress = ISC_TRUE;
+ state->trans4->ai_sentinel.ai_next = NULL;
+ }
+ if (need_v6) {
+ state->trans6 = isc_mem_get(mctx, sizeof(gai_restrans_t));
+ if (state->trans6 == NULL) {
+ if (state->trans4 != NULL)
+ isc_mem_put(mctx, state->trans4,
+ sizeof(*state->trans4));
+ isc_mem_put(mctx, state, sizeof(*state));
+ return (ISC_R_NOMEMORY);
+ }
+ state->trans6->error = 0;
+ state->trans6->xid = NULL;
+ state->trans6->resstate = state;
+ state->trans6->is_inprogress = ISC_TRUE;
+ state->trans6->ai_sentinel.ai_next = NULL;
+ }
+
+ state->mctx = mctx;
+ state->head = head;
+ ISC_LINK_INIT(state, link);
+
+ *statep = state;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+make_resstates(isc_mem_t *mctx, const char *hostname, gai_statehead_t *head,
+ irs_resconf_t *resconf)
+{
+ isc_result_t result;
+ irs_resconf_searchlist_t *searchlist;
+ irs_resconf_search_t *searchent;
+ gai_resstate_t *resstate, *resstate0;
+
+ resstate0 = NULL;
+ result = make_resstate(mctx, head, hostname, ".", &resstate0);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ searchlist = irs_resconf_getsearchlist(resconf);
+ for (searchent = ISC_LIST_HEAD(*searchlist); searchent != NULL;
+ searchent = ISC_LIST_NEXT(searchent, link)) {
+ resstate = NULL;
+ result = make_resstate(mctx, head, hostname,
+ (const char *)searchent->domain,
+ &resstate);
+ if (result != ISC_R_SUCCESS)
+ break;
+
+ ISC_LIST_APPEND(head->resstates, resstate, link);
+ head->activestates++;
+ }
+
+ /*
+ * Insert the original hostname either at the head or the tail of the
+ * state list, depending on the number of labels contained in the
+ * original name and the 'ndots' configuration parameter.
+ */
+ if (dns_name_countlabels(resstate0->qname) >
+ irs_resconf_getndots(resconf) + 1) {
+ ISC_LIST_PREPEND(head->resstates, resstate0, link);
+ } else
+ ISC_LIST_APPEND(head->resstates, resstate0, link);
+ head->activestates++;
+
+ if (result != ISC_R_SUCCESS) {
+ while ((resstate = ISC_LIST_HEAD(head->resstates)) != NULL) {
+ ISC_LIST_UNLINK(head->resstates, resstate, link);
+ if (resstate->trans4 != NULL) {
+ isc_mem_put(mctx, resstate->trans4,
+ sizeof(*resstate->trans4));
+ }
+ if (resstate->trans6 != NULL) {
+ isc_mem_put(mctx, resstate->trans6,
+ sizeof(*resstate->trans6));
+ }
+
+ isc_mem_put(mctx, resstate, sizeof(*resstate));
+ }
+ }
+
+ return (result);
+}
+
+static void
+process_answer(isc_task_t *task, isc_event_t *event) {
+ int error = 0, family;
+ gai_restrans_t *trans = event->ev_arg;
+ gai_resstate_t *resstate;
+ dns_clientresevent_t *rev = (dns_clientresevent_t *)event;
+ dns_rdatatype_t qtype;
+ dns_name_t *name;
+
+ REQUIRE(trans != NULL);
+ resstate = trans->resstate;
+ REQUIRE(resstate != NULL);
+ REQUIRE(task != NULL);
+
+ if (trans == resstate->trans4) {
+ family = AF_INET;
+ qtype = dns_rdatatype_a;
+ } else {
+ INSIST(trans == resstate->trans6);
+ family = AF_INET6;
+ qtype = dns_rdatatype_aaaa;
+ }
+
+ INSIST(trans->is_inprogress);
+ trans->is_inprogress = ISC_FALSE;
+
+ switch (rev->result) {
+ case ISC_R_SUCCESS:
+ case DNS_R_NCACHENXDOMAIN: /* treat this as a fatal error? */
+ case DNS_R_NCACHENXRRSET:
+ break;
+ default:
+ switch (rev->vresult) {
+ case DNS_R_SIGINVALID:
+ case DNS_R_SIGEXPIRED:
+ case DNS_R_SIGFUTURE:
+ case DNS_R_KEYUNAUTHORIZED:
+ case DNS_R_MUSTBESECURE:
+ case DNS_R_COVERINGNSEC:
+ case DNS_R_NOTAUTHORITATIVE:
+ case DNS_R_NOVALIDKEY:
+ case DNS_R_NOVALIDDS:
+ case DNS_R_NOVALIDSIG:
+ error = EAI_INSECUREDATA;
+ break;
+ default:
+ error = EAI_FAIL;
+ }
+ goto done;
+ }
+
+ /* Parse the response and construct the addrinfo chain */
+ for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL;
+ name = ISC_LIST_NEXT(name, link)) {
+ isc_result_t result;
+ dns_rdataset_t *rdataset;
+ isc_buffer_t b;
+ isc_region_t r;
+ char t[1024];
+
+ for (rdataset = ISC_LIST_HEAD(name->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (!dns_rdataset_isassociated(rdataset))
+ continue;
+ if (rdataset->type != qtype)
+ continue;
+
+ if ((resstate->head->ai_flags & AI_CANONNAME) != 0) {
+ isc_buffer_init(&b, t, sizeof(t));
+ result = dns_name_totext(name, ISC_TRUE, &b);
+ if (result != ISC_R_SUCCESS) {
+ error = EAI_FAIL;
+ goto done;
+ }
+ isc_buffer_putuint8(&b, '\0');
+ isc_buffer_usedregion(&b, &r);
+ }
+
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ struct addrinfo *ai;
+ dns_rdata_t rdata;
+ dns_rdata_in_a_t rdata_a;
+ dns_rdata_in_aaaa_t rdata_aaaa;
+
+ ai = ai_alloc(family,
+ ((family == AF_INET6) ?
+ sizeof(struct sockaddr_in6) :
+ sizeof(struct sockaddr_in)));
+ if (ai == NULL) {
+ error = EAI_MEMORY;
+ goto done;
+ }
+ ai->ai_socktype = resstate->head->ai_socktype;
+ ai->ai_next = trans->ai_sentinel.ai_next;
+ trans->ai_sentinel.ai_next = ai;
+
+ /*
+ * Set AF-specific parameters
+ * (IPv4/v6 address/port)
+ */
+ dns_rdata_init(&rdata);
+ switch (family) {
+ case AF_INET:
+ dns_rdataset_current(rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &rdata_a,
+ NULL);
+
+ SIN(ai->ai_addr)->sin_port =
+ resstate->head->ai_port;
+ memcpy(&SIN(ai->ai_addr)->sin_addr,
+ &rdata_a.in_addr, 4);
+ dns_rdata_freestruct(&rdata_a);
+ break;
+ case AF_INET6:
+ dns_rdataset_current(rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &rdata_aaaa,
+ NULL);
+ SIN6(ai->ai_addr)->sin6_port =
+ resstate->head->ai_port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr,
+ &rdata_aaaa.in6_addr, 16);
+ dns_rdata_freestruct(&rdata_aaaa);
+ break;
+ }
+
+ if ((resstate->head->ai_flags & AI_CANONNAME)
+ != 0) {
+ ai->ai_canonname =
+ strdup((const char *)r.base);
+ if (ai->ai_canonname == NULL) {
+ error = EAI_MEMORY;
+ goto done;
+ }
+ }
+ }
+ }
+ }
+
+ done:
+ dns_client_freeresanswer(resstate->head->dnsclient, &rev->answerlist);
+ dns_client_destroyrestrans(&trans->xid);
+
+ isc_event_free(&event);
+
+ /* Make sure that error == 0 iff we have a non-empty list */
+ if (error == 0) {
+ if (trans->ai_sentinel.ai_next == NULL)
+ error = EAI_NONAME;
+ } else {
+ if (trans->ai_sentinel.ai_next != NULL) {
+ freeaddrinfo(trans->ai_sentinel.ai_next);
+ trans->ai_sentinel.ai_next = NULL;
+ }
+ }
+ trans->error = error;
+
+ /* Check whether we are done */
+ if ((resstate->trans4 == NULL || !resstate->trans4->is_inprogress) &&
+ (resstate->trans6 == NULL || !resstate->trans6->is_inprogress)) {
+ /*
+ * We're done for this state. If there is no other outstanding
+ * state, we can exit.
+ */
+ resstate->head->activestates--;
+ if (resstate->head->activestates == 0) {
+ isc_app_ctxsuspend(resstate->head->actx);
+ return;
+ }
+
+ /*
+ * There are outstanding states, but if we are at the head
+ * of the state list (i.e., at the highest search priority)
+ * and have any answer, we can stop now by canceling the
+ * others.
+ */
+ if (resstate == ISC_LIST_HEAD(resstate->head->resstates)) {
+ if ((resstate->trans4 != NULL &&
+ resstate->trans4->ai_sentinel.ai_next != NULL) ||
+ (resstate->trans6 != NULL &&
+ resstate->trans6->ai_sentinel.ai_next != NULL)) {
+ gai_resstate_t *rest;
+
+ for (rest = ISC_LIST_NEXT(resstate, link);
+ rest != NULL;
+ rest = ISC_LIST_NEXT(rest, link)) {
+ if (rest->trans4 != NULL &&
+ rest->trans4->xid != NULL)
+ dns_client_cancelresolve(
+ rest->trans4->xid);
+ if (rest->trans6 != NULL &&
+ rest->trans6->xid != NULL)
+ dns_client_cancelresolve(
+ rest->trans6->xid);
+ }
+ } else {
+ /*
+ * This search fails, so we move to the tail
+ * of the list so that the next entry will
+ * have the highest priority.
+ */
+ ISC_LIST_UNLINK(resstate->head->resstates,
+ resstate, link);
+ ISC_LIST_APPEND(resstate->head->resstates,
+ resstate, link);
+ }
+ }
+ }
+}
+
+static int
+resolve_name(int family, const char *hostname, int flags,
+ struct addrinfo **aip, int socktype, int port)
+{
+ isc_result_t result;
+ irs_context_t *irsctx;
+ irs_resconf_t *conf;
+ isc_mem_t *mctx;
+ isc_appctx_t *actx;
+ isc_task_t *task;
+ int terror = 0;
+ int error = 0;
+ dns_client_t *client;
+ gai_resstate_t *resstate;
+ gai_statehead_t head;
+ isc_boolean_t all_fail = ISC_TRUE;
+
+ /* get IRS context and the associated parameters */
+ irsctx = NULL;
+ result = irs_context_get(&irsctx);
+ if (result != ISC_R_SUCCESS)
+ return (EAI_FAIL);
+ actx = irs_context_getappctx(irsctx);
+
+ mctx = irs_context_getmctx(irsctx);
+ task = irs_context_gettask(irsctx);
+ conf = irs_context_getresconf(irsctx);
+ client = irs_context_getdnsclient(irsctx);
+
+ /* construct resolution states */
+ head.activestates = 0;
+ head.ai_family = family;
+ head.ai_socktype = socktype;
+ head.ai_flags = flags;
+ head.ai_port = port;
+ head.actx = actx;
+ head.dnsclient = client;
+ ISC_LIST_INIT(head.resstates);
+ result = make_resstates(mctx, hostname, &head, conf);
+ if (result != ISC_R_SUCCESS)
+ return (EAI_FAIL);
+
+ for (resstate = ISC_LIST_HEAD(head.resstates);
+ resstate != NULL; resstate = ISC_LIST_NEXT(resstate, link)) {
+ if (resstate->trans4 != NULL) {
+ result = dns_client_startresolve(client,
+ resstate->qname,
+ dns_rdataclass_in,
+ dns_rdatatype_a,
+ 0, task,
+ process_answer,
+ resstate->trans4,
+ &resstate->trans4->xid);
+ if (result == ISC_R_SUCCESS) {
+ resstate->trans4->is_inprogress = ISC_TRUE;
+ all_fail = ISC_FALSE;
+ } else
+ resstate->trans4->is_inprogress = ISC_FALSE;
+ }
+ if (resstate->trans6 != NULL) {
+ result = dns_client_startresolve(client,
+ resstate->qname,
+ dns_rdataclass_in,
+ dns_rdatatype_aaaa,
+ 0, task,
+ process_answer,
+ resstate->trans6,
+ &resstate->trans6->xid);
+ if (result == ISC_R_SUCCESS) {
+ resstate->trans6->is_inprogress = ISC_TRUE;
+ all_fail = ISC_FALSE;
+ } else
+ resstate->trans6->is_inprogress= ISC_FALSE;
+ }
+ }
+ if (!all_fail) {
+ /* Start all the events */
+ isc_app_ctxrun(actx);
+ } else
+ error = EAI_FAIL;
+
+ /* Cleanup */
+ while ((resstate = ISC_LIST_HEAD(head.resstates)) != NULL) {
+ int terror4 = 0, terror6 = 0;
+
+ ISC_LIST_UNLINK(head.resstates, resstate, link);
+
+ if (*aip == NULL) {
+ struct addrinfo *sentinel4 = NULL;
+ struct addrinfo *sentinel6 = NULL;
+
+ if (resstate->trans4 != NULL) {
+ sentinel4 =
+ resstate->trans4->ai_sentinel.ai_next;
+ resstate->trans4->ai_sentinel.ai_next = NULL;
+ }
+ if (resstate->trans6 != NULL) {
+ sentinel6 =
+ resstate->trans6->ai_sentinel.ai_next;
+ resstate->trans6->ai_sentinel.ai_next = NULL;
+ }
+ *aip = ai_concat(sentinel4, sentinel6);
+ }
+
+ if (resstate->trans4 != NULL) {
+ INSIST(resstate->trans4->xid == NULL);
+ terror4 = resstate->trans4->error;
+ isc_mem_put(mctx, resstate->trans4,
+ sizeof(*resstate->trans4));
+ }
+ if (resstate->trans6 != NULL) {
+ INSIST(resstate->trans6->xid == NULL);
+ terror6 = resstate->trans6->error;
+ isc_mem_put(mctx, resstate->trans6,
+ sizeof(*resstate->trans6));
+ }
+
+ /*
+ * If the entire lookup fails, we need to choose an appropriate
+ * error code from individual codes. We'll try to provide as
+ * specific a code as possible. In general, we are going to
+ * find an error code other than EAI_NONAME (which is too
+ * generic and may actually not be problematic in some cases).
+ * EAI_NONAME will be set below if no better code is found.
+ */
+ if (terror == 0 || terror == EAI_NONAME) {
+ if (terror4 != 0 && terror4 != EAI_NONAME)
+ terror = terror4;
+ else if (terror6 != 0 && terror6 != EAI_NONAME)
+ terror = terror6;
+ }
+
+ isc_mem_put(mctx, resstate, sizeof(*resstate));
+ }
+
+ if (*aip == NULL) {
+ error = terror;
+ if (error == 0)
+ error = EAI_NONAME;
+ }
+
+#if 1 /* XXX: enabled for finding leaks. should be cleaned up later. */
+ isc_app_ctxfinish(actx);
+ irs_context_destroy(&irsctx);
+#endif
+
+ return (error);
+}
+
+static char *
+irs_strsep(char **stringp, const char *delim) {
+ char *string = *stringp;
+ char *s;
+ const char *d;
+ char sc, dc;
+
+ if (string == NULL)
+ return (NULL);
+
+ for (s = string; *s != '\0'; s++) {
+ sc = *s;
+ for (d = delim; (dc = *d) != '\0'; d++)
+ if (sc == dc) {
+ *s++ = '\0';
+ *stringp = s;
+ return (string);
+ }
+ }
+ *stringp = NULL;
+ return (string);
+}
+
+static void
+set_order(int family, int (**net_order)(const char *, int, struct addrinfo **,
+ int, int))
+{
+ char *order, *tok;
+ int found;
+
+ if (family) {
+ switch (family) {
+ case AF_INET:
+ *net_order++ = add_ipv4;
+ break;
+ case AF_INET6:
+ *net_order++ = add_ipv6;
+ break;
+ }
+ } else {
+ order = getenv("NET_ORDER");
+ found = 0;
+ while (order != NULL) {
+ /*
+ * We ignore any unknown names.
+ */
+ tok = irs_strsep(&order, ":");
+ if (strcasecmp(tok, "inet6") == 0) {
+ if ((found & FOUND_IPV6) == 0)
+ *net_order++ = add_ipv6;
+ found |= FOUND_IPV6;
+ } else if (strcasecmp(tok, "inet") == 0 ||
+ strcasecmp(tok, "inet4") == 0) {
+ if ((found & FOUND_IPV4) == 0)
+ *net_order++ = add_ipv4;
+ found |= FOUND_IPV4;
+ }
+ }
+
+ /*
+ * Add in anything that we didn't find.
+ */
+ if ((found & FOUND_IPV4) == 0)
+ *net_order++ = add_ipv4;
+ if ((found & FOUND_IPV6) == 0)
+ *net_order++ = add_ipv6;
+ }
+ *net_order = NULL;
+ return;
+}
+
+static char v4_loop[4] = { 127, 0, 0, 1 };
+
+static int
+add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port)
+{
+ struct addrinfo *ai;
+
+ UNUSED(hostname);
+ UNUSED(flags);
+
+ ai = ai_clone(*aip, AF_INET); /* don't use ai_clone() */
+ if (ai == NULL) {
+ freeaddrinfo(*aip);
+ return (EAI_MEMORY);
+ }
+
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4);
+
+ return (0);
+}
+
+static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+static int
+add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port)
+{
+ struct addrinfo *ai;
+
+ UNUSED(hostname);
+ UNUSED(flags);
+
+ ai = ai_clone(*aip, AF_INET6); /* don't use ai_clone() */
+ if (ai == NULL) {
+ freeaddrinfo(*aip);
+ return (EAI_MEMORY);
+ }
+
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16);
+
+ return (0);
+}
+
+/*% Free address info. */
+void
+freeaddrinfo(struct addrinfo *ai) {
+ struct addrinfo *ai_next;
+
+ while (ai != NULL) {
+ ai_next = ai->ai_next;
+ if (ai->ai_addr != NULL)
+ free(ai->ai_addr);
+ if (ai->ai_canonname)
+ free(ai->ai_canonname);
+ free(ai);
+ ai = ai_next;
+ }
+}
+
+#ifdef AF_LOCAL
+static int
+get_local(const char *name, int socktype, struct addrinfo **res) {
+ struct addrinfo *ai;
+ struct sockaddr_un *slocal;
+
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+
+ ai = ai_alloc(AF_LOCAL, sizeof(*slocal));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+
+ slocal = SLOCAL(ai->ai_addr);
+ strncpy(slocal->sun_path, name, sizeof(slocal->sun_path));
+
+ ai->ai_socktype = socktype;
+ /*
+ * ai->ai_flags, ai->ai_protocol, ai->ai_canonname,
+ * and ai->ai_next were initialized to zero.
+ */
+
+ *res = ai;
+ return (0);
+}
+#endif
+
+/*!
+ * Allocate an addrinfo structure, and a sockaddr structure
+ * of the specificed length. We initialize:
+ * ai_addrlen
+ * ai_family
+ * ai_addr
+ * ai_addr->sa_family
+ * ai_addr->sa_len (IRS_PLATFORM_HAVESALEN)
+ * and everything else is initialized to zero.
+ */
+static struct addrinfo *
+ai_alloc(int family, int addrlen) {
+ struct addrinfo *ai;
+
+ ai = (struct addrinfo *)calloc(1, sizeof(*ai));
+ if (ai == NULL)
+ return (NULL);
+
+ ai->ai_addr = SA(calloc(1, addrlen));
+ if (ai->ai_addr == NULL) {
+ free(ai);
+ return (NULL);
+ }
+ ai->ai_addrlen = addrlen;
+ ai->ai_family = family;
+ ai->ai_addr->sa_family = family;
+#ifdef IRS_PLATFORM_HAVESALEN
+ ai->ai_addr->sa_len = addrlen;
+#endif
+ return (ai);
+}
+
+static struct addrinfo *
+ai_clone(struct addrinfo *oai, int family) {
+ struct addrinfo *ai;
+
+ ai = ai_alloc(family, ((family == AF_INET6) ?
+ sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)));
+
+ if (ai == NULL) {
+ if (oai != NULL)
+ freeaddrinfo(oai);
+ return (NULL);
+ }
+ if (oai == NULL)
+ return (ai);
+
+ ai->ai_flags = oai->ai_flags;
+ ai->ai_socktype = oai->ai_socktype;
+ ai->ai_protocol = oai->ai_protocol;
+ ai->ai_canonname = NULL;
+ ai->ai_next = oai;
+ return (ai);
+}
+
+static struct addrinfo *
+ai_reverse(struct addrinfo *oai) {
+ struct addrinfo *nai, *tai;
+
+ nai = NULL;
+
+ while (oai != NULL) {
+ /*
+ * Grab one off the old list.
+ */
+ tai = oai;
+ oai = oai->ai_next;
+ /*
+ * Put it on the front of the new list.
+ */
+ tai->ai_next = nai;
+ nai = tai;
+ }
+ return (nai);
+}
+
+
+static struct addrinfo *
+ai_concat(struct addrinfo *ai1, struct addrinfo *ai2) {
+ struct addrinfo *ai_tmp;
+
+ if (ai1 == NULL)
+ return (ai2);
+ else if (ai2 == NULL)
+ return (ai1);
+
+ for (ai_tmp = ai1; ai_tmp != NULL && ai_tmp->ai_next != NULL;
+ ai_tmp = ai_tmp->ai_next)
+ ;
+
+ ai_tmp->ai_next = ai2;
+
+ return (ai1);
+}
diff --git a/lib/irs/getnameinfo.c b/lib/irs/getnameinfo.c
new file mode 100644
index 000000000000..fadd8d8b4624
--- /dev/null
+++ b/lib/irs/getnameinfo.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: getnameinfo.c,v 1.4 2009-09-02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/**
+ * getnameinfo() returns the hostname for the struct sockaddr sa which is
+ * salen bytes long. The hostname is of length hostlen and is returned via
+ * *host. The maximum length of the hostname is 1025 bytes: #NI_MAXHOST.
+ *
+ * The name of the service associated with the port number in sa is
+ * returned in *serv. It is servlen bytes long. The maximum length of the
+ * service name is #NI_MAXSERV - 32 bytes.
+ *
+ * The flags argument sets the following bits:
+ *
+ * \li #NI_NOFQDN:
+ * A fully qualified domain name is not required for local hosts.
+ * The local part of the fully qualified domain name is returned
+ * instead.
+ *
+ * \li #NI_NUMERICHOST
+ * Return the address in numeric form, as if calling inet_ntop(),
+ * instead of a host name.
+ *
+ * \li #NI_NAMEREQD
+ * A name is required. If the hostname cannot be found in the DNS
+ * and this flag is set, a non-zero error code is returned. If the
+ * hostname is not found and the flag is not set, the address is
+ * returned in numeric form.
+ *
+ * \li #NI_NUMERICSERV
+ * The service name is returned as a digit string representing the
+ * port number.
+ *
+ * \li #NI_DGRAM
+ * Specifies that the service being looked up is a datagram
+ * service, and causes getservbyport() to be called with a second
+ * argument of "udp" instead of its default of "tcp". This is
+ * required for the few ports (512-514) that have different
+ * services for UDP and TCP.
+ *
+ * \section getnameinfo_return Return Values
+ *
+ * getnameinfo() returns 0 on success or a non-zero error code if
+ * an error occurs.
+ *
+ * \section getname_see See Also
+ *
+ * RFC3493, getservbyport(),
+ * getnamebyaddr(). inet_ntop().
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/netaddr.h>
+#include <isc/print.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <dns/byaddr.h>
+#include <dns/client.h>
+#include <dns/fixedname.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+#include <dns/result.h>
+
+#include <irs/context.h>
+#include <irs/netdb.h>
+
+#define SUCCESS 0
+
+/*% afd structure definition */
+static struct afd {
+ int a_af;
+ size_t a_addrlen;
+ size_t a_socklen;
+} afdl [] = {
+ /*!
+ * First entry is linked last...
+ */
+ { AF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in) },
+ { AF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6) },
+ {0, 0, 0},
+};
+
+/*!
+ * The test against 0 is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
+ */
+#define ERR(code) \
+ do { result = (code); \
+ if (result != 0) goto cleanup; \
+ } while (0)
+
+int
+getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
+ IRS_GETNAMEINFO_BUFLEN_T hostlen, char *serv,
+ IRS_GETNAMEINFO_BUFLEN_T servlen, IRS_GETNAMEINFO_FLAGS_T flags)
+{
+ struct afd *afd;
+ struct servent *sp;
+ unsigned short port;
+#ifdef IRS_PLATFORM_HAVESALEN
+ size_t len;
+#endif
+ int family, i;
+ const void *addr;
+ char *p;
+#if 0
+ unsigned long v4a;
+ unsigned char pfx;
+#endif
+ char numserv[sizeof("65000")];
+ char numaddr[sizeof("abcd:abcd:abcd:abcd:abcd:abcd:255.255.255.255")
+ + 1 + sizeof("4294967295")];
+ const char *proto;
+ int result = SUCCESS;
+
+ if (sa == NULL)
+ ERR(EAI_FAIL);
+
+#ifdef IRS_PLATFORM_HAVESALEN
+ len = sa->sa_len;
+ if (len != salen)
+ ERR(EAI_FAIL);
+#endif
+
+ family = sa->sa_family;
+ for (i = 0; afdl[i].a_af; i++)
+ if (afdl[i].a_af == family) {
+ afd = &afdl[i];
+ goto found;
+ }
+ ERR(EAI_FAMILY);
+
+ found:
+ if (salen != afd->a_socklen)
+ ERR(EAI_FAIL);
+
+ switch (family) {
+ case AF_INET:
+ port = ((const struct sockaddr_in *)sa)->sin_port;
+ addr = &((const struct sockaddr_in *)sa)->sin_addr.s_addr;
+ break;
+
+ case AF_INET6:
+ port = ((const struct sockaddr_in6 *)sa)->sin6_port;
+ addr = ((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
+ break;
+
+ default:
+ port = 0;
+ addr = NULL;
+ INSIST(0);
+ }
+ proto = (flags & NI_DGRAM) ? "udp" : "tcp";
+
+ if (serv == NULL || servlen == 0U) {
+ /*
+ * Caller does not want service.
+ */
+ } else if ((flags & NI_NUMERICSERV) != 0 ||
+ (sp = getservbyport(port, proto)) == NULL) {
+ snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
+ if ((strlen(numserv) + 1) > servlen)
+ ERR(EAI_OVERFLOW);
+ strcpy(serv, numserv);
+ } else {
+ if ((strlen(sp->s_name) + 1) > servlen)
+ ERR(EAI_OVERFLOW);
+ strcpy(serv, sp->s_name);
+ }
+
+#if 0
+ switch (sa->sa_family) {
+ case AF_INET:
+ v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
+ if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+ flags |= NI_NUMERICHOST;
+ v4a >>= IN_CLASSA_NSHIFT;
+ if (v4a == 0 || v4a == IN_LOOPBACKNET)
+ flags |= NI_NUMERICHOST;
+ break;
+
+ case AF_INET6:
+ pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0];
+ if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+ flags |= NI_NUMERICHOST;
+ break;
+ }
+#endif
+
+ if (host == NULL || hostlen == 0U) {
+ /*
+ * do nothing in this case.
+ * in case you are wondering if "&&" is more correct than
+ * "||" here: RFC3493 says that host == NULL or hostlen == 0
+ * means that the caller does not want the result.
+ */
+ } else if ((flags & NI_NUMERICHOST) != 0) {
+ if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
+ == NULL)
+ ERR(EAI_SYSTEM);
+#if defined(IRS_HAVE_SIN6_SCOPE_ID)
+ if (afd->a_af == AF_INET6 &&
+ ((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
+ char *p = numaddr + strlen(numaddr);
+ const char *stringscope = NULL;
+#ifdef VENDOR_SPECIFIC
+ /*
+ * Vendors may want to add support for
+ * non-numeric scope identifier.
+ */
+ stringscope = foo;
+#endif
+ if (stringscope == NULL) {
+ snprintf(p, sizeof(numaddr) - (p - numaddr),
+ "%%%u",
+ ((const struct sockaddr_in6 *)sa)->sin6_scope_id);
+ } else {
+ snprintf(p, sizeof(numaddr) - (p - numaddr),
+ "%%%s", stringscope);
+ }
+ }
+#endif
+ if (strlen(numaddr) + 1 > hostlen)
+ ERR(EAI_OVERFLOW);
+ strcpy(host, numaddr);
+ } else {
+ isc_netaddr_t netaddr;
+ dns_fixedname_t ptrfname;
+ dns_name_t *ptrname;
+ irs_context_t *irsctx = NULL;
+ dns_client_t *client;
+ isc_boolean_t found = ISC_FALSE;
+ dns_namelist_t answerlist;
+ dns_rdataset_t *rdataset;
+ isc_region_t hostregion;
+ char hoststr[1024]; /* is this enough? */
+ isc_result_t iresult;
+
+ /* Get IRS context and the associated DNS client object */
+ iresult = irs_context_get(&irsctx);
+ if (iresult != ISC_R_SUCCESS)
+ ERR(EAI_FAIL);
+ client = irs_context_getdnsclient(irsctx);
+
+ /* Make query name */
+ isc_netaddr_fromsockaddr(&netaddr, (const isc_sockaddr_t *)sa);
+ dns_fixedname_init(&ptrfname);
+ ptrname = dns_fixedname_name(&ptrfname);
+ iresult = dns_byaddr_createptrname2(&netaddr, 0, ptrname);
+ if (iresult != ISC_R_SUCCESS)
+ ERR(EAI_FAIL);
+
+ /* Get the PTR RRset */
+ ISC_LIST_INIT(answerlist);
+ iresult = dns_client_resolve(client, ptrname,
+ dns_rdataclass_in,
+ dns_rdatatype_ptr,
+ DNS_CLIENTRESOPT_ALLOWRUN,
+ &answerlist);
+ switch (iresult) {
+ case ISC_R_SUCCESS:
+ /*
+ * a 'non-existent' error is not necessarily fatal for
+ * getnameinfo().
+ */
+ case DNS_R_NCACHENXDOMAIN:
+ case DNS_R_NCACHENXRRSET:
+ break;
+ case DNS_R_SIGINVALID:
+ case DNS_R_SIGEXPIRED:
+ case DNS_R_SIGFUTURE:
+ case DNS_R_KEYUNAUTHORIZED:
+ case DNS_R_MUSTBESECURE:
+ case DNS_R_COVERINGNSEC:
+ case DNS_R_NOTAUTHORITATIVE:
+ case DNS_R_NOVALIDKEY:
+ case DNS_R_NOVALIDDS:
+ case DNS_R_NOVALIDSIG:
+ ERR(EAI_INSECUREDATA);
+ default:
+ ERR(EAI_FAIL);
+ }
+
+ /* Parse the answer for the hostname */
+ for (ptrname = ISC_LIST_HEAD(answerlist); ptrname != NULL;
+ ptrname = ISC_LIST_NEXT(ptrname, link)) {
+ for (rdataset = ISC_LIST_HEAD(ptrname->list);
+ rdataset != NULL;
+ rdataset = ISC_LIST_NEXT(rdataset, link)) {
+ if (!dns_rdataset_isassociated(rdataset))
+ continue;
+ if (rdataset->type != dns_rdatatype_ptr)
+ continue;
+
+ for (iresult = dns_rdataset_first(rdataset);
+ iresult == ISC_R_SUCCESS;
+ iresult = dns_rdataset_next(rdataset)) {
+ dns_rdata_t rdata;
+ dns_rdata_ptr_t rdata_ptr;
+ isc_buffer_t b;
+
+ dns_rdata_init(&rdata);
+ dns_rdataset_current(rdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &rdata_ptr,
+ NULL);
+
+ isc_buffer_init(&b, hoststr,
+ sizeof(hoststr));
+ iresult =
+ dns_name_totext(&rdata_ptr.ptr,
+ ISC_TRUE, &b);
+ dns_rdata_freestruct(&rdata_ptr);
+ if (iresult == ISC_R_SUCCESS) {
+ /*
+ * We ignore the rest of the
+ * answer. After all,
+ * getnameinfo() can return
+ * at most one hostname.
+ */
+ found = ISC_TRUE;
+ isc_buffer_usedregion(
+ &b, &hostregion);
+ goto ptrfound;
+ }
+
+ }
+ }
+ }
+ ptrfound:
+ dns_client_freeresanswer(client, &answerlist);
+ if (found) {
+ if ((flags & NI_NOFQDN) != 0) {
+ p = strchr(hoststr, '.');
+ if (p)
+ *p = '\0';
+ }
+ if (hostregion.length + 1 > hostlen)
+ ERR(EAI_OVERFLOW);
+ snprintf(host, hostlen, "%.*s",
+ (int)hostregion.length,
+ (char *)hostregion.base);
+ } else {
+ if ((flags & NI_NAMEREQD) != 0)
+ ERR(EAI_NONAME);
+ if (inet_ntop(afd->a_af, addr, numaddr,
+ sizeof(numaddr)) == NULL)
+ ERR(EAI_SYSTEM);
+ if ((strlen(numaddr) + 1) > hostlen)
+ ERR(EAI_OVERFLOW);
+ strcpy(host, numaddr);
+ }
+ }
+ result = SUCCESS;
+
+ cleanup:
+ return (result);
+}
diff --git a/lib/irs/include/Makefile.in b/lib/irs/include/Makefile.in
new file mode 100644
index 000000000000..22a63ee98be5
--- /dev/null
+++ b/lib/irs/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = irs
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/irs/include/irs/Makefile.in b/lib/irs/include/irs/Makefile.in
new file mode 100644
index 000000000000..7d50995160ce
--- /dev/null
+++ b/lib/irs/include/irs/Makefile.in
@@ -0,0 +1,44 @@
+# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.3 2009-09-02 23:48:02 tbox Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+#
+# Only list headers that are to be installed and are not
+# machine generated. The latter are handled specially in the
+# install target below.
+#
+HEADERS = version.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/irs
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/irs ; \
+ done
+ ${INSTALL_DATA} netdb.h ${DESTDIR}${includedir}/irs
+ ${INSTALL_DATA} platform.h ${DESTDIR}${includedir}/irs
+
+distclean::
+ rm -f netdb.h platform.h
diff --git a/lib/irs/include/irs/context.h b/lib/irs/include/irs/context.h
new file mode 100644
index 000000000000..c49cfcfa4974
--- /dev/null
+++ b/lib/irs/include/irs/context.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: context.h,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+#ifndef IRS_CONTEXT_H
+#define IRS_CONTEXT_H 1
+
+/*! \file
+ *
+ * \brief
+ * The IRS context module provides an abstract interface to the DNS library
+ * with an application. An IRS context object initializes and holds various
+ * resources used in the DNS library.
+ */
+
+#include <dns/types.h>
+#include <irs/types.h>
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+irs_context_create(irs_context_t **contextp);
+/*%<
+ * Create an IRS context. It internally initializes the ISC and DNS libraries
+ * (if not yet), creates a DNS client object and initializes the client using
+ * the configuration files parsed via the 'resconf' and 'dnsconf' IRS modules.
+ * Some of the internally initialized objects can be used by the application
+ * via irs_context_getxxx() functions (see below).
+ *
+ * Requires:
+ *
+ *\li contextp != NULL && *contextp == NULL.
+ */
+
+isc_result_t
+irs_context_get(irs_context_t **contextp);
+/*%<
+ * Return an IRS context for the calling thread. If no IRS context is
+ * associated to the thread, this function creates a new one by calling
+ * irs_context_create(), and associates it with the thread as a thread specific
+ * data value. This function is provided for standard libraries that are
+ * expected to be thread-safe but do not accept an appropriate IRS context
+ * as a library parameter, e.g., getaddrinfo().
+ *
+ * Requires:
+ *
+ *\li contextp != NULL && *contextp == NULL.
+ */
+
+void
+irs_context_destroy(irs_context_t **contextp);
+/*%<
+ * Destroy an IRS context.
+ *
+ * Requires:
+ *
+ *\li '*contextp' is a valid IRS context.
+ *
+ * Ensures:
+ *\li '*contextp' == NULL.
+ */
+
+isc_mem_t *
+irs_context_getmctx(irs_context_t *context);
+/*%<
+ * Return the memory context held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+isc_appctx_t *
+irs_context_getappctx(irs_context_t *context);
+/*%<
+ * Return the application context held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+isc_taskmgr_t *
+irs_context_gettaskmgr(irs_context_t *context);
+/*%<
+ * Return the task manager held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+isc_timermgr_t *
+irs_context_gettimermgr(irs_context_t *context);
+/*%<
+ * Return the timer manager held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+isc_task_t *
+irs_context_gettask(irs_context_t *context);
+/*%<
+ * Return the task object held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+dns_client_t *
+irs_context_getdnsclient(irs_context_t *context);
+/*%<
+ * Return the DNS client object held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+irs_resconf_t *
+irs_context_getresconf(irs_context_t *context);
+/*%<
+ * Return the resolver configuration object held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+irs_dnsconf_t *
+irs_context_getdnsconf(irs_context_t *context);
+/*%<
+ * Return the advanced DNS configuration object held in the context.
+ *
+ * Requires:
+ *
+ *\li 'context' is a valid IRS context.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* IRS_CONTEXT_H */
diff --git a/lib/irs/include/irs/dnsconf.h b/lib/irs/include/irs/dnsconf.h
new file mode 100644
index 000000000000..0041c1616cad
--- /dev/null
+++ b/lib/irs/include/irs/dnsconf.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: dnsconf.h,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+#ifndef IRS_DNSCONF_H
+#define IRS_DNSCONF_H 1
+
+/*! \file
+ *
+ * \brief
+ * The IRS dnsconf module parses an "advanced" configuration file related to
+ * the DNS library, such as trusted keys for DNSSEC validation, and creates
+ * the corresponding configuration objects for the DNS library modules.
+ *
+ * Notes:
+ * This module is very experimental and the configuration syntax or library
+ * interfaces may change in future versions. Currently, only the
+ * 'trusted-keys' statement is supported, whose syntax is the same as the
+ * same name of statement for named.conf.
+ */
+
+#include <irs/types.h>
+
+/*%
+ * A compound structure storing DNS key information mainly for DNSSEC
+ * validation. A dns_key_t object will be created using the 'keyname' and
+ * 'keydatabuf' members with the dst_key_fromdns() function.
+ */
+typedef struct irs_dnsconf_dnskey {
+ dns_name_t *keyname;
+ isc_buffer_t *keydatabuf;
+ ISC_LINK(struct irs_dnsconf_dnskey) link;
+} irs_dnsconf_dnskey_t;
+
+typedef ISC_LIST(irs_dnsconf_dnskey_t) irs_dnsconf_dnskeylist_t;
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+irs_dnsconf_load(isc_mem_t *mctx, const char *filename, irs_dnsconf_t **confp);
+/*%<
+ * Load the "advanced" DNS configuration file 'filename' in the "dns.conf"
+ * format, and create a new irs_dnsconf_t object from the configuration.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'filename' != NULL
+ *
+ *\li 'confp' != NULL && '*confp' == NULL
+ */
+
+void
+irs_dnsconf_destroy(irs_dnsconf_t **confp);
+/*%<
+ * Destroy the dnsconf object.
+ *
+ * Requires:
+ *
+ *\li '*confp' is a valid dnsconf object.
+ *
+ * Ensures:
+ *
+ *\li *confp == NULL
+ */
+
+irs_dnsconf_dnskeylist_t *
+irs_dnsconf_gettrustedkeys(irs_dnsconf_t *conf);
+/*%<
+ * Return a list of key information stored in 'conf'.
+ *
+ * Requires:
+ *
+ *\li 'conf' is a valid dnsconf object.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* IRS_DNSCONF_H */
diff --git a/lib/irs/include/irs/netdb.h.in b/lib/irs/include/irs/netdb.h.in
new file mode 100644
index 000000000000..9dda4137535d
--- /dev/null
+++ b/lib/irs/include/irs/netdb.h.in
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: netdb.h.in,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#ifndef IRS_NETDB_H
+#define IRS_NETDB_H 1
+
+#include <stddef.h> /* Required on FreeBSD (and others?) for size_t. */
+#include <netdb.h> /* Contractual provision. */
+
+/*
+ * Define if <netdb.h> does not declare struct addrinfo.
+ */
+@ISC_IRS_NEEDADDRINFO@
+
+#ifdef ISC_IRS_NEEDADDRINFO
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* Length of ai_addr */
+ char *ai_canonname; /* Canonical name for hostname */
+ struct sockaddr *ai_addr; /* Binary address */
+ struct addrinfo *ai_next; /* Next structure in linked list */
+};
+#endif
+
+/*
+ * Undefine all #defines we are interested in as <netdb.h> may or may not have
+ * defined them.
+ */
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in extern int h_errno).
+ */
+
+#undef NETDB_INTERNAL
+#undef NETDB_SUCCESS
+#undef HOST_NOT_FOUND
+#undef TRY_AGAIN
+#undef NO_RECOVERY
+#undef NO_DATA
+#undef NO_ADDRESS
+
+#define NETDB_INTERNAL -1 /* see errno */
+#define NETDB_SUCCESS 0 /* no problem */
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#define NO_ADDRESS NO_DATA /* no address, look for MX record */
+
+/*
+ * Error return codes from getaddrinfo(). EAI_INSECUREDATA is our own extension
+ * and it's very unlikely to be already defined, but undef it just in case; it
+ * at least doesn't do any harm.
+ */
+
+#undef EAI_ADDRFAMILY
+#undef EAI_AGAIN
+#undef EAI_BADFLAGS
+#undef EAI_FAIL
+#undef EAI_FAMILY
+#undef EAI_MEMORY
+#undef EAI_NODATA
+#undef EAI_NONAME
+#undef EAI_SERVICE
+#undef EAI_SOCKTYPE
+#undef EAI_SYSTEM
+#undef EAI_BADHINTS
+#undef EAI_PROTOCOL
+#undef EAI_OVERFLOW
+#undef EAI_INSECUREDATA
+#undef EAI_MAX
+
+#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with hostname */
+#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+#define EAI_BADHINTS 12
+#define EAI_PROTOCOL 13
+#define EAI_OVERFLOW 14
+#define EAI_INSECUREDATA 15
+#define EAI_MAX 16
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#undef AI_PASSIVE
+#undef AI_CANONNAME
+#undef AI_NUMERICHOST
+
+#define AI_PASSIVE 0x00000001
+#define AI_CANONNAME 0x00000002
+#define AI_NUMERICHOST 0x00000004
+
+/*
+ * Flag values for getipnodebyname()
+ */
+#undef AI_V4MAPPED
+#undef AI_ALL
+#undef AI_ADDRCONFIG
+#undef AI_DEFAULT
+
+#define AI_V4MAPPED 0x00000008
+#define AI_ALL 0x00000010
+#define AI_ADDRCONFIG 0x00000020
+#define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG)
+
+/*
+ * Constants for lwres_getnameinfo()
+ */
+#undef NI_MAXHOST
+#undef NI_MAXSERV
+
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+
+/*
+ * Flag values for lwres_getnameinfo()
+ */
+#undef NI_NOFQDN
+#undef NI_NUMERICHOST
+#undef NI_NAMEREQD
+#undef NI_NUMERICSERV
+#undef NI_DGRAM
+#undef NI_NUMERICSCOPE
+
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+
+/*
+ * Tell Emacs to use C mode on this file.
+ * Local variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* IRS_NETDB_H */
diff --git a/lib/irs/include/irs/platform.h.in b/lib/irs/include/irs/platform.h.in
new file mode 100644
index 000000000000..f61f67170016
--- /dev/null
+++ b/lib/irs/include/irs/platform.h.in
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: platform.h.in,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#ifndef IRS_PLATFORM_H
+#define IRS_PLATFORM_H 1
+
+/*****
+ ***** Platform-dependent defines.
+ *****/
+
+#ifndef IRS_PLATFORM_USEDECLSPEC
+#define LIBIRS_EXTERNAL_DATA
+#else
+#ifdef LIBIRS_EXPORTS
+#define LIBIRS_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBIRS_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#endif
+
+/*
+ * Tell Emacs to use C mode on this file.
+ * Local Variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* IRS_PLATFORM_H */
diff --git a/lib/irs/include/irs/resconf.h b/lib/irs/include/irs/resconf.h
new file mode 100644
index 000000000000..8249c7b0de4f
--- /dev/null
+++ b/lib/irs/include/irs/resconf.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: resconf.h,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+#ifndef IRS_RESCONF_H
+#define IRS_RESCONF_H 1
+
+/*! \file
+ *
+ * \brief
+ * The IRS resconf module parses the legacy "/etc/resolv.conf" file and
+ * creates the corresponding configuration objects for the DNS library
+ * modules.
+ */
+
+#include <irs/types.h>
+
+/*%
+ * A DNS search list specified in the 'domain' or 'search' statements
+ * in the "resolv.conf" file.
+ */
+typedef struct irs_resconf_search {
+ char *domain;
+ ISC_LINK(struct irs_resconf_search) link;
+} irs_resconf_search_t;
+
+typedef ISC_LIST(irs_resconf_search_t) irs_resconf_searchlist_t;
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp);
+/*%<
+ * Load the resolver configuration file 'filename' in the "resolv.conf" format,
+ * and create a new irs_resconf_t object from the configuration.
+ *
+ * Notes:
+ *
+ *\li Currently, only the following options are supported:
+ * nameserver, domain, search, sortlist, ndots, and options.
+ * In addition, 'sortlist' is not actually effective; it's parsed, but
+ * the application cannot use the configuration.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'filename' != NULL
+ *
+ *\li 'confp' != NULL && '*confp' == NULL
+ */
+
+void
+irs_resconf_destroy(irs_resconf_t **confp);
+/*%<
+ * Destroy the resconf object.
+ *
+ * Requires:
+ *
+ *\li '*confp' is a valid resconf object.
+ *
+ * Ensures:
+ *
+ *\li *confp == NULL
+ */
+
+isc_sockaddrlist_t *
+irs_resconf_getnameservers(irs_resconf_t *conf);
+/*%<
+ * Return a list of name server addresses stored in 'conf'.
+ *
+ * Requires:
+ *
+ *\li 'conf' is a valid resconf object.
+ */
+
+irs_resconf_searchlist_t *
+irs_resconf_getsearchlist(irs_resconf_t *conf);
+/*%<
+ * Return the search list stored in 'conf'.
+ *
+ * Requires:
+ *
+ *\li 'conf' is a valid resconf object.
+ */
+
+unsigned int
+irs_resconf_getndots(irs_resconf_t *conf);
+/*%<
+ * Return the 'ndots' value stored in 'conf'.
+ *
+ * Requires:
+ *
+ *\li 'conf' is a valid resconf object.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* IRS_RESCONF_H */
diff --git a/lib/irs/include/irs/types.h b/lib/irs/include/irs/types.h
new file mode 100644
index 000000000000..4b8a80470516
--- /dev/null
+++ b/lib/irs/include/irs/types.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN 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.3 2009-09-02 23:48:02 tbox Exp $ */
+
+#ifndef IRS_TYPES_H
+#define IRS_TYPES_H 1
+
+/* Core Types. Alphabetized by defined type. */
+
+/*%< per-thread IRS context */
+typedef struct irs_context irs_context_t;
+/*%< resolv.conf configuration information */
+typedef struct irs_resconf irs_resconf_t;
+/*%< advanced DNS-related configuration information */
+typedef struct irs_dnsconf irs_dnsconf_t;
+
+#endif /* IRS_TYPES_H */
diff --git a/lib/irs/include/irs/version.h b/lib/irs/include/irs/version.h
new file mode 100644
index 000000000000..f43aa1453df1
--- /dev/null
+++ b/lib/irs/include/irs/version.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: version.h,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include <irs/platform.h>
+
+LIBIRS_EXTERNAL_DATA extern const char irs_version[];
+
+LIBIRS_EXTERNAL_DATA extern const unsigned int irs_libinterface;
+LIBIRS_EXTERNAL_DATA extern const unsigned int irs_librevision;
+LIBIRS_EXTERNAL_DATA extern const unsigned int irs_libage;
diff --git a/lib/irs/resconf.c b/lib/irs/resconf.c
new file mode 100644
index 000000000000..af1413b3454d
--- /dev/null
+++ b/lib/irs/resconf.c
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: resconf.c,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+/*! \file resconf.c */
+
+/**
+ * Module for parsing resolv.conf files (largely derived from lwconfig.c).
+ *
+ * irs_resconf_load() opens the file filename and parses it to initialize
+ * the configuration structure.
+ *
+ * \section lwconfig_return Return Values
+ *
+ * irs_resconf_load() returns #IRS_R_SUCCESS if it successfully read and
+ * parsed filename. It returns a non-0 error code if filename could not be
+ * opened or contained incorrect resolver statements.
+ *
+ * \section lwconfig_see See Also
+ *
+ * stdio(3), \link resolver resolver \endlink
+ *
+ * \section files Files
+ *
+ * /etc/resolv.conf
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/netaddr.h>
+#include <isc/sockaddr.h>
+#include <isc/util.h>
+
+#include <irs/resconf.h>
+
+#define IRS_RESCONF_MAGIC ISC_MAGIC('R', 'E', 'S', 'c')
+#define IRS_RESCONF_VALID(c) ISC_MAGIC_VALID(c, IRS_RESCONF_MAGIC)
+
+/*!
+ * protocol constants
+ */
+
+#if ! defined(NS_INADDRSZ)
+#define NS_INADDRSZ 4
+#endif
+
+#if ! defined(NS_IN6ADDRSZ)
+#define NS_IN6ADDRSZ 16
+#endif
+
+/*!
+ * resolv.conf parameters
+ */
+
+#define RESCONFMAXNAMESERVERS 3 /*%< max 3 "nameserver" entries */
+#define RESCONFMAXSEARCH 8 /*%< max 8 domains in "search" entry */
+#define RESCONFMAXLINELEN 256 /*%< max size of a line */
+#define RESCONFMAXSORTLIST 10 /*%< max 10 */
+
+/*!
+ * configuration data structure
+ */
+
+struct irs_resconf {
+ /*
+ * The configuration data is a thread-specific object, and does not
+ * need to be locked.
+ */
+ unsigned int magic;
+ isc_mem_t *mctx;
+
+ isc_sockaddrlist_t nameservers;
+ unsigned int numns; /*%< number of configured servers */
+
+ char *domainname;
+ char *search[RESCONFMAXSEARCH];
+ isc_uint8_t searchnxt; /*%< index for next free slot */
+
+ irs_resconf_searchlist_t searchlist;
+
+ struct {
+ isc_netaddr_t addr;
+ /*% mask has a non-zero 'family' if set */
+ isc_netaddr_t mask;
+ } sortlist[RESCONFMAXSORTLIST];
+ isc_uint8_t sortlistnxt;
+
+ /*%< non-zero if 'options debug' set */
+ isc_uint8_t resdebug;
+ /*%< set to n in 'options ndots:n' */
+ isc_uint8_t ndots;
+};
+
+static isc_result_t
+resconf_parsenameserver(irs_resconf_t *conf, FILE *fp);
+static isc_result_t
+resconf_parsedomain(irs_resconf_t *conf, FILE *fp);
+static isc_result_t
+resconf_parsesearch(irs_resconf_t *conf, FILE *fp);
+static isc_result_t
+resconf_parsesortlist(irs_resconf_t *conf, FILE *fp);
+static isc_result_t
+resconf_parseoption(irs_resconf_t *ctx, FILE *fp);
+
+/*!
+ * Eat characters from FP until EOL or EOF. Returns EOF or '\n'
+ */
+static int
+eatline(FILE *fp) {
+ int ch;
+
+ ch = fgetc(fp);
+ while (ch != '\n' && ch != EOF)
+ ch = fgetc(fp);
+
+ return (ch);
+}
+
+/*!
+ * Eats white space up to next newline or non-whitespace character (of
+ * EOF). Returns the last character read. Comments are considered white
+ * space.
+ */
+static int
+eatwhite(FILE *fp) {
+ int ch;
+
+ ch = fgetc(fp);
+ while (ch != '\n' && ch != EOF && isspace((unsigned char)ch))
+ ch = fgetc(fp);
+
+ if (ch == ';' || ch == '#')
+ ch = eatline(fp);
+
+ return (ch);
+}
+
+/*!
+ * Skip over any leading whitespace and then read in the next sequence of
+ * non-whitespace characters. In this context newline is not considered
+ * whitespace. Returns EOF on end-of-file, or the character
+ * that caused the reading to stop.
+ */
+static int
+getword(FILE *fp, char *buffer, size_t size) {
+ int ch;
+ char *p = buffer;
+
+ REQUIRE(buffer != NULL);
+ REQUIRE(size > 0U);
+
+ *p = '\0';
+
+ ch = eatwhite(fp);
+
+ if (ch == EOF)
+ return (EOF);
+
+ do {
+ *p = '\0';
+
+ if (ch == EOF || isspace((unsigned char)ch))
+ break;
+ else if ((size_t) (p - buffer) == size - 1)
+ return (EOF); /* Not enough space. */
+
+ *p++ = (char)ch;
+ ch = fgetc(fp);
+ } while (1);
+
+ return (ch);
+}
+
+static isc_result_t
+add_server(isc_mem_t *mctx, const char *address_str,
+ isc_sockaddrlist_t *nameservers)
+{
+ int error;
+ isc_sockaddr_t *address = NULL;
+ struct addrinfo hints, *res;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ res = NULL;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_NUMERICHOST;
+ error = getaddrinfo(address_str, "53", &hints, &res);
+ if (error != 0)
+ return (ISC_R_BADADDRESSFORM);
+
+ /* XXX: special case: treat all-0 IPv4 address as loopback */
+ if (res->ai_family == AF_INET) {
+ struct in_addr *v4;
+ unsigned char zeroaddress[] = {0, 0, 0, 0};
+ unsigned char loopaddress[] = {127, 0, 0, 1};
+
+ v4 = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
+ if (memcmp(v4, zeroaddress, 4) == 0)
+ memcpy(v4, loopaddress, 4);
+ }
+
+ address = isc_mem_get(mctx, sizeof(*address));
+ if (address == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ if (res->ai_addrlen > sizeof(address->type)) {
+ isc_mem_put(mctx, address, sizeof(*address));
+ result = ISC_R_RANGE;
+ goto cleanup;
+ }
+ address->length = res->ai_addrlen;
+ memcpy(&address->type.sa, res->ai_addr, res->ai_addrlen);
+ ISC_LINK_INIT(address, link);
+ ISC_LIST_APPEND(*nameservers, address, link);
+
+ cleanup:
+ freeaddrinfo(res);
+
+ return (result);
+}
+
+static isc_result_t
+create_addr(const char *buffer, isc_netaddr_t *addr, int convert_zero) {
+ struct in_addr v4;
+ struct in6_addr v6;
+
+ if (inet_aton(buffer, &v4) == 1) {
+ if (convert_zero) {
+ unsigned char zeroaddress[] = {0, 0, 0, 0};
+ unsigned char loopaddress[] = {127, 0, 0, 1};
+ if (memcmp(&v4, zeroaddress, 4) == 0)
+ memcpy(&v4, loopaddress, 4);
+ }
+ addr->family = AF_INET;
+ memcpy(&addr->type.in, &v4, NS_INADDRSZ);
+ addr->zone = 0;
+ } else if (inet_pton(AF_INET6, buffer, &v6) == 1) {
+ addr->family = AF_INET6;
+ memcpy(&addr->type.in6, &v6, NS_IN6ADDRSZ);
+ addr->zone = 0;
+ } else
+ return (ISC_R_BADADDRESSFORM); /* Unrecognised format. */
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+resconf_parsenameserver(irs_resconf_t *conf, FILE *fp) {
+ char word[RESCONFMAXLINELEN];
+ int cp;
+ isc_result_t result;
+
+ if (conf->numns == RESCONFMAXNAMESERVERS)
+ return (ISC_R_SUCCESS);
+
+ cp = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0U)
+ return (ISC_R_UNEXPECTEDEND); /* Nothing on line. */
+ else if (cp == ' ' || cp == '\t')
+ cp = eatwhite(fp);
+
+ if (cp != EOF && cp != '\n')
+ return (ISC_R_UNEXPECTEDTOKEN); /* Extra junk on line. */
+
+ result = add_server(conf->mctx, word, &conf->nameservers);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ conf->numns++;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+resconf_parsedomain(irs_resconf_t *conf, FILE *fp) {
+ char word[RESCONFMAXLINELEN];
+ int res, i;
+
+ res = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0U)
+ return (ISC_R_UNEXPECTEDEND); /* Nothing else on line. */
+ else if (res == ' ' || res == '\t')
+ res = eatwhite(fp);
+
+ if (res != EOF && res != '\n')
+ return (ISC_R_UNEXPECTEDTOKEN); /* Extra junk on line. */
+
+ if (conf->domainname != NULL)
+ isc_mem_free(conf->mctx, conf->domainname);
+
+ /*
+ * Search and domain are mutually exclusive.
+ */
+ for (i = 0; i < RESCONFMAXSEARCH; i++) {
+ if (conf->search[i] != NULL) {
+ isc_mem_free(conf->mctx, conf->search[i]);
+ conf->search[i] = NULL;
+ }
+ }
+ conf->searchnxt = 0;
+
+ conf->domainname = isc_mem_strdup(conf->mctx, word);
+ if (conf->domainname == NULL)
+ return (ISC_R_NOMEMORY);
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+resconf_parsesearch(irs_resconf_t *conf, FILE *fp) {
+ int idx, delim;
+ char word[RESCONFMAXLINELEN];
+
+ if (conf->domainname != NULL) {
+ /*
+ * Search and domain are mutually exclusive.
+ */
+ isc_mem_free(conf->mctx, conf->domainname);
+ conf->domainname = NULL;
+ }
+
+ /*
+ * Remove any previous search definitions.
+ */
+ for (idx = 0; idx < RESCONFMAXSEARCH; idx++) {
+ if (conf->search[idx] != NULL) {
+ isc_mem_free(conf->mctx, conf->search[idx]);
+ conf->search[idx] = NULL;
+ }
+ }
+ conf->searchnxt = 0;
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0U)
+ return (ISC_R_UNEXPECTEDEND); /* Nothing else on line. */
+
+ idx = 0;
+ while (strlen(word) > 0U) {
+ if (conf->searchnxt == RESCONFMAXSEARCH)
+ goto ignore; /* Too many domains. */
+
+ conf->search[idx] = isc_mem_strdup(conf->mctx, word);
+ if (conf->search[idx] == NULL)
+ return (ISC_R_NOMEMORY);
+ idx++;
+ conf->searchnxt++;
+
+ ignore:
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+resconf_parsesortlist(irs_resconf_t *conf, FILE *fp) {
+ int delim, res, idx;
+ char word[RESCONFMAXLINELEN];
+ char *p;
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0U)
+ return (ISC_R_UNEXPECTEDEND); /* Empty line after keyword. */
+
+ while (strlen(word) > 0U) {
+ if (conf->sortlistnxt == RESCONFMAXSORTLIST)
+ return (ISC_R_QUOTA); /* Too many values. */
+
+ p = strchr(word, '/');
+ if (p != NULL)
+ *p++ = '\0';
+
+ idx = conf->sortlistnxt;
+ res = create_addr(word, &conf->sortlist[idx].addr, 1);
+ if (res != ISC_R_SUCCESS)
+ return (res);
+
+ if (p != NULL) {
+ res = create_addr(p, &conf->sortlist[idx].mask, 0);
+ if (res != ISC_R_SUCCESS)
+ return (res);
+ } else {
+ /*
+ * Make up a mask. (XXX: is this correct?)
+ */
+ conf->sortlist[idx].mask = conf->sortlist[idx].addr;
+ memset(&conf->sortlist[idx].mask.type, 0xff,
+ sizeof(conf->sortlist[idx].mask.type));
+ }
+
+ conf->sortlistnxt++;
+
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+resconf_parseoption(irs_resconf_t *conf, FILE *fp) {
+ int delim;
+ long ndots;
+ char *p;
+ char word[RESCONFMAXLINELEN];
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0U)
+ return (ISC_R_UNEXPECTEDEND); /* Empty line after keyword. */
+
+ while (strlen(word) > 0U) {
+ if (strcmp("debug", word) == 0) {
+ conf->resdebug = 1;
+ } else if (strncmp("ndots:", word, 6) == 0) {
+ ndots = strtol(word + 6, &p, 10);
+ if (*p != '\0') /* Bad string. */
+ return (ISC_R_UNEXPECTEDTOKEN);
+ if (ndots < 0 || ndots > 0xff) /* Out of range. */
+ return (ISC_R_RANGE);
+ conf->ndots = (isc_uint8_t)ndots;
+ }
+
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+add_search(irs_resconf_t *conf, char *domain) {
+ irs_resconf_search_t *entry;
+
+ entry = isc_mem_get(conf->mctx, sizeof(*entry));
+ if (entry == NULL)
+ return (ISC_R_NOMEMORY);
+
+ entry->domain = domain;
+ ISC_LINK_INIT(entry, link);
+ ISC_LIST_APPEND(conf->searchlist, entry, link);
+
+ return (ISC_R_SUCCESS);
+}
+
+/*% parses a file and fills in the data structure. */
+isc_result_t
+irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp)
+{
+ FILE *fp = NULL;
+ char word[256];
+ isc_result_t rval, ret;
+ irs_resconf_t *conf;
+ int i, stopchar;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(filename != NULL);
+ REQUIRE(strlen(filename) > 0U);
+ REQUIRE(confp != NULL && *confp == NULL);
+
+ conf = isc_mem_get(mctx, sizeof(*conf));
+ if (conf == NULL)
+ return (ISC_R_NOMEMORY);
+
+ conf->mctx = mctx;
+ ISC_LIST_INIT(conf->nameservers);
+ conf->numns = 0;
+ conf->domainname = NULL;
+ conf->searchnxt = 0;
+ conf->resdebug = 0;
+ conf->ndots = 1;
+ for (i = 0; i < RESCONFMAXSEARCH; i++)
+ conf->search[i] = NULL;
+
+ errno = 0;
+ if ((fp = fopen(filename, "r")) == NULL) {
+ isc_mem_put(mctx, conf, sizeof(*conf));
+ return (ISC_R_INVALIDFILE);
+ }
+
+ ret = ISC_R_SUCCESS;
+ do {
+ stopchar = getword(fp, word, sizeof(word));
+ if (stopchar == EOF) {
+ rval = ISC_R_SUCCESS;
+ break;
+ }
+
+ if (strlen(word) == 0U)
+ rval = ISC_R_SUCCESS;
+ else if (strcmp(word, "nameserver") == 0)
+ rval = resconf_parsenameserver(conf, fp);
+ else if (strcmp(word, "domain") == 0)
+ rval = resconf_parsedomain(conf, fp);
+ else if (strcmp(word, "search") == 0)
+ rval = resconf_parsesearch(conf, fp);
+ else if (strcmp(word, "sortlist") == 0)
+ rval = resconf_parsesortlist(conf, fp);
+ else if (strcmp(word, "options") == 0)
+ rval = resconf_parseoption(conf, fp);
+ else {
+ /* unrecognised word. Ignore entire line */
+ rval = ISC_R_SUCCESS;
+ stopchar = eatline(fp);
+ if (stopchar == EOF) {
+ break;
+ }
+ }
+ if (ret == ISC_R_SUCCESS && rval != ISC_R_SUCCESS)
+ ret = rval;
+ } while (1);
+
+ fclose(fp);
+
+ /* If we don't find a nameserver fall back to localhost */
+ if (conf->numns == 0) {
+ INSIST(ISC_LIST_EMPTY(conf->nameservers));
+
+ /* XXX: should we catch errors? */
+ (void)add_server(conf->mctx, "127.0.0.1", &conf->nameservers);
+ (void)add_server(conf->mctx, "::1", &conf->nameservers);
+ }
+
+ /*
+ * Construct unified search list from domain or configured
+ * search list
+ */
+ ISC_LIST_INIT(conf->searchlist);
+ if (conf->domainname != NULL) {
+ ret = add_search(conf, conf->domainname);
+ } else if (conf->searchnxt > 0) {
+ for (i = 0; i < conf->searchnxt; i++) {
+ ret = add_search(conf, conf->search[i]);
+ if (ret != ISC_R_SUCCESS)
+ break;
+ }
+ }
+
+ conf->magic = IRS_RESCONF_MAGIC;
+
+ if (ret != ISC_R_SUCCESS)
+ irs_resconf_destroy(&conf);
+ else
+ *confp = conf;
+
+ return (ret);
+}
+
+void
+irs_resconf_destroy(irs_resconf_t **confp) {
+ irs_resconf_t *conf;
+ isc_sockaddr_t *address;
+ irs_resconf_search_t *searchentry;
+ int i;
+
+ REQUIRE(confp != NULL);
+ conf = *confp;
+ REQUIRE(IRS_RESCONF_VALID(conf));
+
+ while ((searchentry = ISC_LIST_HEAD(conf->searchlist)) != NULL) {
+ ISC_LIST_UNLINK(conf->searchlist, searchentry, link);
+ isc_mem_put(conf->mctx, searchentry, sizeof(*searchentry));
+ }
+
+ while ((address = ISC_LIST_HEAD(conf->nameservers)) != NULL) {
+ ISC_LIST_UNLINK(conf->nameservers, address, link);
+ isc_mem_put(conf->mctx, address, sizeof(*address));
+ }
+
+ if (conf->domainname != NULL)
+ isc_mem_free(conf->mctx, conf->domainname);
+
+ for (i = 0; i < RESCONFMAXSEARCH; i++) {
+ if (conf->search[i] != NULL)
+ isc_mem_free(conf->mctx, conf->search[i]);
+ }
+
+ isc_mem_put(conf->mctx, conf, sizeof(*conf));
+
+ *confp = NULL;
+}
+
+isc_sockaddrlist_t *
+irs_resconf_getnameservers(irs_resconf_t *conf) {
+ REQUIRE(IRS_RESCONF_VALID(conf));
+
+ return (&conf->nameservers);
+}
+
+irs_resconf_searchlist_t *
+irs_resconf_getsearchlist(irs_resconf_t *conf) {
+ REQUIRE(IRS_RESCONF_VALID(conf));
+
+ return (&conf->searchlist);
+}
+
+unsigned int
+irs_resconf_getndots(irs_resconf_t *conf) {
+ REQUIRE(IRS_RESCONF_VALID(conf));
+
+ return ((unsigned int)conf->ndots);
+}
diff --git a/lib/irs/version.c b/lib/irs/version.c
new file mode 100644
index 000000000000..b27de99a4ee0
--- /dev/null
+++ b/lib/irs/version.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: version.c,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include <irs/version.h>
+
+const char irs_version[] = VERSION;
+
+const unsigned int irs_libinterface = LIBINTERFACE;
+const unsigned int irs_librevision = LIBREVISION;
+const unsigned int irs_libage = LIBAGE;
diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in
index d831fcff3fd5..d92c0b854484 100644
--- a/lib/isc/Makefile.in
+++ b/lib/isc/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.96.50.6 2010-06-09 01:52:54 marka Exp $
+# $Id: Makefile.in,v 1.109 2010-06-09 01:43:09 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -27,8 +27,8 @@ CINCLUDES = -I${srcdir}/unix/include \
-I${srcdir}/@ISC_THREAD_DIR@/include \
-I${srcdir}/@ISC_ARCH_DIR@/include \
-I./include \
- -I${srcdir}/include
-CDEFINES =
+ -I${srcdir}/include @ISC_OPENSSL_INC@
+CDEFINES = @USE_OPENSSL@
CWARNINGS =
# Alphabetically
@@ -39,7 +39,6 @@ UNIXOBJS = @ISC_ISCIPV6_O@ \
unix/os.@O@ unix/resource.@O@ unix/socket.@O@ unix/stdio.@O@ \
unix/stdtime.@O@ unix/strerror.@O@ unix/syslog.@O@ unix/time.@O@
-
NLSOBJS = nls/msgcat.@O@
THREADOPTOBJS = @ISC_THREAD_DIR@/condition.@O@ @ISC_THREAD_DIR@/mutex.@O@
@@ -52,8 +51,9 @@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \
# Alphabetically
OBJS = @ISC_EXTRA_OBJS@ \
- assertions.@O@ base32.@O@ base64.@O@ bitstring.@O@ buffer.@O@ \
- bufferlist.@O@ commandline.@O@ error.@O@ event.@O@ \
+ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
+ bitstring.@O@ buffer.@O@ bufferlist.@O@ commandline.@O@ \
+ error.@O@ event.@O@ \
hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \
lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
@@ -64,11 +64,12 @@ OBJS = @ISC_EXTRA_OBJS@ \
serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \
string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \
timer.@O@ version.@O@ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
+SYMTBLOBJS = backtrace-emptytbl.@O@
# Alphabetically
SRCS = @ISC_EXTRA_SRCS@ \
- assertions.c base32.c base64.c bitstring.c buffer.c \
- bufferlist.c commandline.c error.c event.c \
+ assertions.c backtrace.c base32.c base64.c bitstring.c \
+ buffer.c bufferlist.c commandline.c error.c event.c \
heap.c hex.c hmacmd5.c hmacsha.c \
httpd.c inet_aton.c iterated_hash.c \
lex.c lfsr.c lib.c log.c \
@@ -77,7 +78,7 @@ SRCS = @ISC_EXTRA_SRCS@ \
parseint.c portset.c quota.c radix.c random.c \
ratelimiter.c refcount.c region.c result.c rwlock.c \
serial.c sha1.c sha2.c sockaddr.c stats.c string.c strtoul.c \
- symtab.c task.c taskpool.c timer.c version.c
+ symtab.c symtbl-empty.c task.c taskpool.c timer.c version.c
LIBS = @LIBS@
@@ -98,17 +99,27 @@ version.@O@: version.c
-DLIBAGE=${LIBAGE} \
-c ${srcdir}/version.c
-libisc.@SA@: ${OBJS}
+libisc.@SA@: ${OBJS} ${SYMTBLOBJS}
+ ${AR} ${ARFLAGS} $@ ${OBJS} ${SYMTBLOBJS}
+ ${RANLIB} $@
+
+libisc-nosymtbl.@SA@: ${OBJS}
${AR} ${ARFLAGS} $@ ${OBJS}
${RANLIB} $@
-libisc.la: ${OBJS}
+libisc.la: ${OBJS} ${SYMTBLOBJS}
${LIBTOOL_MODE_LINK} \
${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc.la -rpath ${libdir} \
-version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} ${SYMTBLOBJS} ${LIBS}
+
+libisc-nosymtbl.la: ${OBJS}
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc-nosymtbl.la -rpath ${libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
${OBJS} ${LIBS}
-timestamp: libisc.@A@
+timestamp: libisc.@A@ libisc-nosymtbl.@A@
touch timestamp
installdirs:
@@ -118,4 +129,5 @@ install:: timestamp installdirs
${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisc.@A@ ${DESTDIR}${libdir}
clean distclean::
- rm -f libisc.@A@ libisc.la timestamp
+ rm -f libisc.@A@ libisc-nosymtbl.@A@ libisc.la \
+ libisc-nosymtbl.la timestamp
diff --git a/lib/isc/alpha/include/isc/atomic.h b/lib/isc/alpha/include/isc/atomic.h
index bb4f1ad64277..012c955c3f3e 100644
--- a/lib/isc/alpha/include/isc/atomic.h
+++ b/lib/isc/alpha/include/isc/atomic.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: atomic.h,v 1.5.332.2 2009-04-08 06:47:32 tbox Exp $ */
+/* $Id: atomic.h,v 1.7 2009-04-08 06:48:23 tbox Exp $ */
/*
* This code was written based on FreeBSD's kernel source whose copyright
diff --git a/lib/isc/api b/lib/isc/api
index e1f7b71eb113..b91b130d9f26 100644
--- a/lib/isc/api
+++ b/lib/isc/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 54
-LIBREVISION = 1
-LIBAGE = 4
+LIBINTERFACE = 81
+LIBREVISION = 2
+LIBAGE = 0
diff --git a/lib/isc/app_api.c b/lib/isc/app_api.c
new file mode 100644
index 000000000000..b2a2f149de7d
--- /dev/null
+++ b/lib/isc/app_api.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: app_api.c,v 1.5 2009-09-02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <isc/app.h>
+#include <isc/magic.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/util.h>
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_appctxcreatefunc_t appctx_createfunc = NULL;
+
+#define ISCAPI_APPMETHODS_VALID(m) ISC_MAGIC_VALID(m, ISCAPI_APPMETHODS_MAGIC)
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_app_register(isc_appctxcreatefunc_t createfunc) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+ if (appctx_createfunc == NULL)
+ appctx_createfunc = createfunc;
+ else
+ result = ISC_R_EXISTS;
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) {
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(appctx_createfunc != NULL);
+ result = (*appctx_createfunc)(mctx, ctxp);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_appctx_destroy(isc_appctx_t **ctxp) {
+ REQUIRE(ctxp != NULL && ISCAPI_APPCTX_VALID(*ctxp));
+
+ (*ctxp)->methods->ctxdestroy(ctxp);
+
+ ENSURE(*ctxp == NULL);
+}
+
+isc_result_t
+isc_app_ctxstart(isc_appctx_t *ctx) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+
+ return (ctx->methods->ctxstart(ctx));
+}
+
+isc_result_t
+isc_app_ctxrun(isc_appctx_t *ctx) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+
+ return (ctx->methods->ctxrun(ctx));
+}
+
+isc_result_t
+isc_app_ctxsuspend(isc_appctx_t *ctx) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+
+ return (ctx->methods->ctxsuspend(ctx));
+}
+
+isc_result_t
+isc_app_ctxshutdown(isc_appctx_t *ctx) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+
+ return (ctx->methods->ctxshutdown(ctx));
+}
+
+void
+isc_app_ctxfinish(isc_appctx_t *ctx) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+
+ ctx->methods->ctxfinish(ctx);
+}
+
+void
+isc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+ REQUIRE(taskmgr != NULL);
+
+ ctx->methods->settaskmgr(ctx, taskmgr);
+}
+
+void
+isc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+ REQUIRE(socketmgr != NULL);
+
+ ctx->methods->setsocketmgr(ctx, socketmgr);
+}
+
+void
+isc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr) {
+ REQUIRE(ISCAPI_APPCTX_VALID(ctx));
+ REQUIRE(timermgr != NULL);
+
+ ctx->methods->settimermgr(ctx, timermgr);
+}
diff --git a/lib/isc/assertions.c b/lib/isc/assertions.c
index b98d61de1a09..fe082b79ef92 100644
--- a/lib/isc/assertions.c
+++ b/lib/isc/assertions.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: assertions.c,v 1.23 2008-10-15 23:47:31 tbox Exp $ */
+/* $Id: assertions.c,v 1.26 2009-09-29 15:06:07 fdupont Exp $ */
/*! \file */
@@ -25,29 +25,47 @@
#include <stdlib.h>
#include <isc/assertions.h>
+#include <isc/backtrace.h>
#include <isc/msgs.h>
+#include <isc/result.h>
+
+/*
+ * The maximum number of stack frames to dump on assertion failure.
+ */
+#ifndef BACKTRACE_MAXFRAME
+#define BACKTRACE_MAXFRAME 128
+#endif
/*%
* Forward.
*/
-/* coverity[+kill] */
static void
default_callback(const char *, int, isc_assertiontype_t, const char *);
+static isc_assertioncallback_t isc_assertion_failed_cb = default_callback;
+
/*%
* Public.
*/
-LIBISC_EXTERNAL_DATA isc_assertioncallback_t isc_assertion_failed =
- default_callback;
+/*% assertion failed handler */
+/* coverity[+kill] */
+void
+isc_assertion_failed(const char *file, int line, isc_assertiontype_t type,
+ const char *cond)
+{
+ isc_assertion_failed_cb(file, line, type, cond);
+ abort();
+ /* NOTREACHED */
+}
/*% Set callback. */
void
isc_assertion_setcallback(isc_assertioncallback_t cb) {
if (cb == NULL)
- isc_assertion_failed = default_callback;
+ isc_assertion_failed_cb = default_callback;
else
- isc_assertion_failed = cb;
+ isc_assertion_failed_cb = cb;
}
/*% Type to Text */
@@ -87,11 +105,35 @@ static void
default_callback(const char *file, int line, isc_assertiontype_t type,
const char *cond)
{
- fprintf(stderr, "%s:%d: %s(%s) %s.\n",
+ void *tracebuf[BACKTRACE_MAXFRAME];
+ int i, nframes;
+ const char *logsuffix = ".";
+ const char *fname;
+ isc_result_t result;
+
+ result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, &nframes);
+ if (result == ISC_R_SUCCESS && nframes > 0)
+ logsuffix = ", back trace";
+
+ fprintf(stderr, "%s:%d: %s(%s) %s%s\n",
file, line, isc_assertion_typetotext(type), cond,
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED, "failed"));
+ ISC_MSG_FAILED, "failed"), logsuffix);
+ if (result == ISC_R_SUCCESS) {
+ for (i = 0; i < nframes; i++) {
+ unsigned long offset;
+
+ fname = NULL;
+ result = isc_backtrace_getsymbol(tracebuf[i], &fname,
+ &offset);
+ if (result == ISC_R_SUCCESS) {
+ fprintf(stderr, "#%d %p in %s()+0x%lx\n", i,
+ tracebuf[i], fname, offset);
+ } else {
+ fprintf(stderr, "#%d %p in ??\n", i,
+ tracebuf[i]);
+ }
+ }
+ }
fflush(stderr);
- abort();
- /* NOTREACHED */
}
diff --git a/lib/isc/backtrace-emptytbl.c b/lib/isc/backtrace-emptytbl.c
new file mode 100644
index 000000000000..27430302ff51
--- /dev/null
+++ b/lib/isc/backtrace-emptytbl.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: backtrace-emptytbl.c,v 1.3 2009-09-01 20:13:44 each Exp $ */
+
+/*! \file */
+
+/*
+ * This file defines an empty (default) symbol table used in backtrace.c
+ * If the application wants to have a complete symbol table, it should redefine
+ * isc__backtrace_symtable with the complete table in some way, and link the
+ * version of the library not including this definition
+ * (e.g. libisc-nosymbol.a).
+ */
+
+#include <config.h>
+
+#include <isc/backtrace.h>
+
+const int isc__backtrace_nsymbols = 0;
+const isc_backtrace_symmap_t isc__backtrace_symtable[] = { { NULL, "" } };
diff --git a/lib/isc/backtrace.c b/lib/isc/backtrace.c
new file mode 100644
index 000000000000..7b5ddfee9d9e
--- /dev/null
+++ b/lib/isc/backtrace.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: backtrace.c,v 1.3 2009-09-02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_LIBCTRACE
+#include <execinfo.h>
+#endif
+
+#include <isc/backtrace.h>
+#include <isc/result.h>
+#include <isc/util.h>
+
+#ifdef ISC_PLATFORM_USEBACKTRACE
+/*
+ * Getting a back trace of a running process is tricky and highly platform
+ * dependent. Our current approach is as follows:
+ * 1. If the system library supports the "backtrace()" function, use it.
+ * 2. Otherwise, if the compiler is gcc and the architecture is x86_64 or IA64,
+ * then use gcc's (hidden) Unwind_Backtrace() function. Note that this
+ * function doesn't work for C programs on many other architectures.
+ * 3. Otherwise, if the architecture x86 or x86_64, try to unwind the stack
+ * frame following frame pointers. This assumes the executable binary
+ * compiled with frame pointers; this is not always true for x86_64 (rather,
+ * compiler optimizations often disable frame pointers). The validation
+ * checks in getnextframeptr() hopefully rejects bogus values stored in
+ * the RBP register in such a case. If the backtrace function itself crashes
+ * due to this problem, the whole package should be rebuilt with
+ * --disable-backtrace.
+ */
+#ifdef HAVE_LIBCTRACE
+#define BACKTRACE_LIBC
+#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__ia64__))
+#define BACKTRACE_GCC
+#elif defined(__x86_64__) || defined(__i386__)
+#define BACKTRACE_X86STACK
+#else
+#define BACKTRACE_DISABLED
+#endif /* HAVE_LIBCTRACE */
+#else /* !ISC_PLATFORM_USEBACKTRACE */
+#define BACKTRACE_DISABLED
+#endif /* ISC_PLATFORM_USEBACKTRACE */
+
+#ifdef BACKTRACE_LIBC
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ int n;
+
+ /*
+ * Validate the arguments: intentionally avoid using REQUIRE().
+ * See notes in backtrace.h.
+ */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+ /*
+ * backtrace(3) includes this function itself in the address array,
+ * which should be eliminated from the returned sequence.
+ */
+ n = backtrace(addrs, maxaddrs);
+ if (n < 2)
+ return (ISC_R_NOTFOUND);
+ n--;
+ memmove(addrs, &addrs[1], sizeof(void *) * n);
+ *nframes = n;
+ return (ISC_R_SUCCESS);
+}
+#elif defined(BACKTRACE_GCC)
+extern int _Unwind_Backtrace(void* fn, void* a);
+extern void* _Unwind_GetIP(void* ctx);
+
+typedef struct {
+ void **result;
+ int max_depth;
+ int skip_count;
+ int count;
+} trace_arg_t;
+
+static int
+btcallback(void *uc, void *opq) {
+ trace_arg_t *arg = (trace_arg_t *)opq;
+
+ if (arg->skip_count > 0)
+ arg->skip_count--;
+ else
+ arg->result[arg->count++] = (void *)_Unwind_GetIP(uc);
+ if (arg->count == arg->max_depth)
+ return (5); /* _URC_END_OF_STACK */
+
+ return (0); /* _URC_NO_REASON */
+}
+
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ trace_arg_t arg;
+
+ /* Argument validation: see above. */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+ arg.skip_count = 1;
+ arg.result = addrs;
+ arg.max_depth = maxaddrs;
+ arg.count = 0;
+ _Unwind_Backtrace(btcallback, &arg);
+
+ *nframes = arg.count;
+
+ return (ISC_R_SUCCESS);
+}
+#elif defined(BACKTRACE_X86STACK)
+#ifdef __x86_64__
+static unsigned long
+getrbp() {
+ __asm("movq %rbp, %rax\n");
+}
+#endif
+
+static void **
+getnextframeptr(void **sp) {
+ void **newsp = (void **)*sp;
+
+ /*
+ * Perform sanity check for the new frame pointer, derived from
+ * google glog. This can actually be bogus depending on compiler.
+ */
+
+ /* prohibit the stack frames from growing downwards */
+ if (newsp <= sp)
+ return (NULL);
+
+ /* A heuristics to reject "too large" frame: this actually happened. */
+ if ((char *)newsp - (char *)sp > 100000)
+ return (NULL);
+
+ /*
+ * Not sure if other checks used in glog are needed at this moment.
+ * For our purposes we don't have to consider non-contiguous frames,
+ * for example.
+ */
+
+ return (newsp);
+}
+
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ int i = 0;
+ void **sp;
+
+ /* Argument validation: see above. */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+#ifdef __x86_64__
+ sp = (void **)getrbp();
+ if (sp == NULL)
+ return (ISC_R_NOTFOUND);
+ /*
+ * sp is the frame ptr of this function itself due to the call to
+ * getrbp(), so need to unwind one frame for consistency.
+ */
+ sp = getnextframeptr(sp);
+#else
+ /*
+ * i386: the frame pointer is stored 2 words below the address for the
+ * first argument. Note that the body of this function cannot be
+ * inlined since it depends on the address of the function argument.
+ */
+ sp = (void **)&addrs - 2;
+#endif
+
+ while (sp != NULL && i < maxaddrs) {
+ addrs[i++] = *(sp + 1);
+ sp = getnextframeptr(sp);
+ }
+
+ *nframes = i;
+
+ return (ISC_R_SUCCESS);
+}
+#elif defined(BACKTRACE_DISABLED)
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ /* Argument validation: see above. */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+ UNUSED(maxaddrs);
+
+ return (ISC_R_NOTIMPLEMENTED);
+}
+#endif
+
+isc_result_t
+isc_backtrace_getsymbolfromindex(int index, const void **addrp,
+ const char **symbolp)
+{
+ REQUIRE(addrp != NULL && *addrp == NULL);
+ REQUIRE(symbolp != NULL && *symbolp == NULL);
+
+ if (index < 0 || index >= isc__backtrace_nsymbols)
+ return (ISC_R_RANGE);
+
+ *addrp = isc__backtrace_symtable[index].addr;
+ *symbolp = isc__backtrace_symtable[index].symbol;
+ return (ISC_R_SUCCESS);
+}
+
+static int
+symtbl_compare(const void *addr, const void *entryarg) {
+ const isc_backtrace_symmap_t *entry = entryarg;
+ const isc_backtrace_symmap_t *end =
+ &isc__backtrace_symtable[isc__backtrace_nsymbols - 1];
+
+ if (isc__backtrace_nsymbols == 1 || entry == end) {
+ if (addr >= entry->addr) {
+ /*
+ * If addr is equal to or larger than that of the last
+ * entry of the table, we cannot be sure if this is
+ * within a valid range so we consider it valid.
+ */
+ return (0);
+ }
+ return (-1);
+ }
+
+ /* entry + 1 is a valid entry from now on. */
+ if (addr < entry->addr)
+ return (-1);
+ else if (addr >= (entry + 1)->addr)
+ return (1);
+ return (0);
+}
+
+isc_result_t
+isc_backtrace_getsymbol(const void *addr, const char **symbolp,
+ unsigned long *offsetp)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_backtrace_symmap_t *found;
+
+ /*
+ * Validate the arguments: intentionally avoid using REQUIRE().
+ * See notes in backtrace.h.
+ */
+ if (symbolp == NULL || *symbolp != NULL || offsetp == NULL)
+ return (ISC_R_FAILURE);
+
+ if (isc__backtrace_nsymbols < 1)
+ return (ISC_R_NOTFOUND);
+
+ /*
+ * Search the table for the entry that meets:
+ * entry.addr <= addr < next_entry.addr.
+ */
+ found = bsearch(addr, isc__backtrace_symtable, isc__backtrace_nsymbols,
+ sizeof(isc__backtrace_symtable[0]), symtbl_compare);
+ if (found == NULL)
+ result = ISC_R_NOTFOUND;
+ else {
+ *symbolp = found->symbol;
+ *offsetp = (const char *)addr - (char *)found->addr;
+ }
+
+ return (result);
+}
diff --git a/lib/isc/base32.c b/lib/isc/base32.c
index 5e5cbd9ba8f0..76219207cffc 100644
--- a/lib/isc/base32.c
+++ b/lib/isc/base32.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: base32.c,v 1.3.116.3 2009-10-21 01:22:47 each Exp $ */
+/* $Id: base32.c,v 1.6 2009-10-21 01:22:29 each Exp $ */
/*! \file */
diff --git a/lib/isc/base64.c b/lib/isc/base64.c
index 858525ffeaba..ee34c3c27dcd 100644
--- a/lib/isc/base64.c
+++ b/lib/isc/base64.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: base64.c,v 1.32.332.2 2009-10-21 23:47:20 tbox Exp $ */
+/* $Id: base64.c,v 1.34 2009-10-21 23:48:05 tbox Exp $ */
/*! \file */
diff --git a/lib/isc/entropy.c b/lib/isc/entropy.c
index af8757f1eb88..8d273d25fbca 100644
--- a/lib/isc/entropy.c
+++ b/lib/isc/entropy.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: entropy.c,v 1.18.332.4 2010-08-10 23:46:54 tbox Exp $ */
+/* $Id: entropy.c,v 1.22 2010-08-10 23:48:19 tbox Exp $ */
/*! \file
* \brief
diff --git a/lib/isc/hash.c b/lib/isc/hash.c
index 7c0fcea1b75b..44975e7803a2 100644
--- a/lib/isc/hash.c
+++ b/lib/isc/hash.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: hash.c,v 1.13.332.3 2009-05-07 23:47:12 tbox Exp $ */
+/* $Id: hash.c,v 1.16 2009-09-01 00:22:28 jinmei Exp $ */
/*! \file
* Some portion of this code was derived from universal hash function
@@ -194,8 +194,12 @@ isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy,
hctx->vectorlen = vlen;
hctx->rndvector = rv;
+#ifdef BIND9
if (entropy != NULL)
isc_entropy_attach(entropy, &hctx->entropy);
+#else
+ UNUSED(entropy);
+#endif
*hctxp = hctx;
return (ISC_R_SUCCESS);
@@ -236,18 +240,22 @@ isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit) {
void
isc_hash_ctxinit(isc_hash_t *hctx) {
- isc_result_t result;
-
LOCK(&hctx->lock);
if (hctx->initialized == ISC_TRUE)
goto out;
if (hctx->entropy) {
+#ifdef BIND9
+ isc_result_t result;
+
result = isc_entropy_getdata(hctx->entropy,
hctx->rndvector, hctx->vectorlen,
NULL, 0);
INSIST(result == ISC_R_SUCCESS);
+#else
+ INSIST(0);
+#endif
} else {
isc_uint32_t pr;
unsigned int i, copylen;
@@ -293,6 +301,7 @@ static void
destroy(isc_hash_t **hctxp) {
isc_hash_t *hctx;
isc_mem_t *mctx;
+ unsigned char canary0[4], canary1[4];
REQUIRE(hctxp != NULL && *hctxp != NULL);
hctx = *hctxp;
@@ -303,8 +312,10 @@ destroy(isc_hash_t **hctxp) {
isc_refcount_destroy(&hctx->refcnt);
mctx = hctx->mctx;
+#ifdef BIND9
if (hctx->entropy != NULL)
isc_entropy_detach(&hctx->entropy);
+#endif
if (hctx->rndvector != NULL)
isc_mem_put(mctx, hctx->rndvector, hctx->vectorlen);
@@ -312,7 +323,10 @@ destroy(isc_hash_t **hctxp) {
DESTROYLOCK(&hctx->lock);
+ memcpy(canary0, hctx + 1, sizeof(canary0));
memset(hctx, 0, sizeof(isc_hash_t));
+ memcpy(canary1, hctx + 1, sizeof(canary1));
+ INSIST(memcmp(canary0, canary1, sizeof(canary0)) == 0);
isc_mem_put(mctx, hctx, sizeof(isc_hash_t));
isc_mem_detach(&mctx);
}
diff --git a/lib/isc/heap.c b/lib/isc/heap.c
index 68f8ba836f3c..4dead3f3ca05 100644
--- a/lib/isc/heap.c
+++ b/lib/isc/heap.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: heap.c,v 1.37.240.3 2010-02-04 23:47:46 tbox Exp $ */
+/* $Id: heap.c,v 1.39 2010-02-04 23:49:13 tbox Exp $ */
/*! \file
* Heap implementation of priority queues adapted from the following:
diff --git a/lib/isc/hmacmd5.c b/lib/isc/hmacmd5.c
index b1d59067b71a..10e87c9921de 100644
--- a/lib/isc/hmacmd5.c
+++ b/lib/isc/hmacmd5.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: hmacmd5.c,v 1.14 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: hmacmd5.c,v 1.16 2009-02-06 23:47:42 tbox Exp $ */
/*! \file
* This code implements the HMAC-MD5 keyed hash algorithm
@@ -27,10 +27,40 @@
#include <isc/assertions.h>
#include <isc/hmacmd5.h>
#include <isc/md5.h>
+#include <isc/platform.h>
#include <isc/string.h>
#include <isc/types.h>
#include <isc/util.h>
+#ifdef ISC_PLATFORM_OPENSSLHASH
+
+void
+isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_md5());
+}
+
+void
+isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
+ HMAC_Final(ctx, digest, NULL);
+ HMAC_CTX_cleanup(ctx);
+}
+
+#else
+
#define PADLEN 64
#define IPAD 0x36
#define OPAD 0x5C
@@ -98,6 +128,7 @@ isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
isc_md5_final(&ctx->md5ctx, digest);
isc_hmacmd5_invalidate(ctx);
}
+#endif /* !ISC_PLATFORM_OPENSSLHASH */
/*!
* Verify signature - finalize MD5 operation and reapply MD5, then
diff --git a/lib/isc/hmacsha.c b/lib/isc/hmacsha.c
index 9f2716367a54..125672d668b9 100644
--- a/lib/isc/hmacsha.c
+++ b/lib/isc/hmacsha.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: hmacsha.c,v 1.8 2007-08-27 03:27:53 marka Exp $ */
+/* $Id: hmacsha.c,v 1.10 2009-02-06 23:47:42 tbox Exp $ */
/*
* This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
@@ -26,12 +26,172 @@
#include <isc/assertions.h>
#include <isc/hmacsha.h>
+#include <isc/platform.h>
#include <isc/sha1.h>
#include <isc/sha2.h>
#include <isc/string.h>
#include <isc/types.h>
#include <isc/util.h>
+#ifdef ISC_PLATFORM_OPENSSLHASH
+
+void
+isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha1());
+}
+
+void
+isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
+
+ HMAC_Final(ctx, newdigest, NULL);
+ HMAC_CTX_cleanup(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+void
+isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha224());
+}
+
+void
+isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
+
+ HMAC_Final(ctx, newdigest, NULL);
+ HMAC_CTX_cleanup(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+void
+isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha256());
+}
+
+void
+isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
+
+ HMAC_Final(ctx, newdigest, NULL);
+ HMAC_CTX_cleanup(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+void
+isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha384());
+}
+
+void
+isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
+
+ HMAC_Final(ctx, newdigest, NULL);
+ HMAC_CTX_cleanup(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+void
+isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ HMAC_Init(ctx, (const void *) key, (int) len, EVP_sha512());
+}
+
+void
+isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
+ HMAC_CTX_cleanup(ctx);
+}
+
+void
+isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ HMAC_Update(ctx, buf, (int) len);
+}
+
+void
+isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
+
+ HMAC_Final(ctx, newdigest, NULL);
+ HMAC_CTX_cleanup(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+#else
+
#define IPAD 0x36
#define OPAD 0x5C
@@ -105,19 +265,6 @@ isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
}
/*
- * Verify signature - finalize SHA1 operation and reapply SHA1, then
- * compare to the supplied digest.
- */
-isc_boolean_t
-isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
- unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
-
- REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
- isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
- return (ISC_TF(memcmp(digest, newdigest, len) == 0));
-}
-
-/*
* Start HMAC-SHA224 process. Initialize an sha224 context and digest the key.
*/
void
@@ -185,19 +332,6 @@ isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
}
/*
- * Verify signature - finalize SHA224 operation and reapply SHA224, then
- * compare to the supplied digest.
- */
-isc_boolean_t
-isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
- unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
-
- REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
- isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
- return (ISC_TF(memcmp(digest, newdigest, len) == 0));
-}
-
-/*
* Start HMAC-SHA256 process. Initialize an sha256 context and digest the key.
*/
void
@@ -265,19 +399,6 @@ isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
}
/*
- * Verify signature - finalize SHA256 operation and reapply SHA256, then
- * compare to the supplied digest.
- */
-isc_boolean_t
-isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
- unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
-
- REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
- isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
- return (ISC_TF(memcmp(digest, newdigest, len) == 0));
-}
-
-/*
* Start HMAC-SHA384 process. Initialize an sha384 context and digest the key.
*/
void
@@ -345,19 +466,6 @@ isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
}
/*
- * Verify signature - finalize SHA384 operation and reapply SHA384, then
- * compare to the supplied digest.
- */
-isc_boolean_t
-isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
- unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
-
- REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
- isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
- return (ISC_TF(memcmp(digest, newdigest, len) == 0));
-}
-
-/*
* Start HMAC-SHA512 process. Initialize an sha512 context and digest the key.
*/
void
@@ -423,6 +531,59 @@ isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
memcpy(digest, newdigest, len);
memset(newdigest, 0, sizeof(newdigest));
}
+#endif /* !ISC_PLATFORM_OPENSSLHASH */
+
+/*
+ * Verify signature - finalize SHA1 operation and reapply SHA1, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
+ isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
+ return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Verify signature - finalize SHA224 operation and reapply SHA224, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
+ isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
+ return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Verify signature - finalize SHA256 operation and reapply SHA256, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
+ isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
+ return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Verify signature - finalize SHA384 operation and reapply SHA384, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
+ isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
+ return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+}
/*
* Verify signature - finalize SHA512 operation and reapply SHA512, then
diff --git a/lib/isc/httpd.c b/lib/isc/httpd.c
index b653f7991e2f..81f118e5a9a0 100644
--- a/lib/isc/httpd.c
+++ b/lib/isc/httpd.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: httpd.c,v 1.16.64.2 2010-02-04 23:47:46 tbox Exp $ */
+/* $Id: httpd.c,v 1.20 2010-11-16 05:38:31 marka Exp $ */
/*! \file */
diff --git a/lib/isc/ia64/include/isc/atomic.h b/lib/isc/ia64/include/isc/atomic.h
index 466cddb9320e..11c9706dbe1e 100644
--- a/lib/isc/ia64/include/isc/atomic.h
+++ b/lib/isc/ia64/include/isc/atomic.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: atomic.h,v 1.4.326.3 2009-06-24 02:21:28 marka Exp $ */
+/* $Id: atomic.h,v 1.7 2009-06-24 02:22:50 marka Exp $ */
#ifndef ISC_ATOMIC_H
#define ISC_ATOMIC_H 1
diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in
index c1d71f4afc2b..12c09cd1f0cc 100644
--- a/lib/isc/include/isc/Makefile.in
+++ b/lib/isc/include/isc/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.64.12.2 2009-02-12 23:47:22 tbox Exp $
+# $Id: Makefile.in,v 1.68 2009-12-05 23:31:41 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -26,15 +26,15 @@ top_srcdir = @top_srcdir@
# machine generated. The latter are handled specially in the
# install target below.
#
-HEADERS = app.h assertions.h base64.h bitstring.h boolean.h buffer.h \
- bufferlist.h commandline.h entropy.h error.h event.h \
+HEADERS = app.h assertions.h base64.h bind9.h bitstring.h boolean.h \
+ buffer.h bufferlist.h commandline.h entropy.h error.h event.h \
eventclass.h file.h formatcheck.h fsaccess.h \
hash.h heap.h hex.h hmacmd5.h \
httpd.h \
interfaceiter.h @ISC_IPV6_H@ iterated_hash.h lang.h lex.h \
lfsr.h lib.h list.h log.h \
- magic.h md5.h mem.h msgcat.h msgs.h \
- mutexblock.h netaddr.h ondestroy.h os.h parseint.h \
+ magic.h md5.h mem.h msgcat.h msgs.h mutexblock.h \
+ namespace.h netaddr.h ondestroy.h os.h parseint.h \
print.h quota.h radix.h random.h ratelimiter.h \
refcount.h region.h resource.h \
result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \
diff --git a/lib/isc/include/isc/app.h b/lib/isc/include/isc/app.h
index 05527581603a..ac8669f0ac77 100644
--- a/lib/isc/include/isc/app.h
+++ b/lib/isc/include/isc/app.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: app.h,v 1.8 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: app.h,v 1.11 2009-09-02 23:48:03 tbox Exp $ */
#ifndef ISC_APP_H
#define ISC_APP_H 1
@@ -54,12 +54,23 @@
* Use of this module is not required. In particular, isc_app_start() is
* NOT an ISC library initialization routine.
*
+ * This module also supports per-thread 'application contexts'. With this
+ * mode, a thread-based application will have a separate context, in which
+ * it uses other ISC library services such as tasks or timers. Signals are
+ * not caught in this mode, so that the application can handle the signals
+ * in its preferred way.
+ *
* \li MP:
* Clients must ensure that isc_app_start(), isc_app_run(), and
* isc_app_finish() are called at most once. isc_app_shutdown()
* is safe to use by any thread (provided isc_app_start() has been
* called previously).
*
+ * The same note applies to isc_app_ctxXXX() functions, but in this case
+ * it's a per-thread restriction. For example, a thread with an
+ * application context must ensure that isc_app_ctxstart() with the
+ * context is called at most once.
+ *
* \li Reliability:
* No anticipated impact.
*
@@ -75,17 +86,64 @@
#include <isc/eventclass.h>
#include <isc/lang.h>
+#include <isc/magic.h>
#include <isc/result.h>
+/***
+ *** Types
+ ***/
+
typedef isc_event_t isc_appevent_t;
#define ISC_APPEVENT_FIRSTEVENT (ISC_EVENTCLASS_APP + 0)
#define ISC_APPEVENT_SHUTDOWN (ISC_EVENTCLASS_APP + 1)
#define ISC_APPEVENT_LASTEVENT (ISC_EVENTCLASS_APP + 65535)
+/*%
+ * app module methods. Only app driver implementations use this structure.
+ * Other clients should use the top-level interfaces (i.e., isc_app_xxx
+ * functions). magic must be ISCAPI_APPMETHODS_MAGIC.
+ */
+typedef struct isc_appmethods {
+ void (*ctxdestroy)(isc_appctx_t **ctxp);
+ isc_result_t (*ctxstart)(isc_appctx_t *ctx);
+ isc_result_t (*ctxrun)(isc_appctx_t *ctx);
+ isc_result_t (*ctxsuspend)(isc_appctx_t *ctx);
+ isc_result_t (*ctxshutdown)(isc_appctx_t *ctx);
+ void (*ctxfinish)(isc_appctx_t *ctx);
+ void (*settaskmgr)(isc_appctx_t *ctx,
+ isc_taskmgr_t *timermgr);
+ void (*setsocketmgr)(isc_appctx_t *ctx,
+ isc_socketmgr_t *timermgr);
+ void (*settimermgr)(isc_appctx_t *ctx,
+ isc_timermgr_t *timermgr);
+} isc_appmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of an application context
+ * implementation's version of an isc_appctx_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. app implementations
+ * may change the structure. 'magic' must be ISCAPI_APPCTX_MAGIC for any
+ * of the isc_app_ routines to work. app implementations must maintain
+ * all app context invariants.
+ */
+struct isc_appctx {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_appmethods_t *methods;
+};
+
+#define ISCAPI_APPCTX_MAGIC ISC_MAGIC('A','a','p','c')
+#define ISCAPI_APPCTX_VALID(c) ((c) != NULL && \
+ (c)->magic == ISCAPI_APPCTX_MAGIC)
+
ISC_LANG_BEGINDECLS
isc_result_t
+isc_app_ctxstart(isc_appctx_t *ctx);
+
+isc_result_t
isc_app_start(void);
/*!<
* \brief Start an ISC library application.
@@ -93,6 +151,9 @@ isc_app_start(void);
* Notes:
* This call should be made before any other ISC library call, and as
* close to the beginning of the application as possible.
+ *
+ * Requires:
+ * 'ctx' is a valid application context (for app_ctxstart()).
*/
isc_result_t
@@ -102,7 +163,7 @@ isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
* \brief Request delivery of an event when the application is run.
*
* Requires:
- * isc_app_start() has been called.
+ *\li isc_app_start() has been called.
*
* Returns:
* ISC_R_SUCCESS
@@ -110,6 +171,9 @@ isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
*/
isc_result_t
+isc_app_ctxrun(isc_appctx_t *ctx);
+
+isc_result_t
isc_app_run(void);
/*!<
* \brief Run an ISC library application.
@@ -120,11 +184,12 @@ isc_app_run(void);
* caller should start shutting down the application.
*
* Requires:
- *\li isc_app_start() has been called.
+ *\li isc_app_[ctx]start() has been called.
*
* Ensures:
*\li Any events requested via isc_app_onrun() will have been posted (in
* FIFO order) before isc_app_run() blocks.
+ *\li 'ctx' is a valid application context (for app_ctxrun()).
*
* Returns:
*\li ISC_R_SUCCESS Shutdown has been requested.
@@ -132,6 +197,9 @@ isc_app_run(void);
*/
isc_result_t
+isc_app_ctxshutdown(isc_appctx_t *ctx);
+
+isc_result_t
isc_app_shutdown(void);
/*!<
* \brief Request application shutdown.
@@ -141,7 +209,8 @@ isc_app_shutdown(void);
* only be triggered once.
*
* Requires:
- *\li isc_app_run() has been called.
+ *\li isc_app_[ctx]run() has been called.
+ *\li 'ctx' is a valid application context (for app_ctxshutdown()).
*
* Returns:
*\li ISC_R_SUCCESS
@@ -149,6 +218,12 @@ isc_app_shutdown(void);
*/
isc_result_t
+isc_app_ctxsuspend(isc_appctx_t *ctx);
+/*!<
+ * \brief This has the same behavior as isc_app_ctxsuspend().
+ */
+
+isc_result_t
isc_app_reload(void);
/*!<
* \brief Request application reload.
@@ -162,6 +237,9 @@ isc_app_reload(void);
*/
void
+isc_app_ctxfinish(isc_appctx_t *ctx);
+
+void
isc_app_finish(void);
/*!<
* \brief Finish an ISC library application.
@@ -171,6 +249,7 @@ isc_app_finish(void);
*
* Requires:
*\li isc_app_start() has been called.
+ *\li 'ctx' is a valid application context (for app_ctxfinish()).
*
* Ensures:
*\li Any resources allocated by isc_app_start() have been released.
@@ -206,6 +285,90 @@ isc_app_unblock(void);
* \li isc_app_block() has been called by the same thread.
*/
+isc_result_t
+isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp);
+/*!<
+ * \brief Create an application context.
+ *
+ * Requires:
+ *\li 'mctx' is a valid memory context.
+ *\li 'ctxp' != NULL && *ctxp == NULL.
+ */
+
+void
+isc_appctx_destroy(isc_appctx_t **ctxp);
+/*!<
+ * \brief Destroy an application context.
+ *
+ * Requires:
+ *\li '*ctxp' is a valid application context.
+ *
+ * Ensures:
+ *\li *ctxp == NULL.
+ */
+
+void
+isc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr);
+/*!<
+ * \brief Associate a task manager with an application context.
+ *
+ * This must be done before running tasks within the application context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'taskmgr' is a valid task manager.
+ */
+
+void
+isc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr);
+/*!<
+ * \brief Associate a socket manager with an application context.
+ *
+ * This must be done before handling socket events within the application
+ * context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'socketmgr' is a valid socket manager.
+ */
+
+void
+isc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr);
+/*!<
+ * \brief Associate a socket timer with an application context.
+ *
+ * This must be done before handling timer events within the application
+ * context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'timermgr' is a valid timer manager.
+ */
+
+#ifdef USE_APPIMPREGISTER
+/*%<
+ * See isc_appctx_create() above.
+ */
+typedef isc_result_t
+(*isc_appctxcreatefunc_t)(isc_mem_t *mctx, isc_appctx_t **ctxp);
+
+isc_result_t
+isc_app_register(isc_appctxcreatefunc_t createfunc);
+/*%<
+ * Register a new application implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__app_register(void);
+/*%<
+ * A short cut function that specifies the application module in the ISC
+ * library for isc_app_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_APPIMPREGISTER */
ISC_LANG_ENDDECLS
diff --git a/lib/isc/include/isc/assertions.h b/lib/isc/include/isc/assertions.h
index 8a2ba7ed4056..91217b85f96c 100644
--- a/lib/isc/include/isc/assertions.h
+++ b/lib/isc/include/isc/assertions.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,7 +16,7 @@
*/
/*
- * $Id: assertions.h,v 1.26 2008-10-15 23:47:31 tbox Exp $
+ * $Id: assertions.h,v 1.28 2009-09-29 23:48:04 tbox Exp $
*/
/*! \file isc/assertions.h
*/
@@ -41,7 +41,9 @@ typedef void (*isc_assertioncallback_t)(const char *, int, isc_assertiontype_t,
const char *);
/* coverity[+kill] */
-LIBISC_EXTERNAL_DATA extern isc_assertioncallback_t isc_assertion_failed;
+ISC_PLATFORM_NORETURN_PRE
+void isc_assertion_failed(const char *, int, isc_assertiontype_t,
+ const char *) ISC_PLATFORM_NORETURN_POST;
void
isc_assertion_setcallback(isc_assertioncallback_t);
diff --git a/lib/isc/include/isc/backtrace.h b/lib/isc/include/isc/backtrace.h
new file mode 100644
index 000000000000..94fee61cb3a8
--- /dev/null
+++ b/lib/isc/include/isc/backtrace.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: backtrace.h,v 1.2 2009-09-01 18:40:25 jinmei Exp $ */
+
+/*! \file isc/backtrace.h
+ * \brief provide a back trace of the running process to help debug problems.
+ *
+ * This module tries to get a back trace of the process using some platform
+ * dependent way when available. It also manages an internal symbol table
+ * that maps function addresses used in the process to their textual symbols.
+ * This module is expected to be used to help debug when some fatal error
+ * happens.
+ *
+ * IMPORTANT NOTE: since the (major) intended use case of this module is
+ * dumping a back trace on a fatal error, normally followed by self termination,
+ * functions defined in this module generally doesn't employ assertion checks
+ * (if it did, a program bug could cause infinite recursive calls to a
+ * backtrace function). These functions still perform minimal checks and return
+ * ISC_R_FAILURE if they detect an error, but the caller should therefore be
+ * very careful about the use of these functions, and generally discouraged to
+ * use them except in an exit path. The exception is
+ * isc_backtrace_getsymbolfromindex(), which is expected to be used in a
+ * non-error-handling context and validates arguments with assertion checks.
+ */
+
+#ifndef ISC_BACKTRACE_H
+#define ISC_BACKTRACE_H 1
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/types.h>
+
+/***
+ *** Types
+ ***/
+struct isc_backtrace_symmap {
+ void *addr;
+ const char *symbol;
+};
+
+extern const int isc__backtrace_nsymbols;
+extern const isc_backtrace_symmap_t isc__backtrace_symtable[];
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes);
+/*%<
+ * Get a back trace of the running process above this function itself. On
+ * success, addrs[i] will store the address of the call point of the i-th
+ * stack frame (addrs[0] is the caller of this function). *nframes will store
+ * the total number of frames.
+ *
+ * Requires (note that these are not ensured by assertion checks, see above):
+ *
+ *\li 'addrs' is a valid array containing at least 'maxaddrs' void * entries.
+ *
+ *\li 'nframes' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_FAILURE
+ *\li #ISC_R_NOTFOUND
+ *\li #ISC_R_NOTIMPLEMENTED
+ */
+
+isc_result_t
+isc_backtrace_getsymbolfromindex(int index, const void **addrp,
+ const char **symbolp);
+/*%<
+ * Returns the content of the internal symbol table of the given index.
+ * On success, *addrsp and *symbolp point to the address and the symbol of
+ * the 'index'th entry of the table, respectively. If 'index' is not in the
+ * range of the symbol table, ISC_R_RANGE will be returned.
+ *
+ * Requires
+ *
+ *\li 'addrp' must be non NULL && '*addrp' == NULL.
+ *
+ *\li 'symbolp' must be non NULL && '*symbolp' == NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_RANGE
+ */
+
+isc_result_t
+isc_backtrace_getsymbol(const void *addr, const char **symbolp,
+ unsigned long *offsetp);
+/*%<
+ * Searches the internal symbol table for the symbol that most matches the
+ * given 'addr'. On success, '*symbolp' will point to the name of function
+ * to which the address 'addr' belong, and '*offsetp' will store the offset
+ * from the function's entry address to 'addr'.
+ *
+ * Requires (note that these are not ensured by assertion checks, see above):
+ *
+ *\li 'symbolp' must be non NULL && '*symbolp' == NULL.
+ *
+ *\li 'offsetp' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_FAILURE
+ *\li #ISC_R_NOTFOUND
+ */
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BACKTRACE_H */
diff --git a/lib/isc/include/isc/bind9.h b/lib/isc/include/isc/bind9.h
new file mode 100644
index 000000000000..dd75e91c33de
--- /dev/null
+++ b/lib/isc/include/isc/bind9.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: bind9.h,v 1.2 2009-12-05 23:31:41 each Exp $ */
+
+#ifndef ISC_BIND9_H
+#define ISC_BIND9_H 1
+
+/*
+ * This determines whether we are building BIND9 or using the exported
+ * libisc/libdns libraries. The version of this file included in the
+ * standard BIND9 build defines BIND9; the version included with the
+ * exportable libraries does not.
+ */
+#define BIND9 1
+
+#endif /* ISC_BIND9_H */
diff --git a/lib/isc/include/isc/buffer.h b/lib/isc/include/isc/buffer.h
index e55c5b0f0d3d..30a6e398ddbb 100644
--- a/lib/isc/include/isc/buffer.h
+++ b/lib/isc/include/isc/buffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: buffer.h,v 1.53 2008-09-25 04:02:39 tbox Exp $ */
+/* $Id: buffer.h,v 1.55 2010-12-20 23:47:21 tbox Exp $ */
#ifndef ISC_BUFFER_H
#define ISC_BUFFER_H 1
diff --git a/lib/isc/include/isc/entropy.h b/lib/isc/include/isc/entropy.h
index 1eb8fd1d0879..e1159069bbac 100644
--- a/lib/isc/include/isc/entropy.h
+++ b/lib/isc/include/isc/entropy.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: entropy.h,v 1.32.332.3 2009-10-19 02:46:07 marka Exp $ */
+/* $Id: entropy.h,v 1.35 2009-10-19 02:37:08 marka Exp $ */
#ifndef ISC_ENTROPY_H
#define ISC_ENTROPY_H 1
diff --git a/lib/isc/include/isc/error.h b/lib/isc/include/isc/error.h
index a0025e061ab5..d3dcc8bdb58c 100644
--- a/lib/isc/include/isc/error.h
+++ b/lib/isc/include/isc/error.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: error.h,v 1.20 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: error.h,v 1.22 2009-09-29 23:48:04 tbox Exp $ */
#ifndef ISC_ERROR_H
#define ISC_ERROR_H 1
@@ -26,6 +26,7 @@
#include <isc/formatcheck.h>
#include <isc/lang.h>
+#include <isc/platform.h>
ISC_LANG_BEGINDECLS
@@ -45,9 +46,9 @@ isc_error_unexpected(const char *, int, const char *, ...)
ISC_FORMAT_PRINTF(3, 4);
/*% fatal error */
-void
+ISC_PLATFORM_NORETURN_PRE void
isc_error_fatal(const char *, int, const char *, ...)
- ISC_FORMAT_PRINTF(3, 4);
+ISC_FORMAT_PRINTF(3, 4) ISC_PLATFORM_NORETURN_POST;
/*% runtimecheck error */
void
diff --git a/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h
index 6629a3e159ef..be4082540bce 100644
--- a/lib/isc/include/isc/file.h
+++ b/lib/isc/include/isc/file.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: file.h,v 1.33.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: file.h,v 1.39 2011-01-11 23:47:14 tbox Exp $ */
#ifndef ISC_FILE_H
#define ISC_FILE_H 1
@@ -100,6 +100,10 @@ isc_file_mktemplate(const char *path, char *buf, size_t buflen);
isc_result_t
isc_file_openunique(char *templet, FILE **fp);
+isc_result_t
+isc_file_openuniqueprivate(char *templet, FILE **fp);
+isc_result_t
+isc_file_openuniquemode(char *templet, int mode, FILE **fp);
/*!<
* \brief Create and open a file with a unique name based on 'templet'.
*
@@ -251,6 +255,29 @@ isc_file_truncate(const char *filename, isc_offset_t size);
* Truncate/extend the file specified to 'size' bytes.
*/
+isc_result_t
+isc_file_safecreate(const char *filename, FILE **fp);
+/*%<
+ * Open 'filename' for writing, truncating if necessary. Ensure that
+ * if it existed it was a normal file. If creating the file, ensure
+ * that only the owner can read/write it.
+ */
+
+isc_result_t
+isc_file_splitpath(isc_mem_t *mctx, char *path,
+ char **dirname, char **basename);
+/*%<
+ * Split a path into dirname and basename. If 'path' contains no slash
+ * (or, on windows, backslash), then '*dirname' is set to ".".
+ *
+ * Allocates memory for '*dirname', which can be freed with isc_mem_free().
+ *
+ * Returns:
+ * - ISC_R_SUCCESS on success
+ * - ISC_R_INVALIDFILE if 'path' is empty or ends with '/'
+ * - ISC_R_NOMEMORY if unable to allocate memory
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_FILE_H */
diff --git a/lib/isc/include/isc/fsaccess.h b/lib/isc/include/isc/fsaccess.h
index 88469dd68c9b..9758242d094c 100644
--- a/lib/isc/include/isc/fsaccess.h
+++ b/lib/isc/include/isc/fsaccess.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: fsaccess.h,v 1.14.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: fsaccess.h,v 1.16 2009-01-17 23:47:43 tbox Exp $ */
#ifndef ISC_FSACCESS_H
#define ISC_FSACCESS_H 1
diff --git a/lib/isc/include/isc/hash.h b/lib/isc/include/isc/hash.h
index 9bfb709ceeff..543e5fd9a148 100644
--- a/lib/isc/include/isc/hash.h
+++ b/lib/isc/include/isc/hash.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: hash.h,v 1.10.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: hash.h,v 1.12 2009-01-17 23:47:43 tbox Exp $ */
#ifndef ISC_HASH_H
#define ISC_HASH_H 1
diff --git a/lib/isc/include/isc/heap.h b/lib/isc/include/isc/heap.h
index ae346c1a9ea4..943ace39f020 100644
--- a/lib/isc/include/isc/heap.h
+++ b/lib/isc/include/isc/heap.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: heap.h,v 1.24.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: heap.h,v 1.26 2009-01-17 23:47:43 tbox Exp $ */
#ifndef ISC_HEAP_H
#define ISC_HEAP_H 1
diff --git a/lib/isc/include/isc/hmacmd5.h b/lib/isc/include/isc/hmacmd5.h
index 68074ae41db8..c7d7fff5239a 100644
--- a/lib/isc/include/isc/hmacmd5.h
+++ b/lib/isc/include/isc/hmacmd5.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: hmacmd5.h,v 1.12 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: hmacmd5.h,v 1.14 2009-02-06 23:47:42 tbox Exp $ */
/*! \file isc/hmacmd5.h
* \brief This is the header file for the HMAC-MD5 keyed hash algorithm
@@ -27,14 +27,23 @@
#include <isc/lang.h>
#include <isc/md5.h>
+#include <isc/platform.h>
#include <isc/types.h>
#define ISC_HMACMD5_KEYLENGTH 64
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/hmac.h>
+
+typedef HMAC_CTX isc_hmacmd5_t;
+
+#else
+
typedef struct {
isc_md5_t md5ctx;
unsigned char key[ISC_HMACMD5_KEYLENGTH];
} isc_hmacmd5_t;
+#endif
ISC_LANG_BEGINDECLS
diff --git a/lib/isc/include/isc/hmacsha.h b/lib/isc/include/isc/hmacsha.h
index c439883cdda3..286cafcfb25e 100644
--- a/lib/isc/include/isc/hmacsha.h
+++ b/lib/isc/include/isc/hmacsha.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: hmacsha.h,v 1.7 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: hmacsha.h,v 1.9 2009-02-06 23:47:42 tbox Exp $ */
/*! \file isc/hmacsha.h
* This is the header file for the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256,
@@ -25,6 +25,7 @@
#define ISC_HMACSHA_H 1
#include <isc/lang.h>
+#include <isc/platform.h>
#include <isc/sha1.h>
#include <isc/sha2.h>
#include <isc/types.h>
@@ -35,6 +36,17 @@
#define ISC_HMACSHA384_KEYLENGTH ISC_SHA384_BLOCK_LENGTH
#define ISC_HMACSHA512_KEYLENGTH ISC_SHA512_BLOCK_LENGTH
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/hmac.h>
+
+typedef HMAC_CTX isc_hmacsha1_t;
+typedef HMAC_CTX isc_hmacsha224_t;
+typedef HMAC_CTX isc_hmacsha256_t;
+typedef HMAC_CTX isc_hmacsha384_t;
+typedef HMAC_CTX isc_hmacsha512_t;
+
+#else
+
typedef struct {
isc_sha1_t sha1ctx;
unsigned char key[ISC_HMACSHA1_KEYLENGTH];
@@ -59,6 +71,7 @@ typedef struct {
isc_sha512_t sha512ctx;
unsigned char key[ISC_HMACSHA512_KEYLENGTH];
} isc_hmacsha512_t;
+#endif
ISC_LANG_BEGINDECLS
diff --git a/lib/isc/include/isc/lib.h b/lib/isc/include/isc/lib.h
index 3804a0751cad..c8bdbc67c480 100644
--- a/lib/isc/include/isc/lib.h
+++ b/lib/isc/include/isc/lib.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lib.h,v 1.14 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: lib.h,v 1.16 2009-09-02 23:48:03 tbox Exp $ */
#ifndef ISC_LIB_H
#define ISC_LIB_H 1
@@ -36,6 +36,15 @@ isc_lib_initmsgcat(void);
* has not already been initialized.
*/
+void
+isc_lib_register(void);
+/*!<
+ * \brief Register the ISC library implementations for some base services
+ * such as memory or event management and handling socket or timer events.
+ * An external application that wants to use the ISC library must call this
+ * function very early in main().
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_LIB_H */
diff --git a/lib/isc/include/isc/log.h b/lib/isc/include/isc/log.h
index fec3d9d8421e..eac575589d16 100644
--- a/lib/isc/include/isc/log.h
+++ b/lib/isc/include/isc/log.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: log.h,v 1.54.332.5 2009-02-16 02:04:05 marka Exp $ */
+/* $Id: log.h,v 1.59 2009-02-16 02:01:16 marka Exp $ */
#ifndef ISC_LOG_H
#define ISC_LOG_H 1
diff --git a/lib/isc/include/isc/md5.h b/lib/isc/include/isc/md5.h
index 9d5b1ec0a1aa..90171152cd58 100644
--- a/lib/isc/include/isc/md5.h
+++ b/lib/isc/include/isc/md5.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: md5.h,v 1.16 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: md5.h,v 1.20 2010-01-07 23:48:54 tbox Exp $ */
/*! \file isc/md5.h
* \brief This is the header file for the MD5 message-digest algorithm.
@@ -44,15 +44,25 @@
#define ISC_MD5_H 1
#include <isc/lang.h>
+#include <isc/platform.h>
#include <isc/types.h>
#define ISC_MD5_DIGESTLENGTH 16U
+#define ISC_MD5_BLOCK_LENGTH 64U
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/evp.h>
+
+typedef EVP_MD_CTX isc_md5_t;
+
+#else
typedef struct {
isc_uint32_t buf[4];
isc_uint32_t bytes[2];
isc_uint32_t in[16];
} isc_md5_t;
+#endif
ISC_LANG_BEGINDECLS
diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h
index d13d912c4998..e0a7fe532eea 100644
--- a/lib/isc/include/isc/mem.h
+++ b/lib/isc/include/isc/mem.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mem.h,v 1.78.120.6 2010-08-11 23:04:21 jinmei Exp $ */
+/* $Id: mem.h,v 1.89 2010-08-11 22:54:58 jinmei Exp $ */
#ifndef ISC_MEM_H
#define ISC_MEM_H 1
@@ -152,11 +152,29 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging;
#endif
-#define isc_mem_get(c, s) isc__mem_get((c), (s) _ISC_MEM_FILELINE)
-#define isc_mem_allocate(c, s) isc__mem_allocate((c), (s) _ISC_MEM_FILELINE)
-#define isc_mem_reallocate(c, p, s) isc__mem_reallocate((c), (p), (s) _ISC_MEM_FILELINE)
-#define isc_mem_strdup(c, p) isc__mem_strdup((c), (p) _ISC_MEM_FILELINE)
-#define isc_mempool_get(c) isc__mempool_get((c) _ISC_MEM_FILELINE)
+/*%<
+ * We use either isc___mem (three underscores) or isc__mem (two) depending on
+ * whether it's for BIND9's internal purpose (with -DBIND9) or generic export
+ * library. This condition is generally handled in isc/namespace.h, but for
+ * Windows it doesn't work if it involves multiple times of macro expansion
+ * (such as isc_mem to isc__mem then to isc___mem). The following definitions
+ * are used to work around this portability issue. Right now, we don't support
+ * the export library for Windows, so we always use the three-underscore
+ * version.
+ */
+#ifdef WIN32
+#define ISCMEMFUNC(sfx) isc___mem_ ## sfx
+#define ISCMEMPOOLFUNC(sfx) isc___mempool_ ## sfx
+#else
+#define ISCMEMFUNC(sfx) isc__mem_ ## sfx
+#define ISCMEMPOOLFUNC(sfx) isc__mempool_ ## sfx
+#endif
+
+#define isc_mem_get(c, s) ISCMEMFUNC(get)((c), (s) _ISC_MEM_FILELINE)
+#define isc_mem_allocate(c, s) ISCMEMFUNC(allocate)((c), (s) _ISC_MEM_FILELINE)
+#define isc_mem_reallocate(c, p, s) ISCMEMFUNC(reallocate)((c), (p), (s) _ISC_MEM_FILELINE)
+#define isc_mem_strdup(c, p) ISCMEMFUNC(strdup)((c), (p) _ISC_MEM_FILELINE)
+#define isc_mempool_get(c) ISCMEMPOOLFUNC(get)((c) _ISC_MEM_FILELINE)
/*%
* isc_mem_putanddetach() is a convenience function for use where you
@@ -187,33 +205,102 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging;
* \endcode
*/
+/*% memory and memory pool methods */
+typedef struct isc_memmethods {
+ void (*attach)(isc_mem_t *source, isc_mem_t **targetp);
+ void (*detach)(isc_mem_t **mctxp);
+ void (*destroy)(isc_mem_t **mctxp);
+ void *(*memget)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG);
+ void (*memput)(isc_mem_t *mctx, void *ptr, size_t size _ISC_MEM_FLARG);
+ void (*memputanddetach)(isc_mem_t **mctxp, void *ptr,
+ size_t size _ISC_MEM_FLARG);
+ void *(*memallocate)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG);
+ void *(*memreallocate)(isc_mem_t *mctx, void *ptr,
+ size_t size _ISC_MEM_FLARG);
+ char *(*memstrdup)(isc_mem_t *mctx, const char *s _ISC_MEM_FLARG);
+ void (*memfree)(isc_mem_t *mctx, void *ptr _ISC_MEM_FLARG);
+ void (*setdestroycheck)(isc_mem_t *mctx, isc_boolean_t flag);
+ void (*setwater)(isc_mem_t *ctx, isc_mem_water_t water,
+ void *water_arg, size_t hiwater, size_t lowater);
+ void (*waterack)(isc_mem_t *ctx, int flag);
+ size_t (*inuse)(isc_mem_t *mctx);
+ isc_boolean_t (*isovermem)(isc_mem_t *mctx);
+ isc_result_t (*mpcreate)(isc_mem_t *mctx, size_t size,
+ isc_mempool_t **mpctxp);
+} isc_memmethods_t;
+
+typedef struct isc_mempoolmethods {
+ void (*destroy)(isc_mempool_t **mpctxp);
+ void *(*get)(isc_mempool_t *mpctx _ISC_MEM_FLARG);
+ void (*put)(isc_mempool_t *mpctx, void *mem _ISC_MEM_FLARG);
+ unsigned int (*getallocated)(isc_mempool_t *mpctx);
+ void (*setmaxalloc)(isc_mempool_t *mpctx, unsigned int limit);
+ void (*setfreemax)(isc_mempool_t *mpctx, unsigned int limit);
+ void (*setname)(isc_mempool_t *mpctx, const char *name);
+ void (*associatelock)(isc_mempool_t *mpctx, isc_mutex_t *lock);
+ void (*setfillcount)(isc_mempool_t *mpctx, unsigned int limit);
+} isc_mempoolmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a memory context
+ * implementation's version of an isc_mem_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. mctx implementations
+ * may change the structure. 'magic' must be ISCAPI_MCTX_MAGIC for any of the
+ * isc_mem_ routines to work. mctx implementations must maintain all mctx
+ * invariants.
+ */
+struct isc_mem {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_memmethods_t *methods;
+};
+
+#define ISCAPI_MCTX_MAGIC ISC_MAGIC('A','m','c','x')
+#define ISCAPI_MCTX_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_MCTX_MAGIC)
+
+/*%
+ * This is the common prefix of a memory pool context. The same note as
+ * that for the mem structure applies.
+ */
+struct isc_mempool {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_mempoolmethods_t *methods;
+};
+
+#define ISCAPI_MPOOL_MAGIC ISC_MAGIC('A','m','p','l')
+#define ISCAPI_MPOOL_VALID(mp) ((mp) != NULL && \
+ (mp)->magic == ISCAPI_MPOOL_MAGIC)
+
#if ISC_MEM_DEBUG
#define isc_mem_put(c, p, s) \
do { \
- isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE); \
+ ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mem_putanddetach(c, p, s) \
do { \
- isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE); \
+ ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mem_free(c, p) \
do { \
- isc__mem_free((c), (p) _ISC_MEM_FILELINE); \
+ ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mempool_put(c, p) \
do { \
- isc__mempool_put((c), (p) _ISC_MEM_FILELINE); \
+ ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#else
-#define isc_mem_put(c, p, s) isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE)
+#define isc_mem_put(c, p, s) ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE)
#define isc_mem_putanddetach(c, p, s) \
- isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE)
-#define isc_mem_free(c, p) isc__mem_free((c), (p) _ISC_MEM_FILELINE)
-#define isc_mempool_put(c, p) isc__mempool_put((c), (p) _ISC_MEM_FILELINE)
+ ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE)
+#define isc_mem_free(c, p) ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE)
+#define isc_mempool_put(c, p) ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE)
#endif
/*@{*/
@@ -613,24 +700,50 @@ isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
* Pseudo-private functions for use via macros. Do not call directly.
*/
void *
-isc__mem_get(isc_mem_t *, size_t _ISC_MEM_FLARG);
+ISCMEMFUNC(get)(isc_mem_t *, size_t _ISC_MEM_FLARG);
void
-isc__mem_putanddetach(isc_mem_t **, void *,
- size_t _ISC_MEM_FLARG);
+ISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t _ISC_MEM_FLARG);
void
-isc__mem_put(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
+ISCMEMFUNC(put)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
void *
-isc__mem_allocate(isc_mem_t *, size_t _ISC_MEM_FLARG);
+ISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG);
void *
-isc__mem_reallocate(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
+ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
void
-isc__mem_free(isc_mem_t *, void * _ISC_MEM_FLARG);
+ISCMEMFUNC(free)(isc_mem_t *, void * _ISC_MEM_FLARG);
char *
-isc__mem_strdup(isc_mem_t *, const char *_ISC_MEM_FLARG);
+ISCMEMFUNC(strdup)(isc_mem_t *, const char *_ISC_MEM_FLARG);
void *
-isc__mempool_get(isc_mempool_t * _ISC_MEM_FLARG);
+ISCMEMPOOLFUNC(get)(isc_mempool_t * _ISC_MEM_FLARG);
void
-isc__mempool_put(isc_mempool_t *, void * _ISC_MEM_FLARG);
+ISCMEMPOOLFUNC(put)(isc_mempool_t *, void * _ISC_MEM_FLARG);
+
+#ifdef USE_MEMIMPREGISTER
+
+/*%<
+ * See isc_mem_create2() above.
+ */
+typedef isc_result_t
+(*isc_memcreatefunc_t)(size_t init_max_size, size_t target_size,
+ isc_mem_t **ctxp, unsigned int flags);
+
+isc_result_t
+isc_mem_register(isc_memcreatefunc_t createfunc);
+/*%<
+ * Register a new memory management implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * memory management library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__mem_register(void);
+/*%<
+ * A short cut function that specifies the memory management module in the ISC
+ * library for isc_mem_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_MEMIMPREGISTER */
ISC_LANG_ENDDECLS
diff --git a/lib/isc/include/isc/msgs.h b/lib/isc/include/isc/msgs.h
index 674371f540b8..22dfde290eb5 100644
--- a/lib/isc/include/isc/msgs.h
+++ b/lib/isc/include/isc/msgs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: msgs.h,v 1.17 2008-08-08 06:28:59 tbox Exp $ */
+/* $Id: msgs.h,v 1.19 2009-10-01 23:48:08 tbox Exp $ */
#ifndef ISC_MSGS_H
#define ISC_MSGS_H 1
@@ -156,7 +156,7 @@
#define ISC_MSG_FILTER 1421 /*%< setsockopt(SO_ACCEPTFILTER): %s */
#define ISC_MSG_TOOMANYHANDLES 1422 /*%< %s: too many open WSA event handles: %s */
-
+#define ISC_MSG_POKED 1423 /*%< "poked flags: %d" */
#define ISC_MSG_AWAKE 1502 /*%< "awake" */
#define ISC_MSG_WORKING 1503 /*%< "working" */
diff --git a/lib/isc/include/isc/namespace.h b/lib/isc/include/isc/namespace.h
new file mode 100644
index 000000000000..05a8b2c9de50
--- /dev/null
+++ b/lib/isc/include/isc/namespace.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: namespace.h,v 1.9 2010-12-04 13:25:59 marka Exp $ */
+
+#ifndef ISCAPI_NAMESPACE_H
+#define ISCAPI_NAMESPACE_H 1
+
+/*%
+ * name space conversions
+ */
+
+#ifdef BIND9
+
+#define isc_app_start isc__app_start
+#define isc_app_ctxstart isc__app_ctxstart
+#define isc_app_onrun isc__app_onrun
+#define isc_app_run isc__app_run
+#define isc_app_ctxrun isc__app_ctxrun
+#define isc_app_shutdown isc__app_shutdown
+#define isc_app_ctxshutdown isc__app_ctxshutdown
+#define isc_app_ctxsuspend isc__app_ctxsuspend
+#define isc_app_reload isc__app_reload
+#define isc_app_finish isc__app_finish
+#define isc_app_block isc__app_block
+#define isc_app_unblock isc__app_unblock
+#define isc_appctx_create isc__appctx_create
+#define isc_appctx_destroy isc__appctx_destroy
+#define isc_appctx_settaskmgr isc__appctx_settaskmgr
+#define isc_appctx_setsocketmgr isc__appctx_setsocketmgr
+#define isc_appctx_settimermgr isc__appctx_settimermgr
+
+#define isc_mem_checkdestroyed isc__mem_checkdestroyed
+#define isc_mem_createx isc__mem_createx
+#define isc_mem_createx2 isc__mem_createx2
+#define isc_mem_create isc__mem_create
+#define isc_mem_create2 isc__mem_create2
+#define isc_mem_attach isc__mem_attach
+#define isc_mem_detach isc__mem_detach
+#define isc__mem_putanddetach isc___mem_putanddetach
+#define isc_mem_destroy isc__mem_destroy
+#define isc_mem_ondestroy isc__mem_ondestroy
+#define isc__mem_get isc___mem_get
+#define isc__mem_put isc___mem_put
+#define isc_mem_stats isc__mem_stats
+#define isc__mem_allocate isc___mem_allocate
+#define isc__mem_free isc___mem_free
+#define isc__mem_strdup isc___mem_strdup
+#define isc__mem_reallocate isc___mem_reallocate
+#define isc_mem_references isc__mem_references
+#define isc_mem_setdestroycheck isc__mem_setdestroycheck
+#define isc_mem_setquota isc__mem_setquota
+#define isc_mem_getname isc__mem_getname
+#define isc_mem_getquota isc__mem_getquota
+#define isc_mem_gettag isc__mem_gettag
+#define isc_mem_inuse isc__mem_inuse
+#define isc_mem_isovermem isc__mem_isovermem
+#define isc_mem_setname isc__mem_setname
+#define isc_mem_setwater isc__mem_setwater
+#define isc_mem_printallactive isc__mem_printallactive
+#define isc_mem_waterack isc__mem_waterack
+#define isc_mempool_create isc__mempool_create
+#define isc_mempool_setname isc__mempool_setname
+#define isc_mempool_destroy isc__mempool_destroy
+#define isc_mempool_associatelock isc__mempool_associatelock
+#define isc__mempool_get isc___mempool_get
+#define isc__mempool_put isc___mempool_put
+#define isc_mempool_setfreemax isc__mempool_setfreemax
+#define isc_mempool_getfreemax isc__mempool_getfreemax
+#define isc_mempool_getfreecount isc__mempool_getfreecount
+#define isc_mempool_setmaxalloc isc__mempool_setmaxalloc
+#define isc_mempool_getmaxalloc isc__mempool_getmaxalloc
+#define isc_mempool_getallocated isc__mempool_getallocated
+#define isc_mempool_setfillcount isc__mempool_setfillcount
+#define isc_mempool_getfillcount isc__mempool_getfillcount
+
+#define isc_socket_create isc__socket_create
+#define isc_socket_attach isc__socket_attach
+#define isc_socket_detach isc__socket_detach
+#define isc_socketmgr_create isc__socketmgr_create
+#define isc_socketmgr_create2 isc__socketmgr_create2
+#define isc_socketmgr_destroy isc__socketmgr_destroy
+#define isc_socket_open isc__socket_open
+#define isc_socket_close isc__socket_close
+#define isc_socket_recvv isc__socket_recvv
+#define isc_socket_recv isc__socket_recv
+#define isc_socket_recv2 isc__socket_recv2
+#define isc_socket_send isc__socket_send
+#define isc_socket_sendto isc__socket_sendto
+#define isc_socket_sendv isc__socket_sendv
+#define isc_socket_sendtov isc__socket_sendtov
+#define isc_socket_sendto2 isc__socket_sendto2
+#define isc_socket_cleanunix isc__socket_cleanunix
+#define isc_socket_permunix isc__socket_permunix
+#define isc_socket_bind isc__socket_bind
+#define isc_socket_filter isc__socket_filter
+#define isc_socket_listen isc__socket_listen
+#define isc_socket_accept isc__socket_accept
+#define isc_socket_connect isc__socket_connect
+#define isc_socket_getname isc__socket_getname
+#define isc_socket_gettag isc__socket_gettag
+#define isc_socket_getpeername isc__socket_getpeername
+#define isc_socket_getsockname isc__socket_getsockname
+#define isc_socket_cancel isc__socket_cancel
+#define isc_socket_gettype isc__socket_gettype
+#define isc_socket_isbound isc__socket_isbound
+#define isc_socket_ipv6only isc__socket_ipv6only
+#define isc_socket_setname isc__socket_setname
+#define isc_socketmgr_getmaxsockets isc__socketmgr_getmaxsockets
+#define isc_socketmgr_setstats isc__socketmgr_setstats
+#define isc_socketmgr_setreserved isc__socketmgr_setreserved
+#define isc__socketmgr_maxudp isc___socketmgr_maxudp
+#define isc_socket_fdwatchcreate isc__socket_fdwatchcreate
+#define isc_socket_fdwatchpoke isc__socket_fdwatchpoke
+
+#define isc_task_create isc__task_create
+#define isc_task_attach isc__task_attach
+#define isc_task_detach isc__task_detach
+/* #define isc_task_exiting isc__task_exiting XXXMPA */
+#define isc_task_send isc__task_send
+#define isc_task_sendanddetach isc__task_sendanddetach
+#define isc_task_purgerange isc__task_purgerange
+#define isc_task_purge isc__task_purge
+#define isc_task_purgeevent isc__task_purgeevent
+#define isc_task_unsendrange isc__task_unsendrange
+#define isc_task_unsend isc__task_unsend
+#define isc_task_onshutdown isc__task_onshutdown
+#define isc_task_shutdown isc__task_shutdown
+#define isc_task_destroy isc__task_destroy
+#define isc_task_setname isc__task_setname
+#define isc_task_getname isc__task_getname
+#define isc_task_gettag isc__task_gettag
+#define isc_task_getcurrenttime isc__task_getcurrenttime
+#define isc_taskmgr_create isc__taskmgr_create
+#define isc_taskmgr_destroy isc__taskmgr_destroy
+#define isc_task_beginexclusive isc__task_beginexclusive
+#define isc_task_endexclusive isc__task_endexclusive
+
+#define isc_timer_create isc__timer_create
+#define isc_timer_reset isc__timer_reset
+#define isc_timer_gettype isc__timer_gettype
+#define isc_timer_touch isc__timer_touch
+#define isc_timer_attach isc__timer_attach
+#define isc_timer_detach isc__timer_detach
+#define isc_timermgr_create isc__timermgr_create
+#define isc_timermgr_poke isc__timermgr_poke
+#define isc_timermgr_destroy isc__timermgr_destroy
+
+#endif /* BIND9 */
+
+#endif /* ISCAPI_NAMESPACE_H */
diff --git a/lib/isc/include/isc/netaddr.h b/lib/isc/include/isc/netaddr.h
index 52418ecb2ddb..04b7ec182ba3 100644
--- a/lib/isc/include/isc/netaddr.h
+++ b/lib/isc/include/isc/netaddr.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: netaddr.h,v 1.35.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: netaddr.h,v 1.37 2009-01-17 23:47:43 tbox Exp $ */
#ifndef ISC_NETADDR_H
#define ISC_NETADDR_H 1
diff --git a/lib/isc/include/isc/netscope.h b/lib/isc/include/isc/netscope.h
index 7b2c13cff11c..1a50816b9cc2 100644
--- a/lib/isc/include/isc/netscope.h
+++ b/lib/isc/include/isc/netscope.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: netscope.h,v 1.11.332.2 2009-06-25 23:47:24 tbox Exp $ */
+/* $Id: netscope.h,v 1.13 2009-06-25 23:48:02 tbox Exp $ */
#ifndef ISC_NETSCOPE_H
#define ISC_NETSCOPE_H 1
diff --git a/lib/isc/include/isc/platform.h.in b/lib/isc/include/isc/platform.h.in
index 99c887b6c600..2491274acb6e 100644
--- a/lib/isc/include/isc/platform.h.in
+++ b/lib/isc/include/isc/platform.h.in
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: platform.h.in,v 1.48.84.4 2010-06-03 23:47:49 tbox Exp $ */
+/* $Id: platform.h.in,v 1.56 2010-12-18 01:56:23 each Exp $ */
#ifndef ISC_PLATFORM_H
#define ISC_PLATFORM_H 1
@@ -146,6 +146,11 @@
*/
@ISC_PLATFORM_HAVEDEVPOLL@
+/*! \brief
+ * Define if we want to log backtrace
+ */
+@ISC_PLATFORM_USEBACKTRACE@
+
/*
*** Printing.
***/
@@ -215,6 +220,12 @@
@ISC_PLATFORM_GSSAPIHEADER@
/*
+ * Defined to <gssapi_krb5.h> or <gssapi/gssapi_krb5.h> for how to
+ * include the GSSAPI KRB5 header.
+ */
+@ISC_PLATFORM_GSSAPI_KRB5_HEADER@
+
+/*
* Defined to <krb5.h> or <krb5/krb5.h> for how to include
* the KRB5 header.
*/
@@ -290,6 +301,17 @@
*/
@ISC_PLATFORM_HAVESTRINGSH@
+/*
+ * Define if the hash functions must be provided by OpenSSL.
+ */
+@ISC_PLATFORM_OPENSSLHASH@
+
+/*
+ * Defines for the noreturn attribute.
+ */
+@ISC_PLATFORM_NORETURN_PRE@
+@ISC_PLATFORM_NORETURN_POST@
+
/***
*** Windows dll support.
***/
diff --git a/lib/isc/include/isc/portset.h b/lib/isc/include/isc/portset.h
index a257322fd1e3..2e27467fb16c 100644
--- a/lib/isc/include/isc/portset.h
+++ b/lib/isc/include/isc/portset.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: portset.h,v 1.3.90.3 2009-06-25 05:31:51 marka Exp $ */
+/* $Id: portset.h,v 1.6 2009-06-25 05:28:34 marka Exp $ */
/*! \file isc/portset.h
* \brief Transport Protocol Port Manipulation Module
diff --git a/lib/isc/include/isc/radix.h b/lib/isc/include/isc/radix.h
index fa5e29469fa0..ed8aaf2b0efe 100644
--- a/lib/isc/include/isc/radix.h
+++ b/lib/isc/include/isc/radix.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: radix.h,v 1.11.44.2 2008-12-24 23:47:02 tbox Exp $ */
+/* $Id: radix.h,v 1.13 2008-12-01 23:47:45 tbox Exp $ */
/*
* This source was adapted from MRT's RCS Ids:
diff --git a/lib/isc/include/isc/random.h b/lib/isc/include/isc/random.h
index 9743cb46034f..e05b20465445 100644
--- a/lib/isc/include/isc/random.h
+++ b/lib/isc/include/isc/random.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: random.h,v 1.18.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: random.h,v 1.20 2009-01-17 23:47:43 tbox Exp $ */
#ifndef ISC_RANDOM_H
#define ISC_RANDOM_H 1
diff --git a/lib/isc/include/isc/ratelimiter.h b/lib/isc/include/isc/ratelimiter.h
index 7ed312a83447..f8a981969bf0 100644
--- a/lib/isc/include/isc/ratelimiter.h
+++ b/lib/isc/include/isc/ratelimiter.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ratelimiter.h,v 1.21.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: ratelimiter.h,v 1.23 2009-01-18 23:48:14 tbox Exp $ */
#ifndef ISC_RATELIMITER_H
#define ISC_RATELIMITER_H 1
diff --git a/lib/isc/include/isc/refcount.h b/lib/isc/include/isc/refcount.h
index 8e83a13f695d..71f35f148f47 100644
--- a/lib/isc/include/isc/refcount.h
+++ b/lib/isc/include/isc/refcount.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: refcount.h,v 1.15 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: refcount.h,v 1.17 2009-09-29 23:48:04 tbox Exp $ */
#ifndef ISC_REFCOUNT_H
#define ISC_REFCOUNT_H 1
@@ -28,7 +28,7 @@
#include <isc/util.h>
/*! \file isc/refcount.h
- * \brief Implements a locked reference counter.
+ * \brief Implements a locked reference counter.
*
* These functions may actually be
* implemented using macros, and implementations of these macros are below.
@@ -42,7 +42,7 @@ ISC_LANG_BEGINDECLS
* Function prototypes
*/
-/*
+/*
* isc_result_t
* isc_refcount_init(isc_refcount_t *ref, unsigned int n);
*
@@ -103,7 +103,7 @@ typedef struct isc_refcount {
isc_int32_t refs;
} isc_refcount_t;
-#define isc_refcount_destroy(rp) (REQUIRE((rp)->refs == 0))
+#define isc_refcount_destroy(rp) REQUIRE((rp)->refs == 0)
#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
#define isc_refcount_increment0(rp, tp) \
@@ -192,7 +192,7 @@ typedef struct isc_refcount {
int refs;
} isc_refcount_t;
-#define isc_refcount_destroy(rp) (REQUIRE((rp)->refs == 0))
+#define isc_refcount_destroy(rp) REQUIRE((rp)->refs == 0)
#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
#define isc_refcount_increment0(rp, tp) \
diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h
index 804ab5e00152..cc591dc3dac9 100644
--- a/lib/isc/include/isc/result.h
+++ b/lib/isc/include/isc/result.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.h,v 1.71 2008-09-25 04:02:39 tbox Exp $ */
+/* $Id: result.h,v 1.73 2009-09-02 23:48:03 tbox Exp $ */
#ifndef ISC_RESULT_H
#define ISC_RESULT_H 1
@@ -42,6 +42,7 @@
#define ISC_R_EOF 14 /*%< end of file */
#define ISC_R_BOUND 15 /*%< socket already bound */
#define ISC_R_RELOAD 16 /*%< reload */
+#define ISC_R_SUSPEND ISC_R_RELOAD /*%< alias of 'reload' */
#define ISC_R_LOCKBUSY 17 /*%< lock busy */
#define ISC_R_EXISTS 18 /*%< already exists */
#define ISC_R_NOSPACE 19 /*%< ran out of space */
diff --git a/lib/isc/include/isc/resultclass.h b/lib/isc/include/isc/resultclass.h
index 86c55b6772de..84f6c6477342 100644
--- a/lib/isc/include/isc/resultclass.h
+++ b/lib/isc/include/isc/resultclass.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resultclass.h,v 1.18 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: resultclass.h,v 1.20 2009-09-02 23:48:03 tbox Exp $ */
#ifndef ISC_RESULTCLASS_H
#define ISC_RESULTCLASS_H 1
@@ -45,6 +45,7 @@
#define ISC_RESULTCLASS_DNSRCODE ISC_RESULTCLASS_FROMNUM(3)
#define ISC_RESULTCLASS_OMAPI ISC_RESULTCLASS_FROMNUM(4)
#define ISC_RESULTCLASS_ISCCC ISC_RESULTCLASS_FROMNUM(5)
+#define ISC_RESULTCLASS_DHCP ISC_RESULTCLASS_FROMNUM(6)
#endif /* ISC_RESULTCLASS_H */
diff --git a/lib/isc/include/isc/serial.h b/lib/isc/include/isc/serial.h
index 97d5fe1c1c2d..332709dce35e 100644
--- a/lib/isc/include/isc/serial.h
+++ b/lib/isc/include/isc/serial.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: serial.h,v 1.16.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: serial.h,v 1.18 2009-01-18 23:48:14 tbox Exp $ */
#ifndef ISC_SERIAL_H
#define ISC_SERIAL_H 1
diff --git a/lib/isc/include/isc/sha1.h b/lib/isc/include/isc/sha1.h
index 4da682a7aa26..a9d08b9c4958 100644
--- a/lib/isc/include/isc/sha1.h
+++ b/lib/isc/include/isc/sha1.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@
#ifndef ISC_SHA1_H
#define ISC_SHA1_H 1
-/* $Id: sha1.h,v 1.17 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: sha1.h,v 1.19 2009-02-06 23:47:42 tbox Exp $ */
/* $NetBSD: sha1.h,v 1.2 1998/05/29 22:55:44 thorpej Exp $ */
@@ -29,16 +29,25 @@
*/
#include <isc/lang.h>
+#include <isc/platform.h>
#include <isc/types.h>
#define ISC_SHA1_DIGESTLENGTH 20U
#define ISC_SHA1_BLOCK_LENGTH 64U
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/evp.h>
+
+typedef EVP_MD_CTX isc_sha1_t;
+
+#else
+
typedef struct {
isc_uint32_t state[5];
isc_uint32_t count[2];
unsigned char buffer[ISC_SHA1_BLOCK_LENGTH];
} isc_sha1_t;
+#endif
ISC_LANG_BEGINDECLS
diff --git a/lib/isc/include/isc/sha2.h b/lib/isc/include/isc/sha2.h
index c3130a84c64d..8d4ffa648f31 100644
--- a/lib/isc/include/isc/sha2.h
+++ b/lib/isc/include/isc/sha2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sha2.h,v 1.9.332.2 2010-01-15 23:47:34 tbox Exp $ */
+/* $Id: sha2.h,v 1.12 2009-10-22 02:21:31 each Exp $ */
/* $FreeBSD$ */
/* $KAME: sha2.h,v 1.3 2001/03/12 08:27:48 itojun Exp $ */
@@ -58,6 +58,7 @@
#define ISC_SHA2_H
#include <isc/lang.h>
+#include <isc/platform.h>
#include <isc/types.h>
/*** SHA-224/256/384/512 Various Length Definitions ***********************/
@@ -75,10 +76,15 @@
#define ISC_SHA512_DIGESTLENGTH 64U
#define ISC_SHA512_DIGESTSTRINGLENGTH (ISC_SHA512_DIGESTLENGTH * 2 + 1)
+/*** SHA-256/384/512 Context Structures *******************************/
-ISC_LANG_BEGINDECLS
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/evp.h>
-/*** SHA-256/384/512 Context Structures *******************************/
+typedef EVP_MD_CTX isc_sha256_t;
+typedef EVP_MD_CTX isc_sha512_t;
+
+#else
/*
* Keep buffer immediately after bitcount to preserve alignment.
@@ -97,10 +103,13 @@ typedef struct {
isc_uint64_t bitcount[2];
isc_uint8_t buffer[ISC_SHA512_BLOCK_LENGTH];
} isc_sha512_t;
+#endif
typedef isc_sha256_t isc_sha224_t;
typedef isc_sha512_t isc_sha384_t;
+ISC_LANG_BEGINDECLS
+
/*** SHA-224/256/384/512 Function Prototypes ******************************/
void isc_sha224_init (isc_sha224_t *);
diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h
index 758cef70dcab..c83655e7541f 100644
--- a/lib/isc/include/isc/sockaddr.h
+++ b/lib/isc/include/isc/sockaddr.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sockaddr.h,v 1.55.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: sockaddr.h,v 1.57 2009-01-18 23:48:14 tbox Exp $ */
#ifndef ISC_SOCKADDR_H
#define ISC_SOCKADDR_H 1
diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h
index 749ee52b3479..0aa71daa0f36 100644
--- a/lib/isc/include/isc/socket.h
+++ b/lib/isc/include/isc/socket.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket.h,v 1.85.58.3 2009-01-29 22:40:35 jinmei Exp $ */
+/* $Id: socket.h,v 1.94 2009-10-01 01:30:01 sar Exp $ */
#ifndef ISC_SOCKET_H
#define ISC_SOCKET_H 1
@@ -260,6 +260,85 @@ typedef enum {
#define ISC_SOCKFDWATCH_WRITE 0x00000002 /*%< watch for writable */
/*@}*/
+/*% Socket and socket manager methods */
+typedef struct isc_socketmgrmethods {
+ void (*destroy)(isc_socketmgr_t **managerp);
+ isc_result_t (*socketcreate)(isc_socketmgr_t *manager, int pf,
+ isc_sockettype_t type,
+ isc_socket_t **socketp);
+ isc_result_t (*fdwatchcreate)(isc_socketmgr_t *manager, int fd,
+ int flags,
+ isc_sockfdwatch_t callback,
+ void *cbarg, isc_task_t *task,
+ isc_socket_t **socketp);
+} isc_socketmgrmethods_t;
+
+typedef struct isc_socketmethods {
+ void (*attach)(isc_socket_t *socket,
+ isc_socket_t **socketp);
+ void (*detach)(isc_socket_t **socketp);
+ isc_result_t (*bind)(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
+ unsigned int options);
+ isc_result_t (*sendto)(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg, isc_sockaddr_t *address,
+ struct in6_pktinfo *pktinfo);
+ isc_result_t (*connect)(isc_socket_t *sock, isc_sockaddr_t *addr,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+ isc_result_t (*recv)(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg);
+ void (*cancel)(isc_socket_t *sock, isc_task_t *task,
+ unsigned int how);
+ isc_result_t (*getsockname)(isc_socket_t *sock,
+ isc_sockaddr_t *addressp);
+ isc_sockettype_t (*gettype)(isc_socket_t *sock);
+ void (*ipv6only)(isc_socket_t *sock, isc_boolean_t yes);
+ isc_result_t (*fdwatchpoke)(isc_socket_t *sock, int flags);
+} isc_socketmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a socket manager
+ * object implementation's version of an isc_socketmgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. socket implementations
+ * may change the structure. 'magic' must be ISCAPI_SOCKETMGR_MAGIC for any
+ * of the isc_socket_ routines to work. socket implementations must maintain
+ * all socket invariants.
+ * In effect, this definition is used only for non-BIND9 version ("export")
+ * of the library, and the export version does not work for win32. So, to avoid
+ * the definition conflict with win32/socket.c, we enable this definition only
+ * for non-Win32 (i.e. Unix) platforms.
+ */
+#ifndef WIN32
+struct isc_socketmgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_socketmgrmethods_t *methods;
+};
+#endif
+
+#define ISCAPI_SOCKETMGR_MAGIC ISC_MAGIC('A','s','m','g')
+#define ISCAPI_SOCKETMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_SOCKETMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a socket object. The same note as
+ * that for the socketmgr structure applies.
+ */
+#ifndef WIN32
+struct isc_socket {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_socketmethods_t *methods;
+};
+#endif
+
+#define ISCAPI_SOCKET_MAGIC ISC_MAGIC('A','s','c','t')
+#define ISCAPI_SOCKET_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_SOCKET_MAGIC)
+
/***
*** Socket and Socket Manager Functions
***
@@ -307,6 +386,35 @@ isc_socket_fdwatchcreate(isc_socketmgr_t *manager,
*/
isc_result_t
+isc_socket_fdwatchpoke(isc_socket_t *sock,
+ int flags);
+/*%<
+ * Poke a file descriptor watch socket informing the manager that it
+ * should restart watching the socket
+ *
+ * Note:
+ *
+ *\li 'sock' is the socket returned by isc_socket_fdwatchcreate
+ *
+ *\li 'flags' indicates what the manager should watch for on the socket
+ * in addition to what it may already be watching. It can be one or
+ * both of ISC_SOCKFDWATCH_READ and ISC_SOCKFDWATCH_WRITE. To
+ * temporarily disable watching on a socket the value indicating
+ * no more data should be returned from the call back routine.
+ *
+ *\li This function is not available on Windows.
+ *
+ * Requires:
+ *
+ *\li 'sock' is a valid isc socket
+ *
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ */
+
+isc_result_t
isc_socket_create(isc_socketmgr_t *manager,
int pf,
isc_sockettype_t type,
@@ -821,6 +929,10 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
/*@}*/
isc_result_t
+isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_socketmgr_t **managerp);
+
+isc_result_t
isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
isc_result_t
@@ -831,6 +943,8 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
* maximum number of sockets that the created manager should handle.
* isc_socketmgr_create() is equivalent of isc_socketmgr_create2() with
* "maxsocks" being zero.
+ * isc_socketmgr_createinctx() also associates the new manager with the
+ * specified application context.
*
* Notes:
*
@@ -842,6 +956,8 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
*
*\li 'managerp' points to a NULL isc_socketmgr_t.
*
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
* Ensures:
*
*\li '*managerp' is a valid isc_socketmgr_t.
@@ -992,6 +1108,12 @@ isc__socketmgr_setreserved(isc_socketmgr_t *mgr, isc_uint32_t);
* Temporary. For use by named only.
*/
+void
+isc__socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp);
+/*%<
+ * Test interface. Drop UDP packet > 'maxudp'.
+ */
+
#ifdef HAVE_LIBXML2
void
@@ -1002,6 +1124,31 @@ isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer);
#endif /* HAVE_LIBXML2 */
+#ifdef USE_SOCKETIMPREGISTER
+/*%<
+ * See isc_socketmgr_create() above.
+ */
+typedef isc_result_t
+(*isc_socketmgrcreatefunc_t)(isc_mem_t *mctx, isc_socketmgr_t **managerp);
+
+isc_result_t
+isc_socket_register(isc_socketmgrcreatefunc_t createfunc);
+/*%<
+ * Register a new socket I/O implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__socket_register(void);
+/*%<
+ * A short cut function that specifies the socket I/O module in the ISC
+ * library for isc_socket_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_SOCKETIMPREGISTER */
+
ISC_LANG_ENDDECLS
#endif /* ISC_SOCKET_H */
diff --git a/lib/isc/include/isc/stats.h b/lib/isc/include/isc/stats.h
index 1148a1664dc1..226bc081b4f0 100644
--- a/lib/isc/include/isc/stats.h
+++ b/lib/isc/include/isc/stats.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: stats.h,v 1.4.2.2 2009-01-29 23:47:44 tbox Exp $ */
+/* $Id: stats.h,v 1.4 2009-01-29 01:03:56 jinmei Exp $ */
#ifndef ISC_STATS_H
#define ISC_STATS_H 1
diff --git a/lib/isc/include/isc/symtab.h b/lib/isc/include/isc/symtab.h
index a1d7102a9f19..c61d0eaf5044 100644
--- a/lib/isc/include/isc/symtab.h
+++ b/lib/isc/include/isc/symtab.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: symtab.h,v 1.24.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: symtab.h,v 1.26 2009-01-18 23:48:14 tbox Exp $ */
#ifndef ISC_SYMTAB_H
#define ISC_SYMTAB_H 1
diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h
index a8c75699e4f5..a2a1bbea4d52 100644
--- a/lib/isc/include/isc/task.h
+++ b/lib/isc/include/isc/task.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: task.h,v 1.61.332.4 2010-12-03 23:45:47 tbox Exp $ */
+/* $Id: task.h,v 1.69.14.1.2.1 2011-06-02 23:47:36 tbox Exp $ */
#ifndef ISC_TASK_H
#define ISC_TASK_H 1
@@ -96,6 +96,72 @@
ISC_LANG_BEGINDECLS
+/***
+ *** Types
+ ***/
+
+/*% Task and task manager methods */
+typedef struct isc_taskmgrmethods {
+ void (*destroy)(isc_taskmgr_t **managerp);
+ isc_result_t (*taskcreate)(isc_taskmgr_t *manager,
+ unsigned int quantum,
+ isc_task_t **taskp);
+} isc_taskmgrmethods_t;
+
+typedef struct isc_taskmethods {
+ void (*attach)(isc_task_t *source, isc_task_t **targetp);
+ void (*detach)(isc_task_t **taskp);
+ void (*destroy)(isc_task_t **taskp);
+ void (*send)(isc_task_t *task, isc_event_t **eventp);
+ void (*sendanddetach)(isc_task_t **taskp, isc_event_t **eventp);
+ unsigned int (*unsend)(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events);
+ isc_result_t (*onshutdown)(isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+ void (*shutdown)(isc_task_t *task);
+ void (*setname)(isc_task_t *task, const char *name, void *tag);
+ unsigned int (*purgeevents)(isc_task_t *task, void *sender,
+ isc_eventtype_t type, void *tag);
+ unsigned int (*purgerange)(isc_task_t *task, void *sender,
+ isc_eventtype_t first, isc_eventtype_t last,
+ void *tag);
+ isc_result_t (*beginexclusive)(isc_task_t *task);
+ void (*endexclusive)(isc_task_t *task);
+} isc_taskmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a task manager
+ * object implementation's version of an isc_taskmgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. task implementations
+ * may change the structure. 'magic' must be ISCAPI_TASKMGR_MAGIC for any
+ * of the isc_task_ routines to work. task implementations must maintain
+ * all task invariants.
+ */
+struct isc_taskmgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_taskmgrmethods_t *methods;
+};
+
+#define ISCAPI_TASKMGR_MAGIC ISC_MAGIC('A','t','m','g')
+#define ISCAPI_TASKMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_TASKMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a task object. The same note as
+ * that for the taskmgr structure applies.
+ */
+struct isc_task {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_taskmethods_t *methods;
+};
+
+#define ISCAPI_TASK_MAGIC ISC_MAGIC('A','t','s','t')
+#define ISCAPI_TASK_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_TASK_MAGIC)
+
isc_result_t
isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
isc_task_t **taskp);
@@ -550,10 +616,15 @@ isc_task_exiting(isc_task_t *t);
*****/
isc_result_t
+isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ unsigned int workers, unsigned int default_quantum,
+ isc_taskmgr_t **managerp);
+isc_result_t
isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
unsigned int default_quantum, isc_taskmgr_t **managerp);
/*%<
- * Create a new task manager.
+ * Create a new task manager. isc_taskmgr_createinctx() also associates
+ * the new manager with the specified application context.
*
* Notes:
*
@@ -575,6 +646,8 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
*
*\li managerp != NULL && *managerp == NULL
*
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
* Ensures:
*
*\li On success, '*managerp' will be attached to the newly created task
@@ -584,8 +657,10 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
*
*\li #ISC_R_SUCCESS
*\li #ISC_R_NOMEMORY
- *\li #ISC_R_NOTHREADS No threads could be created.
+ *\li #ISC_R_NOTHREADS No threads could be created.
*\li #ISC_R_UNEXPECTED An unexpected error occurred.
+ *\li #ISC_R_SHUTTINGDOWN The non-threaded, shared, task
+ * manager shutting down.
*/
void
@@ -629,6 +704,31 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer);
#endif
+/*%<
+ * See isc_taskmgr_create() above.
+ */
+typedef isc_result_t
+(*isc_taskmgrcreatefunc_t)(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum,
+ isc_taskmgr_t **managerp);
+
+isc_result_t
+isc_task_register(isc_taskmgrcreatefunc_t createfunc);
+/*%<
+ * Register a new task management implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__task_register(void);
+/*%<
+ * A short cut function that specifies the task management module in the ISC
+ * library for isc_task_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+
ISC_LANG_ENDDECLS
#endif /* ISC_TASK_H */
diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h
index 052e25bc2bdf..a54e73b7b566 100644
--- a/lib/isc/include/isc/timer.h
+++ b/lib/isc/include/isc/timer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: timer.h,v 1.40 2008-06-23 23:47:11 tbox Exp $ */
+/* $Id: timer.h,v 1.43 2009-09-02 23:48:03 tbox Exp $ */
#ifndef ISC_TIMER_H
#define ISC_TIMER_H 1
@@ -103,6 +103,61 @@ typedef struct isc_timerevent {
#define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3)
#define ISC_TIMEREVENT_LASTEVENT (ISC_EVENTCLASS_TIMER + 65535)
+/*% Timer and timer manager methods */
+typedef struct {
+ void (*destroy)(isc_timermgr_t **managerp);
+ isc_result_t (*timercreate)(isc_timermgr_t *manager,
+ isc_timertype_t type,
+ isc_time_t *expires,
+ isc_interval_t *interval,
+ isc_task_t *task,
+ isc_taskaction_t action,
+ const void *arg,
+ isc_timer_t **timerp);
+} isc_timermgrmethods_t;
+
+typedef struct {
+ void (*attach)(isc_timer_t *timer, isc_timer_t **timerp);
+ void (*detach)(isc_timer_t **timerp);
+ isc_result_t (*reset)(isc_timer_t *timer, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_boolean_t purge);
+ isc_result_t (*touch)(isc_timer_t *timer);
+} isc_timermethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a timer manager
+ * object implementation's version of an isc_timermgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. timer implementations
+ * may change the structure. 'magic' must be ISCAPI_TIMERMGR_MAGIC for any
+ * of the isc_timer_ routines to work. timer implementations must maintain
+ * all timer invariants.
+ */
+struct isc_timermgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_timermgrmethods_t *methods;
+};
+
+#define ISCAPI_TIMERMGR_MAGIC ISC_MAGIC('A','t','m','g')
+#define ISCAPI_TIMERMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_TIMERMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a timer object. The same note as
+ * that for the timermgr structure applies.
+ */
+struct isc_timer {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_timermethods_t *methods;
+};
+
+#define ISCAPI_TIMER_MAGIC ISC_MAGIC('A','t','m','r')
+#define ISCAPI_TIMER_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_TIMER_MAGIC)
+
/***
*** Timer and Timer Manager Functions
***
@@ -289,9 +344,14 @@ isc_timer_gettype(isc_timer_t *timer);
*/
isc_result_t
+isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_timermgr_t **managerp);
+
+isc_result_t
isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
/*%<
- * Create a timer manager.
+ * Create a timer manager. isc_timermgr_createinctx() also associates
+ * the new manager with the specified application context.
*
* Notes:
*
@@ -303,6 +363,8 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
*
*\li 'managerp' points to a NULL isc_timermgr_t.
*
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
* Ensures:
*
*\li '*managerp' is a valid isc_timermgr_t.
@@ -339,6 +401,31 @@ isc_timermgr_destroy(isc_timermgr_t **managerp);
void isc_timermgr_poke(isc_timermgr_t *m);
+#ifdef USE_TIMERIMPREGISTER
+/*%<
+ * See isc_timermgr_create() above.
+ */
+typedef isc_result_t
+(*isc_timermgrcreatefunc_t)(isc_mem_t *mctx, isc_timermgr_t **managerp);
+
+isc_result_t
+isc__timer_register(void);
+/*%<
+ * Register a new timer management implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc_timer_register(isc_timermgrcreatefunc_t createfunc);
+/*%<
+ * A short cut function that specifies the timer management module in the ISC
+ * library for isc_timer_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_TIMERIMPREGISTER */
+
ISC_LANG_ENDDECLS
#endif /* ISC_TIMER_H */
diff --git a/lib/isc/include/isc/types.h b/lib/isc/include/isc/types.h
index 01362b8550e5..10da62bfd2ae 100644
--- a/lib/isc/include/isc/types.h
+++ b/lib/isc/include/isc/types.h
@@ -15,11 +15,14 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.46.84.2 2009-01-29 23:47:44 tbox Exp $ */
+/* $Id: types.h,v 1.52 2009-12-05 23:31:41 each Exp $ */
#ifndef ISC_TYPES_H
#define ISC_TYPES_H 1
+#include <isc/bind9.h>
+#include <isc/namespace.h>
+
/*! \file isc/types.h
* \brief
* OS-specific types, from the OS-specific include directories.
@@ -40,6 +43,8 @@
/* Core Types. Alphabetized by defined type. */
+typedef struct isc_appctx isc_appctx_t; /*%< Application context */
+typedef struct isc_backtrace_symmap isc_backtrace_symmap_t; /*%< Symbol Table Entry */
typedef struct isc_bitstring isc_bitstring_t; /*%< Bitstring */
typedef struct isc_buffer isc_buffer_t; /*%< Buffer */
typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */
@@ -94,7 +99,7 @@ typedef struct isc_timer isc_timer_t; /*%< Timer */
typedef struct isc_timermgr isc_timermgr_t; /*%< Timer Manager */
typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *);
-typedef int (*isc_sockfdwatch_t)(isc_task_t *, isc_socket_t *, void *);
+typedef int (*isc_sockfdwatch_t)(isc_task_t *, isc_socket_t *, void *, int);
/* The following cannot be listed alphabetically due to forward reference */
typedef isc_result_t (isc_httpdaction_t)(const char *url,
diff --git a/lib/isc/include/isc/util.h b/lib/isc/include/isc/util.h
index 8ccad8d9c0cf..11d0044b8a32 100644
--- a/lib/isc/include/isc/util.h
+++ b/lib/isc/include/isc/util.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: util.h,v 1.30.332.2 2010-01-11 23:47:22 tbox Exp $ */
+/* $Id: util.h,v 1.32 2010-01-11 23:48:37 tbox Exp $ */
#ifndef ISC_UTIL_H
#define ISC_UTIL_H 1
diff --git a/lib/isc/inet_aton.c b/lib/isc/inet_aton.c
index 3c25ca373c3a..9e35a366a479 100644
--- a/lib/isc/inet_aton.c
+++ b/lib/isc/inet_aton.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -71,7 +71,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
-static char rcsid[] = "$Id: inet_aton.c,v 1.21.332.2 2009-03-05 23:47:03 tbox Exp $";
+static char rcsid[] = "$Id: inet_aton.c,v 1.23 2008-12-01 23:47:45 tbox Exp $";
#endif /* LIBC_SCCS and not lint */
#include <config.h>
diff --git a/lib/isc/inet_ntop.c b/lib/isc/inet_ntop.c
index 22930f3eb7ab..581ebe8348ed 100644
--- a/lib/isc/inet_ntop.c
+++ b/lib/isc/inet_ntop.c
@@ -19,7 +19,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char rcsid[] =
- "$Id: inet_ntop.c,v 1.19.332.2 2009-07-18 23:47:25 tbox Exp $";
+ "$Id: inet_ntop.c,v 1.21 2009-07-17 23:47:41 tbox Exp $";
#endif /* LIBC_SCCS and not lint */
#include <config.h>
diff --git a/lib/isc/iterated_hash.c b/lib/isc/iterated_hash.c
index ebc50763e26b..71850756c39c 100644
--- a/lib/isc/iterated_hash.c
+++ b/lib/isc/iterated_hash.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: iterated_hash.c,v 1.4.48.2 2009-02-18 23:47:12 tbox Exp $ */
+/* $Id: iterated_hash.c,v 1.6 2009-02-18 23:47:48 tbox Exp $ */
#include "config.h"
diff --git a/lib/isc/lib.c b/lib/isc/lib.c
index 99b0178caae0..1b6ccc0589b2 100644
--- a/lib/isc/lib.c
+++ b/lib/isc/lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lib.c,v 1.14 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: lib.c,v 1.16 2009-09-02 23:48:02 tbox Exp $ */
/*! \file */
@@ -24,9 +24,15 @@
#include <stdio.h>
#include <stdlib.h>
-#include <isc/once.h>
-#include <isc/msgs.h>
+#include <isc/app.h>
#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/once.h>
+#include <isc/socket.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
/***
*** Globals
@@ -41,7 +47,6 @@ LIBISC_EXTERNAL_DATA isc_msgcat_t * isc_msgcat = NULL;
static isc_once_t msgcat_once = ISC_ONCE_INIT;
-
/***
*** Functions
***/
@@ -77,3 +82,22 @@ isc_lib_initmsgcat(void) {
abort();
}
}
+
+#ifndef BIND9
+static isc_once_t register_once = ISC_ONCE_INIT;
+
+static void
+do_register(void) {
+ RUNTIME_CHECK(isc__mem_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__app_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__task_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__socket_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__timer_register() == ISC_R_SUCCESS);
+}
+
+void
+isc_lib_register() {
+ RUNTIME_CHECK(isc_once_do(&register_once, do_register)
+ == ISC_R_SUCCESS);
+}
+#endif
diff --git a/lib/isc/log.c b/lib/isc/log.c
index 121bd25b2567..7ef66922f199 100644
--- a/lib/isc/log.c
+++ b/lib/isc/log.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: log.c,v 1.94.332.5 2009-02-16 02:04:05 marka Exp $ */
+/* $Id: log.c,v 1.99 2009-02-16 02:01:16 marka Exp $ */
/*! \file
* \author Principal Authors: DCL */
diff --git a/lib/isc/md5.c b/lib/isc/md5.c
index b9ec42c26637..b778177171c4 100644
--- a/lib/isc/md5.c
+++ b/lib/isc/md5.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: md5.c,v 1.14 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: md5.c,v 1.16 2009-02-06 23:47:42 tbox Exp $ */
/*! \file
* This code implements the MD5 message-digest algorithm.
@@ -38,10 +38,35 @@
#include <isc/assertions.h>
#include <isc/md5.h>
+#include <isc/platform.h>
#include <isc/string.h>
#include <isc/types.h>
#include <isc/util.h>
+#ifdef ISC_PLATFORM_OPENSSLHASH
+
+void
+isc_md5_init(isc_md5_t *ctx) {
+ EVP_DigestInit(ctx, EVP_md5());
+}
+
+void
+isc_md5_invalidate(isc_md5_t *ctx) {
+ EVP_MD_CTX_cleanup(ctx);
+}
+
+void
+isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
+ EVP_DigestUpdate(ctx, (const void *) buf, (size_t) len);
+}
+
+void
+isc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
+ EVP_DigestFinal(ctx, digest, NULL);
+}
+
+#else
+
static void
byteSwap(isc_uint32_t *buf, unsigned words)
{
@@ -249,3 +274,4 @@ isc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(isc_md5_t)); /* In case it's sensitive */
}
+#endif
diff --git a/lib/isc/mem.c b/lib/isc/mem.c
index aeacfc0260ef..831156939010 100644
--- a/lib/isc/mem.c
+++ b/lib/isc/mem.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mem.c,v 1.145.120.9 2010-08-11 23:45:49 tbox Exp $ */
+/* $Id: mem.c,v 1.160 2010-12-08 02:46:16 marka Exp $ */
/*! \file */
@@ -60,6 +60,9 @@ LIBISC_EXTERNAL_DATA unsigned int isc_mem_debugging = ISC_MEM_DEBUGGING;
/*
* Types.
*/
+typedef struct isc__mem isc__mem_t;
+typedef struct isc__mempool isc__mempool_t;
+
#if ISC_MEM_TRACKLINES
typedef struct debuglink debuglink_t;
struct debuglink {
@@ -89,7 +92,7 @@ typedef struct {
*/
union {
size_t size;
- isc_mem_t *ctx;
+ isc__mem_t *ctx;
char bytes[ALIGNMENT_SIZE];
} u;
} size_info;
@@ -110,7 +113,7 @@ typedef ISC_LIST(debuglink_t) debuglist_t;
/* List of all active memory contexts. */
-static ISC_LIST(isc_mem_t) contexts;
+static ISC_LIST(isc__mem_t) contexts;
static isc_once_t once = ISC_ONCE_INIT;
static isc_mutex_t lock;
@@ -120,8 +123,8 @@ static isc_mutex_t lock;
*/
static isc_uint64_t totallost;
-struct isc_mem {
- unsigned int magic;
+struct isc__mem {
+ isc_mem_t common;
isc_ondestroy_t ondestroy;
unsigned int flags;
isc_mutex_t lock;
@@ -144,7 +147,7 @@ struct isc_mem {
isc_boolean_t is_overmem;
isc_mem_water_t water;
void * water_arg;
- ISC_LIST(isc_mempool_t) pools;
+ ISC_LIST(isc__mempool_t) pools;
unsigned int poolcnt;
/* ISC_MEMFLAG_INTERNAL */
@@ -163,19 +166,19 @@ struct isc_mem {
#endif
unsigned int memalloc_failures;
- ISC_LINK(isc_mem_t) link;
+ ISC_LINK(isc__mem_t) link;
};
#define MEMPOOL_MAGIC ISC_MAGIC('M', 'E', 'M', 'p')
#define VALID_MEMPOOL(c) ISC_MAGIC_VALID(c, MEMPOOL_MAGIC)
-struct isc_mempool {
+struct isc__mempool {
/* always unlocked */
- unsigned int magic; /*%< magic number */
+ isc_mempool_t common; /*%< common header of mempool's */
isc_mutex_t *lock; /*%< optional lock */
- isc_mem_t *mctx; /*%< our memory context */
+ isc__mem_t *mctx; /*%< our memory context */
/*%< locked via the memory context's lock */
- ISC_LINK(isc_mempool_t) link; /*%< next pool in this mem context */
+ ISC_LINK(isc__mempool_t) link; /*%< next pool in this mem context */
/*%< optionally locked from here down */
element *items; /*%< low water item list */
size_t size; /*%< size of each item on this pool */
@@ -210,13 +213,187 @@ struct isc_mempool {
#define DELETE_TRACE(a, b, c, d, e) delete_trace_entry(a, b, c, d, e)
static void
-print_active(isc_mem_t *ctx, FILE *out);
+print_active(isc__mem_t *ctx, FILE *out);
+
+/*%
+ * The following can be either static or public, depending on build environment.
+ */
+
+#ifdef BIND9
+#define ISC_MEMFUNC_SCOPE
+#else
+#define ISC_MEMFUNC_SCOPE static
+#endif
+
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_createx(size_t init_max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
+ isc_mem_t **ctxp);
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_createx2(size_t init_max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
+ isc_mem_t **ctxp, unsigned int flags);
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_create(size_t init_max_size, size_t target_size, isc_mem_t **ctxp);
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_create2(size_t init_max_size, size_t target_size,
+ isc_mem_t **ctxp, unsigned int flags);
+ISC_MEMFUNC_SCOPE void
+isc__mem_attach(isc_mem_t *source, isc_mem_t **targetp);
+ISC_MEMFUNC_SCOPE void
+isc__mem_detach(isc_mem_t **ctxp);
+ISC_MEMFUNC_SCOPE void
+isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG);
+ISC_MEMFUNC_SCOPE void
+isc__mem_destroy(isc_mem_t **ctxp);
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event);
+ISC_MEMFUNC_SCOPE void *
+isc___mem_get(isc_mem_t *ctx, size_t size FLARG);
+ISC_MEMFUNC_SCOPE void
+isc___mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG);
+ISC_MEMFUNC_SCOPE void
+isc__mem_stats(isc_mem_t *ctx, FILE *out);
+ISC_MEMFUNC_SCOPE void *
+isc___mem_allocate(isc_mem_t *ctx, size_t size FLARG);
+ISC_MEMFUNC_SCOPE void *
+isc___mem_reallocate(isc_mem_t *ctx, void *ptr, size_t size FLARG);
+ISC_MEMFUNC_SCOPE void
+isc___mem_free(isc_mem_t *ctx, void *ptr FLARG);
+ISC_MEMFUNC_SCOPE char *
+isc___mem_strdup(isc_mem_t *mctx, const char *s FLARG);
+ISC_MEMFUNC_SCOPE void
+isc__mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag);
+ISC_MEMFUNC_SCOPE void
+isc__mem_setquota(isc_mem_t *ctx, size_t quota);
+ISC_MEMFUNC_SCOPE size_t
+isc__mem_getquota(isc_mem_t *ctx);
+ISC_MEMFUNC_SCOPE size_t
+isc__mem_inuse(isc_mem_t *ctx);
+ISC_MEMFUNC_SCOPE isc_boolean_t
+isc__mem_isovermem(isc_mem_t *ctx);
+ISC_MEMFUNC_SCOPE void
+isc__mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
+ size_t hiwater, size_t lowater);
+ISC_MEMFUNC_SCOPE void
+isc__mem_waterack(isc_mem_t *ctx0, int flag);
+ISC_MEMFUNC_SCOPE void
+isc__mem_setname(isc_mem_t *ctx, const char *name, void *tag);
+ISC_MEMFUNC_SCOPE const char *
+isc__mem_getname(isc_mem_t *ctx);
+ISC_MEMFUNC_SCOPE void *
+isc__mem_gettag(isc_mem_t *ctx);
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setname(isc_mempool_t *mpctx, const char *name);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_destroy(isc_mempool_t **mpctxp);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock);
+ISC_MEMFUNC_SCOPE void *
+isc___mempool_get(isc_mempool_t *mpctx FLARG);
+ISC_MEMFUNC_SCOPE void
+isc___mempool_put(isc_mempool_t *mpctx, void *mem FLARG);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfreemax(isc_mempool_t *mpctx);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfreecount(isc_mempool_t *mpctx);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getmaxalloc(isc_mempool_t *mpctx);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getallocated(isc_mempool_t *mpctx);
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfillcount(isc_mempool_t *mpctx);
+#ifdef BIND9
+ISC_MEMFUNC_SCOPE void
+isc__mem_printactive(isc_mem_t *ctx0, FILE *file);
+ISC_MEMFUNC_SCOPE void
+isc__mem_printallactive(FILE *file);
+ISC_MEMFUNC_SCOPE void
+isc__mem_checkdestroyed(FILE *file);
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mem_references(isc_mem_t *ctx0);
+#endif
+
+static struct isc__memmethods {
+ isc_memmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *createx, *create, *create2, *ondestroy, *stats,
+ *setquota, *getquota, *setname, *getname, *gettag;
+#endif
+} memmethods = {
+ {
+ isc__mem_attach,
+ isc__mem_detach,
+ isc__mem_destroy,
+ isc___mem_get,
+ isc___mem_put,
+ isc___mem_putanddetach,
+ isc___mem_allocate,
+ isc___mem_reallocate,
+ isc___mem_strdup,
+ isc___mem_free,
+ isc__mem_setdestroycheck,
+ isc__mem_setwater,
+ isc__mem_waterack,
+ isc__mem_inuse,
+ isc__mem_isovermem,
+ isc__mempool_create
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__mem_createx, (void *)isc__mem_create,
+ (void *)isc__mem_create2, (void *)isc__mem_ondestroy,
+ (void *)isc__mem_stats, (void *)isc__mem_setquota,
+ (void *)isc__mem_getquota, (void *)isc__mem_setname,
+ (void *)isc__mem_getname, (void *)isc__mem_gettag
+#endif
+};
+
+static struct isc__mempoolmethods {
+ isc_mempoolmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *getfreemax, *getfreecount, *getmaxalloc, *getfillcount;
+#endif
+} mempoolmethods = {
+ {
+ isc__mempool_destroy,
+ isc___mempool_get,
+ isc___mempool_put,
+ isc__mempool_getallocated,
+ isc__mempool_setmaxalloc,
+ isc__mempool_setfreemax,
+ isc__mempool_setname,
+ isc__mempool_associatelock,
+ isc__mempool_setfillcount
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__mempool_getfreemax, (void *)isc__mempool_getfreecount,
+ (void *)isc__mempool_getmaxalloc, (void *)isc__mempool_getfillcount
+#endif
+};
/*!
* mctx must be locked.
*/
static inline void
-add_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size
+add_trace_entry(isc__mem_t *mctx, const void *ptr, unsigned int size
FLARG)
{
debuglink_t *dl;
@@ -276,7 +453,7 @@ add_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size
}
static inline void
-delete_trace_entry(isc_mem_t *mctx, const void *ptr, unsigned int size,
+delete_trace_entry(isc__mem_t *mctx, const void *ptr, unsigned int size,
const char *file, unsigned int line)
{
debuglink_t *dl;
@@ -347,7 +524,7 @@ quantize(size_t size) {
}
static inline isc_boolean_t
-more_basic_blocks(isc_mem_t *ctx) {
+more_basic_blocks(isc__mem_t *ctx) {
void *new;
unsigned char *curr, *next;
unsigned char *first, *last;
@@ -417,7 +594,7 @@ more_basic_blocks(isc_mem_t *ctx) {
}
static inline isc_boolean_t
-more_frags(isc_mem_t *ctx, size_t new_size) {
+more_frags(isc__mem_t *ctx, size_t new_size) {
int i, frags;
size_t total_size;
void *new;
@@ -479,7 +656,7 @@ more_frags(isc_mem_t *ctx, size_t new_size) {
}
static inline void *
-mem_getunlocked(isc_mem_t *ctx, size_t size) {
+mem_getunlocked(isc__mem_t *ctx, size_t size) {
size_t new_size = quantize(size);
void *ret;
@@ -560,7 +737,7 @@ check_overrun(void *mem, size_t size, size_t new_size) {
#endif
static inline void
-mem_putunlocked(isc_mem_t *ctx, void *mem, size_t size) {
+mem_putunlocked(isc__mem_t *ctx, void *mem, size_t size) {
size_t new_size = quantize(size);
if (size == ctx->max_size || new_size >= ctx->max_size) {
@@ -608,7 +785,7 @@ mem_putunlocked(isc_mem_t *ctx, void *mem, size_t size) {
* Perform a malloc, doing memory filling and overrun detection as necessary.
*/
static inline void *
-mem_get(isc_mem_t *ctx, size_t size) {
+mem_get(isc__mem_t *ctx, size_t size) {
char *ret;
#if ISC_MEM_CHECKOVERRUN
@@ -636,7 +813,7 @@ mem_get(isc_mem_t *ctx, size_t size) {
* Perform a free, doing memory filling and overrun detection as necessary.
*/
static inline void
-mem_put(isc_mem_t *ctx, void *mem, size_t size) {
+mem_put(isc__mem_t *ctx, void *mem, size_t size) {
#if ISC_MEM_CHECKOVERRUN
INSIST(((unsigned char *)mem)[size] == 0xbe);
#endif
@@ -652,7 +829,7 @@ mem_put(isc_mem_t *ctx, void *mem, size_t size) {
* Update internal counters after a memory get.
*/
static inline void
-mem_getstats(isc_mem_t *ctx, size_t size) {
+mem_getstats(isc__mem_t *ctx, size_t size) {
ctx->total += size;
ctx->inuse += size;
@@ -669,7 +846,7 @@ mem_getstats(isc_mem_t *ctx, size_t size) {
* Update internal counters after a memory put.
*/
static inline void
-mem_putstats(isc_mem_t *ctx, void *ptr, size_t size) {
+mem_putstats(isc__mem_t *ctx, void *ptr, size_t size) {
UNUSED(ptr);
INSIST(ctx->inuse >= size);
@@ -713,22 +890,22 @@ initialize_action(void) {
* Public.
*/
-isc_result_t
-isc_mem_createx(size_t init_max_size, size_t target_size,
- isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
- isc_mem_t **ctxp)
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_createx(size_t init_max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
+ isc_mem_t **ctxp)
{
- return (isc_mem_createx2(init_max_size, target_size, memalloc, memfree,
- arg, ctxp, ISC_MEMFLAG_DEFAULT));
+ return (isc__mem_createx2(init_max_size, target_size, memalloc, memfree,
+ arg, ctxp, ISC_MEMFLAG_DEFAULT));
}
-isc_result_t
-isc_mem_createx2(size_t init_max_size, size_t target_size,
- isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
- isc_mem_t **ctxp, unsigned int flags)
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_createx2(size_t init_max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
+ isc_mem_t **ctxp, unsigned int flags)
{
- isc_mem_t *ctx;
+ isc__mem_t *ctx;
isc_result_t result;
REQUIRE(ctxp != NULL && *ctxp == NULL);
@@ -769,7 +946,9 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
ctx->is_overmem = ISC_FALSE;
ctx->water = NULL;
ctx->water_arg = NULL;
- ctx->magic = MEM_MAGIC;
+ ctx->common.impmagic = MEM_MAGIC;
+ ctx->common.magic = ISCAPI_MCTX_MAGIC;
+ ctx->common.methods = (isc_memmethods_t *)&memmethods;
isc_ondestroy_init(&ctx->ondestroy);
ctx->memalloc = memalloc;
ctx->memfree = memfree;
@@ -834,7 +1013,7 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
ISC_LIST_INITANDAPPEND(contexts, ctx, link);
UNLOCK(&lock);
- *ctxp = ctx;
+ *ctxp = (isc_mem_t *)ctx;
return (ISC_R_SUCCESS);
error:
@@ -855,26 +1034,24 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
return (result);
}
-isc_result_t
-isc_mem_create(size_t init_max_size, size_t target_size,
- isc_mem_t **ctxp)
-{
- return (isc_mem_createx2(init_max_size, target_size,
- default_memalloc, default_memfree, NULL,
- ctxp, ISC_MEMFLAG_DEFAULT));
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_create(size_t init_max_size, size_t target_size, isc_mem_t **ctxp) {
+ return (isc__mem_createx2(init_max_size, target_size,
+ default_memalloc, default_memfree, NULL,
+ ctxp, ISC_MEMFLAG_DEFAULT));
}
-isc_result_t
-isc_mem_create2(size_t init_max_size, size_t target_size,
- isc_mem_t **ctxp, unsigned int flags)
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_create2(size_t init_max_size, size_t target_size,
+ isc_mem_t **ctxp, unsigned int flags)
{
- return (isc_mem_createx2(init_max_size, target_size,
- default_memalloc, default_memfree, NULL,
- ctxp, flags));
+ return (isc__mem_createx2(init_max_size, target_size,
+ default_memalloc, default_memfree, NULL,
+ ctxp, flags));
}
static void
-destroy(isc_mem_t *ctx) {
+destroy(isc__mem_t *ctx) {
unsigned int i;
isc_ondestroy_t ondest;
@@ -883,7 +1060,8 @@ destroy(isc_mem_t *ctx) {
totallost += ctx->inuse;
UNLOCK(&lock);
- ctx->magic = 0;
+ ctx->common.impmagic = 0;
+ ctx->common.magic = 0;
INSIST(ISC_LIST_EMPTY(ctx->pools));
@@ -941,8 +1119,10 @@ destroy(isc_mem_t *ctx) {
isc_ondestroy_notify(&ondest, ctx);
}
-void
-isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_attach(isc_mem_t *source0, isc_mem_t **targetp) {
+ isc__mem_t *source = (isc__mem_t *)source0;
+
REQUIRE(VALID_CONTEXT(source));
REQUIRE(targetp != NULL && *targetp == NULL);
@@ -950,16 +1130,16 @@ isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {
source->references++;
MCTXUNLOCK(source, &source->lock);
- *targetp = source;
+ *targetp = (isc_mem_t *)source;
}
-void
-isc_mem_detach(isc_mem_t **ctxp) {
- isc_mem_t *ctx;
+ISC_MEMFUNC_SCOPE void
+isc__mem_detach(isc_mem_t **ctxp) {
+ isc__mem_t *ctx;
isc_boolean_t want_destroy = ISC_FALSE;
REQUIRE(ctxp != NULL);
- ctx = *ctxp;
+ ctx = (isc__mem_t *)*ctxp;
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -985,15 +1165,15 @@ isc_mem_detach(isc_mem_t **ctxp) {
* isc_mem_detach(&mctx);
*/
-void
-isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
- isc_mem_t *ctx;
+ISC_MEMFUNC_SCOPE void
+isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
+ isc__mem_t *ctx;
isc_boolean_t want_destroy = ISC_FALSE;
size_info *si;
size_t oldsize;
REQUIRE(ctxp != NULL);
- ctx = *ctxp;
+ ctx = (isc__mem_t *)*ctxp;
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(ptr != NULL);
@@ -1011,7 +1191,7 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
oldsize -= ALIGNMENT_SIZE;
INSIST(oldsize == size);
}
- isc__mem_free(ctx, ptr FLARG_PASS);
+ isc_mem_free((isc_mem_t *)ctx, ptr);
MCTXLOCK(ctx, &ctx->lock);
ctx->references--;
@@ -1045,9 +1225,9 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
destroy(ctx);
}
-void
-isc_mem_destroy(isc_mem_t **ctxp) {
- isc_mem_t *ctx;
+ISC_MEMFUNC_SCOPE void
+isc__mem_destroy(isc_mem_t **ctxp) {
+ isc__mem_t *ctx;
/*
* This routine provides legacy support for callers who use mctxs
@@ -1055,7 +1235,7 @@ isc_mem_destroy(isc_mem_t **ctxp) {
*/
REQUIRE(ctxp != NULL);
- ctx = *ctxp;
+ ctx = (isc__mem_t *)*ctxp;
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -1072,8 +1252,9 @@ isc_mem_destroy(isc_mem_t **ctxp) {
*ctxp = NULL;
}
-isc_result_t
-isc_mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event) {
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mem_ondestroy(isc_mem_t *ctx0, isc_task_t *task, isc_event_t **event) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
isc_result_t res;
MCTXLOCK(ctx, &ctx->lock);
@@ -1083,16 +1264,16 @@ isc_mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event) {
return (res);
}
-
-void *
-isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
+ISC_MEMFUNC_SCOPE void *
+isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
void *ptr;
isc_boolean_t call_water = ISC_FALSE;
REQUIRE(VALID_CONTEXT(ctx));
if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0)
- return (isc__mem_allocate(ctx, size FLARG_PASS));
+ return (isc__mem_allocate(ctx0, size FLARG_PASS));
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
MCTXLOCK(ctx, &ctx->lock);
@@ -1128,9 +1309,9 @@ isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
return (ptr);
}
-void
-isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
-{
+ISC_MEMFUNC_SCOPE void
+isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
isc_boolean_t call_water = ISC_FALSE;
size_info *si;
size_t oldsize;
@@ -1146,7 +1327,7 @@ isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
oldsize -= ALIGNMENT_SIZE;
INSIST(oldsize == size);
}
- isc__mem_free(ctx, ptr FLARG_PASS);
+ isc_mem_free((isc_mem_t *)ctx, ptr);
return;
}
@@ -1181,8 +1362,10 @@ isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
}
-void
-isc_mem_waterack(isc_mem_t *ctx, int flag) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_waterack(isc_mem_t *ctx0, int flag) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -1195,7 +1378,7 @@ isc_mem_waterack(isc_mem_t *ctx, int flag) {
#if ISC_MEM_TRACKLINES
static void
-print_active(isc_mem_t *mctx, FILE *out) {
+print_active(isc__mem_t *mctx, FILE *out) {
if (mctx->debuglist != NULL) {
debuglink_t *dl;
unsigned int i, j;
@@ -1237,11 +1420,12 @@ print_active(isc_mem_t *mctx, FILE *out) {
/*
* Print the stats[] on the stream "out" with suitable formatting.
*/
-void
-isc_mem_stats(isc_mem_t *ctx, FILE *out) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_stats(isc_mem_t *ctx0, FILE *out) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_t i;
const struct stats *s;
- const isc_mempool_t *pool;
+ const isc__mempool_t *pool;
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -1314,7 +1498,8 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
*/
static void *
-isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) {
+isc__mem_allocateunlocked(isc_mem_t *ctx0, size_t size) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_info *si;
size += ALIGNMENT_SIZE;
@@ -1336,8 +1521,9 @@ isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) {
return (&si[1]);
}
-void *
-isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
+ISC_MEMFUNC_SCOPE void *
+isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_info *si;
isc_boolean_t call_water = ISC_FALSE;
@@ -1345,9 +1531,9 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
MCTXLOCK(ctx, &ctx->lock);
- si = isc__mem_allocateunlocked(ctx, size);
+ si = isc__mem_allocateunlocked((isc_mem_t *)ctx, size);
} else {
- si = isc__mem_allocateunlocked(ctx, size);
+ si = isc__mem_allocateunlocked((isc_mem_t *)ctx, size);
MCTXLOCK(ctx, &ctx->lock);
if (si != NULL)
mem_getstats(ctx, si[-1].u.size);
@@ -1381,8 +1567,9 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
return (si);
}
-void *
-isc__mem_reallocate(isc_mem_t *ctx, void *ptr, size_t size FLARG) {
+ISC_MEMFUNC_SCOPE void *
+isc___mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
void *new_ptr = NULL;
size_t oldsize, copysize;
@@ -1400,23 +1587,24 @@ isc__mem_reallocate(isc_mem_t *ctx, void *ptr, size_t size FLARG) {
* NULL if allocation fails or doesn't happen.
*/
if (size > 0U) {
- new_ptr = isc__mem_allocate(ctx, size FLARG_PASS);
+ new_ptr = isc__mem_allocate(ctx0, size FLARG_PASS);
if (new_ptr != NULL && ptr != NULL) {
oldsize = (((size_info *)ptr)[-1]).u.size;
INSIST(oldsize >= ALIGNMENT_SIZE);
oldsize -= ALIGNMENT_SIZE;
copysize = oldsize > size ? size : oldsize;
memcpy(new_ptr, ptr, copysize);
- isc__mem_free(ctx, ptr FLARG_PASS);
+ isc__mem_free(ctx0, ptr FLARG_PASS);
}
} else if (ptr != NULL)
- isc__mem_free(ctx, ptr FLARG_PASS);
+ isc__mem_free(ctx0, ptr FLARG_PASS);
return (new_ptr);
}
-void
-isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
+ISC_MEMFUNC_SCOPE void
+isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_info *si;
size_t size;
isc_boolean_t call_water= ISC_FALSE;
@@ -1472,8 +1660,9 @@ isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
* Other useful things.
*/
-char *
-isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
+ISC_MEMFUNC_SCOPE char *
+isc___mem_strdup(isc_mem_t *mctx0, const char *s FLARG) {
+ isc__mem_t *mctx = (isc__mem_t *)mctx0;
size_t len;
char *ns;
@@ -1482,7 +1671,7 @@ isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
len = strlen(s);
- ns = isc__mem_allocate(mctx, len + 1 FLARG_PASS);
+ ns = isc___mem_allocate((isc_mem_t *)mctx, len + 1 FLARG_PASS);
if (ns != NULL)
strncpy(ns, s, len + 1);
@@ -1490,8 +1679,10 @@ isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
return (ns);
}
-void
-isc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_setdestroycheck(isc_mem_t *ctx0, isc_boolean_t flag) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -1504,8 +1695,10 @@ isc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) {
* Quotas
*/
-void
-isc_mem_setquota(isc_mem_t *ctx, size_t quota) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_setquota(isc_mem_t *ctx0, size_t quota) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -1514,8 +1707,9 @@ isc_mem_setquota(isc_mem_t *ctx, size_t quota) {
MCTXUNLOCK(ctx, &ctx->lock);
}
-size_t
-isc_mem_getquota(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE size_t
+isc__mem_getquota(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_t quota;
REQUIRE(VALID_CONTEXT(ctx));
@@ -1528,8 +1722,9 @@ isc_mem_getquota(isc_mem_t *ctx) {
return (quota);
}
-size_t
-isc_mem_inuse(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE size_t
+isc__mem_inuse(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_t inuse;
REQUIRE(VALID_CONTEXT(ctx));
@@ -1542,10 +1737,11 @@ isc_mem_inuse(isc_mem_t *ctx) {
return (inuse);
}
-void
-isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
+ISC_MEMFUNC_SCOPE void
+isc__mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg,
size_t hiwater, size_t lowater)
{
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
isc_boolean_t callwater = ISC_FALSE;
isc_mem_water_t oldwater;
void *oldwater_arg;
@@ -1580,8 +1776,10 @@ isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
(oldwater)(oldwater_arg, ISC_MEM_LOWATER);
}
-isc_boolean_t
-isc_mem_isovermem(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE isc_boolean_t
+isc__mem_isovermem(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
/*
@@ -1592,8 +1790,10 @@ isc_mem_isovermem(isc_mem_t *ctx) {
return (ctx->is_overmem);
}
-void
-isc_mem_setname(isc_mem_t *ctx, const char *name, void *tag) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_setname(isc_mem_t *ctx0, const char *name, void *tag) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
LOCK(&ctx->lock);
@@ -1603,15 +1803,19 @@ isc_mem_setname(isc_mem_t *ctx, const char *name, void *tag) {
UNLOCK(&ctx->lock);
}
-const char *
-isc_mem_getname(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE const char *
+isc__mem_getname(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
return (ctx->name);
}
-void *
-isc_mem_gettag(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE void *
+isc__mem_gettag(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
REQUIRE(VALID_CONTEXT(ctx));
return (ctx->tag);
@@ -1621,9 +1825,10 @@ isc_mem_gettag(isc_mem_t *ctx) {
* Memory pool stuff
*/
-isc_result_t
-isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
- isc_mempool_t *mpctx;
+ISC_MEMFUNC_SCOPE isc_result_t
+isc__mempool_create(isc_mem_t *mctx0, size_t size, isc_mempool_t **mpctxp) {
+ isc__mem_t *mctx = (isc__mem_t *)mctx0;
+ isc__mempool_t *mpctx;
REQUIRE(VALID_CONTEXT(mctx));
REQUIRE(size > 0U);
@@ -1633,11 +1838,13 @@ isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
* Allocate space for this pool, initialize values, and if all works
* well, attach to the memory context.
*/
- mpctx = isc_mem_get(mctx, sizeof(isc_mempool_t));
+ mpctx = isc_mem_get((isc_mem_t *)mctx, sizeof(isc__mempool_t));
if (mpctx == NULL)
return (ISC_R_NOMEMORY);
- mpctx->magic = MEMPOOL_MAGIC;
+ mpctx->common.methods = (isc_mempoolmethods_t *)&mempoolmethods;
+ mpctx->common.impmagic = MEMPOOL_MAGIC;
+ mpctx->common.magic = ISCAPI_MPOOL_MAGIC;
mpctx->lock = NULL;
mpctx->mctx = mctx;
mpctx->size = size;
@@ -1652,7 +1859,7 @@ isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
#endif
mpctx->items = NULL;
- *mpctxp = mpctx;
+ *mpctxp = (isc_mempool_t *)mpctx;
MCTXLOCK(mctx, &mctx->lock);
ISC_LIST_INITANDAPPEND(mctx->pools, mpctx, link);
@@ -1662,9 +1869,12 @@ isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
return (ISC_R_SUCCESS);
}
-void
-isc_mempool_setname(isc_mempool_t *mpctx, const char *name) {
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setname(isc_mempool_t *mpctx0, const char *name) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
REQUIRE(name != NULL);
+ REQUIRE(VALID_MEMPOOL(mpctx));
#if ISC_MEMPOOL_NAMES
if (mpctx->lock != NULL)
@@ -1681,20 +1891,20 @@ isc_mempool_setname(isc_mempool_t *mpctx, const char *name) {
#endif
}
-void
-isc_mempool_destroy(isc_mempool_t **mpctxp) {
- isc_mempool_t *mpctx;
- isc_mem_t *mctx;
+ISC_MEMFUNC_SCOPE void
+isc__mempool_destroy(isc_mempool_t **mpctxp) {
+ isc__mempool_t *mpctx;
+ isc__mem_t *mctx;
isc_mutex_t *lock;
element *item;
REQUIRE(mpctxp != NULL);
- mpctx = *mpctxp;
+ mpctx = (isc__mempool_t *)*mpctxp;
REQUIRE(VALID_MEMPOOL(mpctx));
#if ISC_MEMPOOL_NAMES
if (mpctx->allocated > 0)
UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_mempool_destroy(): mempool %s "
+ "isc__mempool_destroy(): mempool %s "
"leaked memory",
mpctx->name);
#endif
@@ -1734,9 +1944,10 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) {
mctx->poolcnt--;
MCTXUNLOCK(mctx, &mctx->lock);
- mpctx->magic = 0;
+ mpctx->common.impmagic = 0;
+ mpctx->common.magic = 0;
- isc_mem_put(mpctx->mctx, mpctx, sizeof(isc_mempool_t));
+ isc_mem_put((isc_mem_t *)mpctx->mctx, mpctx, sizeof(isc__mempool_t));
if (lock != NULL)
UNLOCK(lock);
@@ -1744,8 +1955,10 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) {
*mpctxp = NULL;
}
-void
-isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) {
+ISC_MEMFUNC_SCOPE void
+isc__mempool_associatelock(isc_mempool_t *mpctx0, isc_mutex_t *lock) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
REQUIRE(VALID_MEMPOOL(mpctx));
REQUIRE(mpctx->lock == NULL);
REQUIRE(lock != NULL);
@@ -1753,10 +1966,11 @@ isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) {
mpctx->lock = lock;
}
-void *
-isc__mempool_get(isc_mempool_t *mpctx FLARG) {
+ISC_MEMFUNC_SCOPE void *
+isc___mempool_get(isc_mempool_t *mpctx0 FLARG) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
element *item;
- isc_mem_t *mctx;
+ isc__mem_t *mctx;
unsigned int i;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1835,9 +2049,10 @@ isc__mempool_get(isc_mempool_t *mpctx FLARG) {
return (item);
}
-void
-isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
- isc_mem_t *mctx;
+ISC_MEMFUNC_SCOPE void
+isc___mempool_put(isc_mempool_t *mpctx0, void *mem FLARG) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+ isc__mem_t *mctx;
element *item;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1892,8 +2107,10 @@ isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
* Quotas
*/
-void
-isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) {
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setfreemax(isc_mempool_t *mpctx0, unsigned int limit) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
REQUIRE(VALID_MEMPOOL(mpctx));
if (mpctx->lock != NULL)
@@ -1905,8 +2122,9 @@ isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) {
UNLOCK(mpctx->lock);
}
-unsigned int
-isc_mempool_getfreemax(isc_mempool_t *mpctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfreemax(isc_mempool_t *mpctx0) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
unsigned int freemax;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1922,8 +2140,9 @@ isc_mempool_getfreemax(isc_mempool_t *mpctx) {
return (freemax);
}
-unsigned int
-isc_mempool_getfreecount(isc_mempool_t *mpctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfreecount(isc_mempool_t *mpctx0) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
unsigned int freecount;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1939,8 +2158,10 @@ isc_mempool_getfreecount(isc_mempool_t *mpctx) {
return (freecount);
}
-void
-isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) {
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setmaxalloc(isc_mempool_t *mpctx0, unsigned int limit) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
REQUIRE(limit > 0);
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1954,8 +2175,9 @@ isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) {
UNLOCK(mpctx->lock);
}
-unsigned int
-isc_mempool_getmaxalloc(isc_mempool_t *mpctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getmaxalloc(isc_mempool_t *mpctx0) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
unsigned int maxalloc;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1971,8 +2193,9 @@ isc_mempool_getmaxalloc(isc_mempool_t *mpctx) {
return (maxalloc);
}
-unsigned int
-isc_mempool_getallocated(isc_mempool_t *mpctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getallocated(isc_mempool_t *mpctx0) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
unsigned int allocated;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -1988,8 +2211,10 @@ isc_mempool_getallocated(isc_mempool_t *mpctx) {
return (allocated);
}
-void
-isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) {
+ISC_MEMFUNC_SCOPE void
+isc__mempool_setfillcount(isc_mempool_t *mpctx0, unsigned int limit) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
REQUIRE(limit > 0);
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -2002,8 +2227,10 @@ isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) {
UNLOCK(mpctx->lock);
}
-unsigned int
-isc_mempool_getfillcount(isc_mempool_t *mpctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc__mempool_getfillcount(isc_mempool_t *mpctx0) {
+ isc__mempool_t *mpctx = (isc__mempool_t *)mpctx0;
+
unsigned int fillcount;
REQUIRE(VALID_MEMPOOL(mpctx));
@@ -2019,8 +2246,17 @@ isc_mempool_getfillcount(isc_mempool_t *mpctx) {
return (fillcount);
}
-void
-isc_mem_printactive(isc_mem_t *ctx, FILE *file) {
+#ifdef USE_MEMIMPREGISTER
+isc_result_t
+isc__mem_register() {
+ return (isc_mem_register(isc__mem_create2));
+}
+#endif
+
+#ifdef BIND9
+ISC_MEMFUNC_SCOPE void
+isc__mem_printactive(isc_mem_t *ctx0, FILE *file) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(file != NULL);
@@ -2033,12 +2269,12 @@ isc_mem_printactive(isc_mem_t *ctx, FILE *file) {
#endif
}
-void
-isc_mem_printallactive(FILE *file) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_printallactive(FILE *file) {
#if !ISC_MEM_TRACKLINES
UNUSED(file);
#else
- isc_mem_t *ctx;
+ isc__mem_t *ctx;
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
@@ -2053,15 +2289,15 @@ isc_mem_printallactive(FILE *file) {
#endif
}
-void
-isc_mem_checkdestroyed(FILE *file) {
+ISC_MEMFUNC_SCOPE void
+isc__mem_checkdestroyed(FILE *file) {
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
LOCK(&lock);
if (!ISC_LIST_EMPTY(contexts)) {
#if ISC_MEM_TRACKLINES
- isc_mem_t *ctx;
+ isc__mem_t *ctx;
for (ctx = ISC_LIST_HEAD(contexts);
ctx != NULL;
@@ -2076,9 +2312,11 @@ isc_mem_checkdestroyed(FILE *file) {
UNLOCK(&lock);
}
-unsigned int
-isc_mem_references(isc_mem_t *ctx) {
+ISC_MEMFUNC_SCOPE unsigned int
+isc_mem_references(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
unsigned int references;
+
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
@@ -2098,7 +2336,7 @@ typedef struct summarystat {
} summarystat_t;
static void
-renderctx(isc_mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
+renderctx(isc__mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
REQUIRE(VALID_CONTEXT(ctx));
xmlTextWriterStartElement(writer, ISC_XMLCHAR "context");
@@ -2184,7 +2422,7 @@ renderctx(isc_mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
void
isc_mem_renderxml(xmlTextWriterPtr writer) {
- isc_mem_t *ctx;
+ isc__mem_t *ctx;
summarystat_t summary;
isc_uint64_t lost;
@@ -2236,3 +2474,4 @@ isc_mem_renderxml(xmlTextWriterPtr writer) {
}
#endif /* HAVE_LIBXML2 */
+#endif /* BIND9 */
diff --git a/lib/isc/mem_api.c b/lib/isc/mem_api.c
new file mode 100644
index 000000000000..638efcd0bb67
--- /dev/null
+++ b/lib/isc/mem_api.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: mem_api.c,v 1.8 2010-08-12 21:30:26 jinmei Exp $ */
+
+#include <config.h>
+
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/once.h>
+#include <isc/util.h>
+
+#if ISC_MEM_TRACKLINES
+#define FLARG_PASS , file, line
+#define FLARG , const char *file, unsigned int line
+#else
+#define FLARG_PASS
+#define FLARG
+#endif
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_memcreatefunc_t mem_createfunc = NULL;
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_mem_register(isc_memcreatefunc_t createfunc) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+ if (mem_createfunc == NULL)
+ mem_createfunc = createfunc;
+ else
+ result = ISC_R_EXISTS;
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_mem_create(size_t init_max_size, size_t target_size, isc_mem_t **mctxp) {
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(mem_createfunc != NULL);
+ result = (*mem_createfunc)(init_max_size, target_size, mctxp,
+ ISC_MEMFLAG_DEFAULT);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_mem_create2(size_t init_max_size, size_t target_size, isc_mem_t **mctxp,
+ unsigned int flags)
+{
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(mem_createfunc != NULL);
+ result = (*mem_createfunc)(init_max_size, target_size, mctxp, flags);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {
+ REQUIRE(ISCAPI_MCTX_VALID(source));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+
+ source->methods->attach(source, targetp);
+
+ ENSURE(*targetp == source);
+}
+
+void
+isc_mem_detach(isc_mem_t **mctxp) {
+ REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp));
+
+ (*mctxp)->methods->detach(mctxp);
+
+ ENSURE(*mctxp == NULL);
+}
+
+void
+isc_mem_destroy(isc_mem_t **mctxp) {
+ REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp));
+
+ (*mctxp)->methods->destroy(mctxp);
+
+ ENSURE(*mctxp == NULL);
+}
+
+void *
+isc__mem_get(isc_mem_t *mctx, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memget(mctx, size FLARG_PASS));
+}
+
+void
+isc__mem_put(isc_mem_t *mctx, void *ptr, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ mctx->methods->memput(mctx, ptr, size FLARG_PASS);
+}
+
+void
+isc__mem_putanddetach(isc_mem_t **mctxp, void *ptr, size_t size FLARG) {
+ REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp));
+
+ (*mctxp)->methods->memputanddetach(mctxp, ptr, size FLARG_PASS);
+
+ /*
+ * XXX: We cannot always ensure *mctxp == NULL here
+ * (see lib/isc/mem.c).
+ */
+}
+
+void *
+isc__mem_allocate(isc_mem_t *mctx, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memallocate(mctx, size FLARG_PASS));
+}
+
+void *
+isc__mem_reallocate(isc_mem_t *mctx, void *ptr, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memreallocate(mctx, ptr, size FLARG_PASS));
+}
+
+char *
+isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memstrdup(mctx, s FLARG_PASS));
+}
+
+void
+isc__mem_free(isc_mem_t *mctx, void *ptr FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ mctx->methods->memfree(mctx, ptr FLARG_PASS);
+}
+
+void
+isc_mem_setdestroycheck(isc_mem_t *mctx, isc_boolean_t flag) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ mctx->methods->setdestroycheck(mctx, flag);
+}
+
+void
+isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
+ size_t hiwater, size_t lowater)
+{
+ REQUIRE(ISCAPI_MCTX_VALID(ctx));
+
+ ctx->methods->setwater(ctx, water, water_arg, hiwater, lowater);
+}
+
+void
+isc_mem_waterack(isc_mem_t *ctx, int flag) {
+ REQUIRE(ISCAPI_MCTX_VALID(ctx));
+
+ ctx->methods->waterack(ctx, flag);
+}
+
+size_t
+isc_mem_inuse(isc_mem_t *mctx) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->inuse(mctx));
+}
+
+isc_boolean_t
+isc_mem_isovermem(isc_mem_t *mctx) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->isovermem(mctx));
+}
+
+void
+isc_mem_setname(isc_mem_t *mctx, const char *name, void *tag) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ UNUSED(name);
+ UNUSED(tag);
+
+ return;
+}
+
+const char *
+isc_mem_getname(isc_mem_t *mctx) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return ("");
+}
+
+void *
+isc_mem_gettag(isc_mem_t *mctx) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (NULL);
+}
+
+isc_result_t
+isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->mpcreate(mctx, size, mpctxp));
+}
+
+void
+isc_mempool_destroy(isc_mempool_t **mpctxp) {
+ REQUIRE(mpctxp != NULL && ISCAPI_MPOOL_VALID(*mpctxp));
+
+ (*mpctxp)->methods->destroy(mpctxp);
+
+ ENSURE(*mpctxp == NULL);
+}
+
+void *
+isc__mempool_get(isc_mempool_t *mpctx FLARG) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ return (mpctx->methods->get(mpctx FLARG_PASS));
+}
+
+void
+isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->put(mpctx, mem FLARG_PASS);
+}
+
+unsigned int
+isc_mempool_getallocated(isc_mempool_t *mpctx) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ return (mpctx->methods->getallocated(mpctx));
+}
+
+void
+isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->setmaxalloc(mpctx, limit);
+}
+
+void
+isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->setfreemax(mpctx, limit);
+}
+
+void
+isc_mempool_setname(isc_mempool_t *mpctx, const char *name) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->setname(mpctx, name);
+}
+
+void
+isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->associatelock(mpctx, lock);
+}
+
+void
+isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit) {
+ REQUIRE(ISCAPI_MPOOL_VALID(mpctx));
+
+ mpctx->methods->setfillcount(mpctx, limit);
+}
diff --git a/lib/isc/netaddr.c b/lib/isc/netaddr.c
index 92c4fe5b4d4c..33dddb8d1b5b 100644
--- a/lib/isc/netaddr.c
+++ b/lib/isc/netaddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: netaddr.c,v 1.38 2007-06-18 23:47:44 tbox Exp $ */
+/* $Id: netaddr.c,v 1.41 2010-11-17 23:47:08 tbox Exp $ */
/*! \file */
@@ -303,18 +303,18 @@ isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6) {
isc_result_t
isc_netaddr_frompath(isc_netaddr_t *netaddr, const char *path) {
#ifdef ISC_PLATFORM_HAVESYSUNH
- if (strlen(path) > sizeof(netaddr->type.un) - 1)
- return (ISC_R_NOSPACE);
-
- memset(netaddr, 0, sizeof(*netaddr));
- netaddr->family = AF_UNIX;
- strcpy(netaddr->type.un, path);
- netaddr->zone = 0;
- return (ISC_R_SUCCESS);
-#else
+ if (strlen(path) > sizeof(netaddr->type.un) - 1)
+ return (ISC_R_NOSPACE);
+
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_UNIX;
+ strcpy(netaddr->type.un, path);
+ netaddr->zone = 0;
+ return (ISC_R_SUCCESS);
+#else
UNUSED(netaddr);
UNUSED(path);
- return (ISC_R_NOTIMPLEMENTED);
+ return (ISC_R_NOTIMPLEMENTED);
#endif
}
diff --git a/lib/isc/nls/Makefile.in b/lib/isc/nls/Makefile.in
index c4ec7a16f4bb..bfd8dd0ff1c6 100644
--- a/lib/isc/nls/Makefile.in
+++ b/lib/isc/nls/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.14 2007-06-19 23:47:18 tbox Exp $
+# $Id: Makefile.in,v 1.17 2009-12-05 23:31:41 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/lib/isc/nothreads/Makefile.in b/lib/isc/nothreads/Makefile.in
index 042cfce553f0..29bacd6663b6 100644
--- a/lib/isc/nothreads/Makefile.in
+++ b/lib/isc/nothreads/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2010 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,11 +13,11 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.7.332.2 2010-06-09 23:48:16 tbox Exp $
+# $Id: Makefile.in,v 1.12 2010-06-09 23:50:58 tbox Exp $
-srcdir = @srcdir@
-VPATH = @srcdir@
top_srcdir = @top_srcdir@
+srcdir = @top_srcdir@/lib/isc/nothreads
+VPATH = @top_srcdir@/lib/isc/nothreads
CINCLUDES = -I${srcdir}/include \
-I${srcdir}/../unix/include \
diff --git a/lib/isc/powerpc/include/isc/atomic.h b/lib/isc/powerpc/include/isc/atomic.h
index 074fea134298..2e11e398e7ab 100644
--- a/lib/isc/powerpc/include/isc/atomic.h
+++ b/lib/isc/powerpc/include/isc/atomic.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: atomic.h,v 1.6.332.2 2009-10-14 23:47:14 tbox Exp $ */
+/* $Id: atomic.h,v 1.8 2009-10-14 23:47:51 tbox Exp $ */
#ifndef ISC_ATOMIC_H
#define ISC_ATOMIC_H 1
diff --git a/lib/isc/print.c b/lib/isc/print.c
index 5d800f338653..bd7b580fc01c 100644
--- a/lib/isc/print.c
+++ b/lib/isc/print.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: print.c,v 1.35.130.2 2010-10-18 23:46:17 tbox Exp $ */
+/* $Id: print.c,v 1.37 2010-10-18 23:47:08 tbox Exp $ */
/*! \file */
diff --git a/lib/isc/pthreads/Makefile.in b/lib/isc/pthreads/Makefile.in
index 572d76cac116..7aae93d4dee9 100644
--- a/lib/isc/pthreads/Makefile.in
+++ b/lib/isc/pthreads/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.19 2007-06-19 23:47:18 tbox Exp $
+# $Id: Makefile.in,v 1.22 2009-12-05 23:31:41 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/lib/isc/pthreads/mutex.c b/lib/isc/pthreads/mutex.c
index efe38dba8f80..fa5a701372dd 100644
--- a/lib/isc/pthreads/mutex.c
+++ b/lib/isc/pthreads/mutex.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mutex.c,v 1.16.112.2 2011-01-04 23:45:43 tbox Exp $ */
+/* $Id: mutex.c,v 1.18 2011-01-04 23:47:14 tbox Exp $ */
/*! \file */
diff --git a/lib/isc/radix.c b/lib/isc/radix.c
index d72ed3311fa1..be2e8412e24d 100644
--- a/lib/isc/radix.c
+++ b/lib/isc/radix.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: radix.c,v 1.20.36.3 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: radix.c,v 1.23 2009-01-18 23:48:14 tbox Exp $ */
/*
* This source was adapted from MRT's RCS Ids:
diff --git a/lib/isc/random.c b/lib/isc/random.c
index 09145f42fba3..f082fe6e6b3b 100644
--- a/lib/isc/random.c
+++ b/lib/isc/random.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: random.c,v 1.25.332.2 2009-07-16 23:47:17 tbox Exp $ */
+/* $Id: random.c,v 1.28 2009-07-16 05:52:46 marka Exp $ */
/*! \file */
@@ -103,7 +103,7 @@ isc_uint32_t
isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter) {
isc_uint32_t rnd;
- REQUIRE(jitter < max);
+ REQUIRE(jitter < max || (jitter == 0 && max == 0));
if (jitter == 0)
return (max);
diff --git a/lib/isc/rwlock.c b/lib/isc/rwlock.c
index 39b90d770728..fce751691195 100644
--- a/lib/isc/rwlock.c
+++ b/lib/isc/rwlock.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rwlock.c,v 1.44.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: rwlock.c,v 1.46 2009-01-18 23:48:14 tbox Exp $ */
/*! \file */
diff --git a/lib/isc/sha1.c b/lib/isc/sha1.c
index 20ee28d1c338..d72eb9cb6063 100644
--- a/lib/isc/sha1.c
+++ b/lib/isc/sha1.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sha1.c,v 1.18 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: sha1.c,v 1.20 2009-02-06 23:47:42 tbox Exp $ */
/* $NetBSD: sha1.c,v 1.5 2000/01/22 22:19:14 mycroft Exp $ */
/* $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ */
@@ -38,11 +38,47 @@
#include "config.h"
#include <isc/assertions.h>
+#include <isc/platform.h>
#include <isc/sha1.h>
#include <isc/string.h>
#include <isc/types.h>
#include <isc/util.h>
+#ifdef ISC_PLATFORM_OPENSSLHASH
+
+void
+isc_sha1_init(isc_sha1_t *context)
+{
+ INSIST(context != NULL);
+
+ EVP_DigestInit(context, EVP_sha1());
+}
+
+void
+isc_sha1_invalidate(isc_sha1_t *context) {
+ EVP_MD_CTX_cleanup(context);
+}
+
+void
+isc_sha1_update(isc_sha1_t *context, const unsigned char *data,
+ unsigned int len)
+{
+ INSIST(context != 0);
+ INSIST(data != 0);
+
+ EVP_DigestUpdate(context, (const void *) data, (size_t) len);
+}
+
+void
+isc_sha1_final(isc_sha1_t *context, unsigned char *digest) {
+ INSIST(digest != 0);
+ INSIST(context != 0);
+
+ EVP_DigestFinal(context, digest, NULL);
+}
+
+#else
+
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/*@{*/
@@ -313,3 +349,4 @@ isc_sha1_final(isc_sha1_t *context, unsigned char *digest) {
memset(context, 0, sizeof(isc_sha1_t));
}
+#endif
diff --git a/lib/isc/sha2.c b/lib/isc/sha2.c
index 22f1d47655a4..1dc05a70dabb 100644
--- a/lib/isc/sha2.c
+++ b/lib/isc/sha2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sha2.c,v 1.13.332.4 2010-01-15 23:47:34 tbox Exp $ */
+/* $Id: sha2.c,v 1.18 2009-10-22 02:21:31 each Exp $ */
/* $FreeBSD$ */
/* $KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $ */
@@ -58,10 +58,169 @@
#include <config.h>
#include <isc/assertions.h>
+#include <isc/platform.h>
#include <isc/sha2.h>
#include <isc/string.h>
#include <isc/util.h>
+#ifdef ISC_PLATFORM_OPENSSLHASH
+
+void
+isc_sha224_init(isc_sha224_t *context) {
+ if (context == (isc_sha224_t *)0) {
+ return;
+ }
+ EVP_DigestInit(context, EVP_sha224());
+}
+
+void
+isc_sha224_invalidate(isc_sha224_t *context) {
+ EVP_MD_CTX_cleanup(context);
+}
+
+void
+isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) {
+ if (len == 0U) {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha224_t *)0 && data != (isc_uint8_t*)0);
+
+ EVP_DigestUpdate(context, (const void *) data, len);
+}
+
+void
+isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) {
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha224_t *)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (isc_uint8_t*)0) {
+ EVP_DigestFinal(context, digest, NULL);
+ } else {
+ EVP_MD_CTX_cleanup(context);
+ }
+}
+
+void
+isc_sha256_init(isc_sha256_t *context) {
+ if (context == (isc_sha256_t *)0) {
+ return;
+ }
+ EVP_DigestInit(context, EVP_sha256());
+}
+
+void
+isc_sha256_invalidate(isc_sha256_t *context) {
+ EVP_MD_CTX_cleanup(context);
+}
+
+void
+isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) {
+ if (len == 0U) {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0);
+
+ EVP_DigestUpdate(context, (const void *) data, len);
+}
+
+void
+isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) {
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha256_t *)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (isc_uint8_t*)0) {
+ EVP_DigestFinal(context, digest, NULL);
+ } else {
+ EVP_MD_CTX_cleanup(context);
+ }
+}
+
+void
+isc_sha512_init(isc_sha512_t *context) {
+ if (context == (isc_sha512_t *)0) {
+ return;
+ }
+ EVP_DigestInit(context, EVP_sha512());
+}
+
+void
+isc_sha512_invalidate(isc_sha512_t *context) {
+ EVP_MD_CTX_cleanup(context);
+}
+
+void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) {
+ if (len == 0U) {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0);
+
+ EVP_DigestUpdate(context, (const void *) data, len);
+}
+
+void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) {
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha512_t *)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (isc_uint8_t*)0) {
+ EVP_DigestFinal(context, digest, NULL);
+ } else {
+ EVP_MD_CTX_cleanup(context);
+ }
+}
+
+void
+isc_sha384_init(isc_sha384_t *context) {
+ if (context == (isc_sha384_t *)0) {
+ return;
+ }
+ EVP_DigestInit(context, EVP_sha384());
+}
+
+void
+isc_sha384_invalidate(isc_sha384_t *context) {
+ EVP_MD_CTX_cleanup(context);
+}
+
+void
+isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) {
+ if (len == 0U) {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0);
+
+ EVP_DigestUpdate(context, (const void *) data, len);
+}
+
+void
+isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) {
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha384_t *)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (isc_uint8_t*)0) {
+ EVP_DigestFinal(context, digest, NULL);
+ } else {
+ EVP_MD_CTX_cleanup(context);
+ }
+}
+
+#else
+
/*
* UNROLLED TRANSFORM LOOP NOTE:
* You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
@@ -394,13 +553,6 @@ static const isc_uint64_t sha512_initial_hash_value[8] = {
};
#endif
-/*
- * Constant used by SHA256/384/512_End() functions for converting the
- * digest to a readable hexadecimal character string:
- */
-static const char *sha2_hex_digits = "0123456789abcdef";
-
-
/*** SHA-224: *********************************************************/
void
@@ -432,41 +584,6 @@ isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) {
memset(sha256_digest, 0, ISC_SHA256_DIGESTLENGTH);
}
-char *
-isc_sha224_end(isc_sha224_t *context, char buffer[]) {
- isc_uint8_t digest[ISC_SHA224_DIGESTLENGTH], *d = digest;
- unsigned int i;
-
- /* Sanity check: */
- REQUIRE(context != (isc_sha224_t *)0);
-
- if (buffer != (char*)0) {
- isc_sha224_final(digest, context);
-
- for (i = 0; i < ISC_SHA224_DIGESTLENGTH; i++) {
- *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
- *buffer++ = sha2_hex_digits[*d & 0x0f];
- d++;
- }
- *buffer = (char)0;
- } else {
- memset(context, 0, sizeof(context));
- }
- memset(digest, 0, ISC_SHA224_DIGESTLENGTH);
- return buffer;
-}
-
-char*
-isc_sha224_data(const isc_uint8_t *data, size_t len,
- char digest[ISC_SHA224_DIGESTSTRINGLENGTH])
-{
- isc_sha224_t context;
-
- isc_sha224_init(&context);
- isc_sha224_update(&context, data, len);
- return (isc_sha224_end(&context, digest));
-}
-
/*** SHA-256: *********************************************************/
void
isc_sha256_init(isc_sha256_t *context) {
@@ -479,6 +596,11 @@ isc_sha256_init(isc_sha256_t *context) {
context->bitcount = 0;
}
+void
+isc_sha256_invalidate(isc_sha256_t *context) {
+ memset(context, 0, sizeof(isc_sha256_t));
+}
+
#ifdef ISC_SHA2_UNROLL_TRANSFORM
/* Unrolled SHA-256 round macros: */
@@ -656,11 +778,6 @@ isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) {
#endif /* ISC_SHA2_UNROLL_TRANSFORM */
void
-isc_sha256_invalidate(isc_sha256_t *context) {
- memset(context, 0, sizeof(isc_sha256_t));
-}
-
-void
isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) {
unsigned int freespace, usedspace;
@@ -782,42 +899,6 @@ isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) {
usedspace = 0;
}
-char *
-isc_sha256_end(isc_sha256_t *context, char buffer[]) {
- isc_uint8_t digest[ISC_SHA256_DIGESTLENGTH], *d = digest;
- unsigned int i;
-
- /* Sanity check: */
- REQUIRE(context != (isc_sha256_t *)0);
-
- if (buffer != (char*)0) {
- isc_sha256_final(digest, context);
-
- for (i = 0; i < ISC_SHA256_DIGESTLENGTH; i++) {
- *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
- *buffer++ = sha2_hex_digits[*d & 0x0f];
- d++;
- }
- *buffer = (char)0;
- } else {
- memset(context, 0, sizeof(context));
- }
- memset(digest, 0, ISC_SHA256_DIGESTLENGTH);
- return buffer;
-}
-
-char *
-isc_sha256_data(const isc_uint8_t* data, size_t len,
- char digest[ISC_SHA256_DIGESTSTRINGLENGTH])
-{
- isc_sha256_t context;
-
- isc_sha256_init(&context);
- isc_sha256_update(&context, data, len);
- return (isc_sha256_end(&context, digest));
-}
-
-
/*** SHA-512: *********************************************************/
void
isc_sha512_init(isc_sha512_t *context) {
@@ -830,6 +911,11 @@ isc_sha512_init(isc_sha512_t *context) {
context->bitcount[0] = context->bitcount[1] = 0;
}
+void
+isc_sha512_invalidate(isc_sha512_t *context) {
+ memset(context, 0, sizeof(isc_sha512_t));
+}
+
#ifdef ISC_SHA2_UNROLL_TRANSFORM
/* Unrolled SHA-512 round macros: */
@@ -1000,13 +1086,7 @@ isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) {
#endif /* ISC_SHA2_UNROLL_TRANSFORM */
-void
-isc_sha512_invalidate(isc_sha512_t *context) {
- memset(context, 0, sizeof(isc_sha512_t));
-}
-
-void
-isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) {
+void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) {
unsigned int freespace, usedspace;
if (len == 0U) {
@@ -1131,41 +1211,6 @@ void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) {
memset(context, 0, sizeof(context));
}
-char *
-isc_sha512_end(isc_sha512_t *context, char buffer[]) {
- isc_uint8_t digest[ISC_SHA512_DIGESTLENGTH], *d = digest;
- unsigned int i;
-
- /* Sanity check: */
- REQUIRE(context != (isc_sha512_t *)0);
-
- if (buffer != (char*)0) {
- isc_sha512_final(digest, context);
-
- for (i = 0; i < ISC_SHA512_DIGESTLENGTH; i++) {
- *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
- *buffer++ = sha2_hex_digits[*d & 0x0f];
- d++;
- }
- *buffer = (char)0;
- } else {
- memset(context, 0, sizeof(context));
- }
- memset(digest, 0, ISC_SHA512_DIGESTLENGTH);
- return buffer;
-}
-
-char *
-isc_sha512_data(const isc_uint8_t *data, size_t len,
- char digest[ISC_SHA512_DIGESTSTRINGLENGTH])
-{
- isc_sha512_t context;
-
- isc_sha512_init(&context);
- isc_sha512_update(&context, data, len);
- return (isc_sha512_end(&context, digest));
-}
-
/*** SHA-384: *********************************************************/
void
@@ -1218,6 +1263,130 @@ isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) {
/* Zero out state data */
memset(context, 0, sizeof(context));
}
+#endif /* !ISC_PLATFORM_OPENSSLHASH */
+
+/*
+ * Constant used by SHA256/384/512_End() functions for converting the
+ * digest to a readable hexadecimal character string:
+ */
+static const char *sha2_hex_digits = "0123456789abcdef";
+
+char *
+isc_sha224_end(isc_sha224_t *context, char buffer[]) {
+ isc_uint8_t digest[ISC_SHA224_DIGESTLENGTH], *d = digest;
+ unsigned int i;
+
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha224_t *)0);
+
+ if (buffer != (char*)0) {
+ isc_sha224_final(digest, context);
+
+ for (i = 0; i < ISC_SHA224_DIGESTLENGTH; i++) {
+ *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha2_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+#ifdef ISC_PLATFORM_OPENSSLHASH
+ EVP_MD_CTX_cleanup(context);
+#else
+ memset(context, 0, sizeof(context));
+#endif
+ }
+ memset(digest, 0, ISC_SHA224_DIGESTLENGTH);
+ return buffer;
+}
+
+char *
+isc_sha224_data(const isc_uint8_t *data, size_t len,
+ char digest[ISC_SHA224_DIGESTSTRINGLENGTH])
+{
+ isc_sha224_t context;
+
+ isc_sha224_init(&context);
+ isc_sha224_update(&context, data, len);
+ return (isc_sha224_end(&context, digest));
+}
+
+char *
+isc_sha256_end(isc_sha256_t *context, char buffer[]) {
+ isc_uint8_t digest[ISC_SHA256_DIGESTLENGTH], *d = digest;
+ unsigned int i;
+
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha256_t *)0);
+
+ if (buffer != (char*)0) {
+ isc_sha256_final(digest, context);
+
+ for (i = 0; i < ISC_SHA256_DIGESTLENGTH; i++) {
+ *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha2_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+#ifdef ISC_PLATFORM_OPENSSLHASH
+ EVP_MD_CTX_cleanup(context);
+#else
+ memset(context, 0, sizeof(context));
+#endif
+ }
+ memset(digest, 0, ISC_SHA256_DIGESTLENGTH);
+ return buffer;
+}
+
+char *
+isc_sha256_data(const isc_uint8_t* data, size_t len,
+ char digest[ISC_SHA256_DIGESTSTRINGLENGTH])
+{
+ isc_sha256_t context;
+
+ isc_sha256_init(&context);
+ isc_sha256_update(&context, data, len);
+ return (isc_sha256_end(&context, digest));
+}
+
+char *
+isc_sha512_end(isc_sha512_t *context, char buffer[]) {
+ isc_uint8_t digest[ISC_SHA512_DIGESTLENGTH], *d = digest;
+ unsigned int i;
+
+ /* Sanity check: */
+ REQUIRE(context != (isc_sha512_t *)0);
+
+ if (buffer != (char*)0) {
+ isc_sha512_final(digest, context);
+
+ for (i = 0; i < ISC_SHA512_DIGESTLENGTH; i++) {
+ *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha2_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+#ifdef ISC_PLATFORM_OPENSSLHASH
+ EVP_MD_CTX_cleanup(context);
+#else
+ memset(context, 0, sizeof(context));
+#endif
+ }
+ memset(digest, 0, ISC_SHA512_DIGESTLENGTH);
+ return buffer;
+}
+
+char *
+isc_sha512_data(const isc_uint8_t *data, size_t len,
+ char digest[ISC_SHA512_DIGESTSTRINGLENGTH])
+{
+ isc_sha512_t context;
+
+ isc_sha512_init(&context);
+ isc_sha512_update(&context, data, len);
+ return (isc_sha512_end(&context, digest));
+}
char *
isc_sha384_end(isc_sha384_t *context, char buffer[]) {
@@ -1237,13 +1406,17 @@ isc_sha384_end(isc_sha384_t *context, char buffer[]) {
}
*buffer = (char)0;
} else {
+#ifdef ISC_PLATFORM_OPENSSLHASH
+ EVP_MD_CTX_cleanup(context);
+#else
memset(context, 0, sizeof(context));
+#endif
}
memset(digest, 0, ISC_SHA384_DIGESTLENGTH);
return buffer;
}
-char*
+char *
isc_sha384_data(const isc_uint8_t *data, size_t len,
char digest[ISC_SHA384_DIGESTSTRINGLENGTH])
{
diff --git a/lib/isc/sockaddr.c b/lib/isc/sockaddr.c
index 19833e4fa1eb..9661ee48b7a6 100644
--- a/lib/isc/sockaddr.c
+++ b/lib/isc/sockaddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sockaddr.c,v 1.70 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: sockaddr.c,v 1.73 2010-11-17 23:47:09 tbox Exp $ */
/*! \file */
@@ -390,8 +390,8 @@ isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na,
#endif
sockaddr->type.sin6.sin6_port = htons(port);
break;
- default:
- INSIST(0);
+ default:
+ INSIST(0);
}
ISC_LINK_INIT(sockaddr, link);
}
diff --git a/lib/isc/socket_api.c b/lib/isc/socket_api.c
new file mode 100644
index 000000000000..c1e5fd4ca846
--- /dev/null
+++ b/lib/isc/socket_api.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: socket_api.c,v 1.5 2009-10-01 01:30:01 sar Exp $ */
+
+#include <config.h>
+
+#include <isc/app.h>
+#include <isc/magic.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/socket.h>
+#include <isc/util.h>
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_socketmgrcreatefunc_t socketmgr_createfunc = NULL;
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_socket_register(isc_socketmgrcreatefunc_t createfunc) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+ if (socketmgr_createfunc == NULL)
+ socketmgr_createfunc = createfunc;
+ else
+ result = ISC_R_EXISTS;
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_socketmgr_t **managerp)
+{
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(socketmgr_createfunc != NULL);
+ result = (*socketmgr_createfunc)(mctx, managerp);
+
+ UNLOCK(&createlock);
+
+ if (result == ISC_R_SUCCESS)
+ isc_appctx_setsocketmgr(actx, *managerp);
+
+ return (result);
+}
+
+isc_result_t
+isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(socketmgr_createfunc != NULL);
+ result = (*socketmgr_createfunc)(mctx, managerp);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
+ REQUIRE(managerp != NULL && ISCAPI_SOCKETMGR_VALID(*managerp));
+
+ (*managerp)->methods->destroy(managerp);
+
+ ENSURE(*managerp == NULL);
+}
+
+isc_result_t
+isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
+ isc_socket_t **socketp)
+{
+ REQUIRE(ISCAPI_SOCKETMGR_VALID(manager));
+
+ return (manager->methods->socketcreate(manager, pf, type, socketp));
+}
+
+void
+isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+ REQUIRE(socketp != NULL && *socketp == NULL);
+
+ sock->methods->attach(sock, socketp);
+
+ ENSURE(*socketp == sock);
+}
+
+void
+isc_socket_detach(isc_socket_t **socketp) {
+ REQUIRE(socketp != NULL && ISCAPI_SOCKET_VALID(*socketp));
+
+ (*socketp)->methods->detach(socketp);
+
+ ENSURE(*socketp == NULL);
+}
+
+isc_result_t
+isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
+ unsigned int options)
+{
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->bind(sock, sockaddr, options));
+}
+
+isc_result_t
+isc_socket_sendto(isc_socket_t *sock, isc_region_t *region, isc_task_t *task,
+ isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+{
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->sendto(sock, region, task, action, arg, address,
+ pktinfo));
+}
+
+isc_result_t
+isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task,
+ isc_taskaction_t action, const void *arg)
+{
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->connect(sock, addr, task, action, arg));
+}
+
+isc_result_t
+isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
+ isc_task_t *task, isc_taskaction_t action, const void *arg)
+{
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->recv(sock, region, minimum, task, action, arg));
+}
+
+void
+isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ sock->methods->cancel(sock, task, how);
+}
+
+isc_result_t
+isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->getsockname(sock, addressp));
+}
+
+void
+isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ sock->methods->ipv6only(sock, yes);
+}
+
+isc_sockettype_t
+isc_socket_gettype(isc_socket_t *sock) {
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return (sock->methods->gettype(sock));
+}
+
+void
+isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) {
+ REQUIRE(ISCAPI_SOCKET_VALID(socket));
+
+ UNUSED(socket); /* in case REQUIRE() is empty */
+ UNUSED(name);
+ UNUSED(tag);
+}
+
+isc_result_t
+isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags,
+ isc_sockfdwatch_t callback, void *cbarg,
+ isc_task_t *task, isc_socket_t **socketp)
+{
+ REQUIRE(ISCAPI_SOCKETMGR_VALID(manager));
+
+ return (manager->methods->fdwatchcreate(manager, fd, flags,
+ callback, cbarg, task,
+ socketp));
+}
+
+isc_result_t
+isc_socket_fdwatchpoke(isc_socket_t *sock, int flags)
+{
+ REQUIRE(ISCAPI_SOCKET_VALID(sock));
+
+ return(sock->methods->fdwatchpoke(sock, flags));
+}
diff --git a/lib/isc/stats.c b/lib/isc/stats.c
index ac66bcfaca55..e72fb543c989 100644
--- a/lib/isc/stats.c
+++ b/lib/isc/stats.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: stats.c,v 1.3.6.2 2009-01-29 23:47:44 tbox Exp $ */
+/* $Id: stats.c,v 1.3 2009-01-27 23:47:54 tbox Exp $ */
/*! \file */
diff --git a/lib/isc/task.c b/lib/isc/task.c
index 5d87f21be39e..a9dfd1fcc35a 100644
--- a/lib/isc/task.c
+++ b/lib/isc/task.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: task.c,v 1.107.120.2 2010-12-03 23:45:47 tbox Exp $ */
+/* $Id: task.c,v 1.115.14.1.2.1 2011-06-02 23:47:36 tbox Exp $ */
/*! \file
* \author Principal Author: Bob Halley
@@ -40,9 +40,33 @@
#include <isc/util.h>
#include <isc/xml.h>
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef OPENSSL_LEAKS
+#include <openssl/err.h>
+#endif
+
+/*%
+ * For BIND9 internal applications:
+ * when built with threads we use multiple worker threads shared by the whole
+ * application.
+ * when built without threads we share a single global task manager and use
+ * an integrated event loop for socket, timer, and other generic task events.
+ * For generic library:
+ * we don't use either of them: an application can have multiple task managers
+ * whether or not it's threaded, and if the application is threaded each thread
+ * is expected to have a separate manager; no "worker threads" are shared by
+ * the application threads.
+ */
+#ifdef BIND9
+#ifdef ISC_PLATFORM_USETHREADS
+#define USE_WORKER_THREADS
+#else
+#define USE_SHARED_MANAGER
+#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* BIND9 */
+
+#ifndef USE_WORKER_THREADS
#include "task_p.h"
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
#ifdef ISC_TASK_TRACE
#define XTRACE(m) fprintf(stderr, "task %p thread %lu: %s\n", \
@@ -66,7 +90,7 @@ typedef enum {
task_state_done
} task_state_t;
-#ifdef HAVE_LIBXML2
+#if defined(HAVE_LIBXML2) && defined(BIND9)
static const char *statenames[] = {
"idle", "ready", "running", "done",
};
@@ -75,10 +99,13 @@ static const char *statenames[] = {
#define TASK_MAGIC ISC_MAGIC('T', 'A', 'S', 'K')
#define VALID_TASK(t) ISC_MAGIC_VALID(t, TASK_MAGIC)
-struct isc_task {
+typedef struct isc__task isc__task_t;
+typedef struct isc__taskmgr isc__taskmgr_t;
+
+struct isc__task {
/* Not locked. */
- unsigned int magic;
- isc_taskmgr_t * manager;
+ isc_task_t common;
+ isc__taskmgr_t * manager;
isc_mutex_t lock;
/* Locked by task lock. */
task_state_t state;
@@ -91,8 +118,8 @@ struct isc_task {
char name[16];
void * tag;
/* Locked by task manager lock. */
- LINK(isc_task_t) link;
- LINK(isc_task_t) ready_link;
+ LINK(isc__task_t) link;
+ LINK(isc__task_t) ready_link;
};
#define TASK_F_SHUTTINGDOWN 0x01
@@ -103,9 +130,11 @@ struct isc_task {
#define TASK_MANAGER_MAGIC ISC_MAGIC('T', 'S', 'K', 'M')
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TASK_MANAGER_MAGIC)
-struct isc_taskmgr {
+typedef ISC_LIST(isc__task_t) isc__tasklist_t;
+
+struct isc__taskmgr {
/* Not locked. */
- unsigned int magic;
+ isc_taskmgr_t common;
isc_mem_t * mctx;
isc_mutex_t lock;
#ifdef ISC_PLATFORM_USETHREADS
@@ -114,8 +143,8 @@ struct isc_taskmgr {
#endif /* ISC_PLATFORM_USETHREADS */
/* Locked by task manager lock. */
unsigned int default_quantum;
- LIST(isc_task_t) tasks;
- isc_tasklist_t ready_tasks;
+ LIST(isc__task_t) tasks;
+ isc__tasklist_t ready_tasks;
#ifdef ISC_PLATFORM_USETHREADS
isc_condition_t work_available;
isc_condition_t exclusive_granted;
@@ -123,7 +152,7 @@ struct isc_taskmgr {
unsigned int tasks_running;
isc_boolean_t exclusive_requested;
isc_boolean_t exiting;
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
unsigned int refs;
#endif /* ISC_PLATFORM_USETHREADS */
};
@@ -132,17 +161,116 @@ struct isc_taskmgr {
#define DEFAULT_DEFAULT_QUANTUM 5
#define FINISHED(m) ((m)->exiting && EMPTY((m)->tasks))
-#ifndef ISC_PLATFORM_USETHREADS
-static isc_taskmgr_t *taskmgr = NULL;
-#endif /* ISC_PLATFORM_USETHREADS */
+#ifdef USE_SHARED_MANAGER
+static isc__taskmgr_t *taskmgr = NULL;
+#endif /* USE_SHARED_MANAGER */
+
+/*%
+ * The following can be either static or public, depending on build environment.
+ */
+
+#ifdef BIND9
+#define ISC_TASKFUNC_SCOPE
+#else
+#define ISC_TASKFUNC_SCOPE static
+#endif
+
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_create(isc_taskmgr_t *manager0, unsigned int quantum,
+ isc_task_t **taskp);
+ISC_TASKFUNC_SCOPE void
+isc__task_attach(isc_task_t *source0, isc_task_t **targetp);
+ISC_TASKFUNC_SCOPE void
+isc__task_detach(isc_task_t **taskp);
+ISC_TASKFUNC_SCOPE void
+isc__task_send(isc_task_t *task0, isc_event_t **eventp);
+ISC_TASKFUNC_SCOPE void
+isc__task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag);
+ISC_TASKFUNC_SCOPE isc_boolean_t
+isc__task_purgeevent(isc_task_t *task0, isc_event_t *event);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag,
+ isc_eventlist_t *events);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events);
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_onshutdown(isc_task_t *task0, isc_taskaction_t action,
+ const void *arg);
+ISC_TASKFUNC_SCOPE void
+isc__task_shutdown(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void
+isc__task_destroy(isc_task_t **taskp);
+ISC_TASKFUNC_SCOPE void
+isc__task_setname(isc_task_t *task0, const char *name, void *tag);
+ISC_TASKFUNC_SCOPE const char *
+isc__task_getname(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void *
+isc__task_gettag(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void
+isc__task_getcurrenttime(isc_task_t *task0, isc_stdtime_t *t);
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum, isc_taskmgr_t **managerp);
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_destroy(isc_taskmgr_t **managerp);
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_beginexclusive(isc_task_t *task);
+ISC_TASKFUNC_SCOPE void
+isc__task_endexclusive(isc_task_t *task0);
+
+static struct isc__taskmethods {
+ isc_taskmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *purgeevent, *unsendrange, *getname, *gettag, *getcurrenttime;
+#endif
+} taskmethods = {
+ {
+ isc__task_attach,
+ isc__task_detach,
+ isc__task_destroy,
+ isc__task_send,
+ isc__task_sendanddetach,
+ isc__task_unsend,
+ isc__task_onshutdown,
+ isc__task_shutdown,
+ isc__task_setname,
+ isc__task_purge,
+ isc__task_purgerange,
+ isc__task_beginexclusive,
+ isc__task_endexclusive
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__task_purgeevent, (void *)isc__task_unsendrange,
+ (void *)isc__task_getname, (void *)isc__task_gettag,
+ (void *)isc__task_getcurrenttime
+#endif
+};
+
+static isc_taskmgrmethods_t taskmgrmethods = {
+ isc__taskmgr_destroy,
+ isc__task_create
+};
/***
*** Tasks.
***/
static void
-task_finished(isc_task_t *task) {
- isc_taskmgr_t *manager = task->manager;
+task_finished(isc__task_t *task) {
+ isc__taskmgr_t *manager = task->manager;
REQUIRE(EMPTY(task->events));
REQUIRE(EMPTY(task->on_shutdown));
@@ -153,7 +281,7 @@ task_finished(isc_task_t *task) {
LOCK(&manager->lock);
UNLINK(manager->tasks, task, link);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
if (FINISHED(manager)) {
/*
* All tasks have completed and the
@@ -163,19 +291,21 @@ task_finished(isc_task_t *task) {
*/
BROADCAST(&manager->work_available);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
UNLOCK(&manager->lock);
DESTROYLOCK(&task->lock);
- task->magic = 0;
+ task->common.impmagic = 0;
+ task->common.magic = 0;
isc_mem_put(manager->mctx, task, sizeof(*task));
}
-isc_result_t
-isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
- isc_task_t **taskp)
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_create(isc_taskmgr_t *manager0, unsigned int quantum,
+ isc_task_t **taskp)
{
- isc_task_t *task;
+ isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
+ isc__task_t *task;
isc_boolean_t exiting;
isc_result_t result;
@@ -220,14 +350,17 @@ isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
return (ISC_R_SHUTTINGDOWN);
}
- task->magic = TASK_MAGIC;
- *taskp = task;
+ task->common.methods = (isc_taskmethods_t *)&taskmethods;
+ task->common.magic = ISCAPI_TASK_MAGIC;
+ task->common.impmagic = TASK_MAGIC;
+ *taskp = (isc_task_t *)task;
return (ISC_R_SUCCESS);
}
-void
-isc_task_attach(isc_task_t *source, isc_task_t **targetp) {
+ISC_TASKFUNC_SCOPE void
+isc__task_attach(isc_task_t *source0, isc_task_t **targetp) {
+ isc__task_t *source = (isc__task_t *)source0;
/*
* Attach *targetp to source.
@@ -242,11 +375,11 @@ isc_task_attach(isc_task_t *source, isc_task_t **targetp) {
source->references++;
UNLOCK(&source->lock);
- *targetp = source;
+ *targetp = (isc_task_t *)source;
}
static inline isc_boolean_t
-task_shutdown(isc_task_t *task) {
+task_shutdown(isc__task_t *task) {
isc_boolean_t was_idle = ISC_FALSE;
isc_event_t *event, *prev;
@@ -283,8 +416,8 @@ task_shutdown(isc_task_t *task) {
}
static inline void
-task_ready(isc_task_t *task) {
- isc_taskmgr_t *manager = task->manager;
+task_ready(isc__task_t *task) {
+ isc__taskmgr_t *manager = task->manager;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(task->state == task_state_ready);
@@ -294,15 +427,15 @@ task_ready(isc_task_t *task) {
LOCK(&manager->lock);
ENQUEUE(manager->ready_tasks, task, ready_link);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
SIGNAL(&manager->work_available);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
UNLOCK(&manager->lock);
}
static inline isc_boolean_t
-task_detach(isc_task_t *task) {
+task_detach(isc__task_t *task) {
/*
* Caller must be holding the task lock.
@@ -330,9 +463,9 @@ task_detach(isc_task_t *task) {
return (ISC_FALSE);
}
-void
-isc_task_detach(isc_task_t **taskp) {
- isc_task_t *task;
+ISC_TASKFUNC_SCOPE void
+isc__task_detach(isc_task_t **taskp) {
+ isc__task_t *task;
isc_boolean_t was_idle;
/*
@@ -340,7 +473,7 @@ isc_task_detach(isc_task_t **taskp) {
*/
REQUIRE(taskp != NULL);
- task = *taskp;
+ task = (isc__task_t *)*taskp;
REQUIRE(VALID_TASK(task));
XTRACE("isc_task_detach");
@@ -356,7 +489,7 @@ isc_task_detach(isc_task_t **taskp) {
}
static inline isc_boolean_t
-task_send(isc_task_t *task, isc_event_t **eventp) {
+task_send(isc__task_t *task, isc_event_t **eventp) {
isc_boolean_t was_idle = ISC_FALSE;
isc_event_t *event;
@@ -385,8 +518,9 @@ task_send(isc_task_t *task, isc_event_t **eventp) {
return (was_idle);
}
-void
-isc_task_send(isc_task_t *task, isc_event_t **eventp) {
+ISC_TASKFUNC_SCOPE void
+isc__task_send(isc_task_t *task0, isc_event_t **eventp) {
+ isc__task_t *task = (isc__task_t *)task0;
isc_boolean_t was_idle;
/*
@@ -426,10 +560,10 @@ isc_task_send(isc_task_t *task, isc_event_t **eventp) {
}
}
-void
-isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
+ISC_TASKFUNC_SCOPE void
+isc__task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
isc_boolean_t idle1, idle2;
- isc_task_t *task;
+ isc__task_t *task;
/*
* Send '*event' to '*taskp' and then detach '*taskp' from its
@@ -437,7 +571,7 @@ isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
*/
REQUIRE(taskp != NULL);
- task = *taskp;
+ task = (isc__task_t *)*taskp;
REQUIRE(VALID_TASK(task));
XTRACE("isc_task_sendanddetach");
@@ -463,7 +597,7 @@ isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
#define PURGE_OK(event) (((event)->ev_attributes & ISC_EVENTATTR_NOPURGE) == 0)
static unsigned int
-dequeue_events(isc_task_t *task, void *sender, isc_eventtype_t first,
+dequeue_events(isc__task_t *task, void *sender, isc_eventtype_t first,
isc_eventtype_t last, void *tag,
isc_eventlist_t *events, isc_boolean_t purging)
{
@@ -502,10 +636,11 @@ dequeue_events(isc_task_t *task, void *sender, isc_eventtype_t first,
return (count);
}
-unsigned int
-isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
- isc_eventtype_t last, void *tag)
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag)
{
+ isc__task_t *task = (isc__task_t *)task0;
unsigned int count;
isc_eventlist_t events;
isc_event_t *event, *next_event;
@@ -533,9 +668,9 @@ isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
return (count);
}
-unsigned int
-isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
- void *tag)
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag)
{
/*
* Purge events from a task's event queue.
@@ -543,11 +678,12 @@ isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
XTRACE("isc_task_purge");
- return (isc_task_purgerange(task, sender, type, type, tag));
+ return (isc__task_purgerange(task, sender, type, type, tag));
}
-isc_boolean_t
-isc_task_purgeevent(isc_task_t *task, isc_event_t *event) {
+ISC_TASKFUNC_SCOPE isc_boolean_t
+isc__task_purgeevent(isc_task_t *task0, isc_event_t *event) {
+ isc__task_t *task = (isc__task_t *)task0;
isc_event_t *curr_event, *next_event;
/*
@@ -588,10 +724,10 @@ isc_task_purgeevent(isc_task_t *task, isc_event_t *event) {
return (ISC_TRUE);
}
-unsigned int
-isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
- isc_eventtype_t last, void *tag,
- isc_eventlist_t *events)
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag,
+ isc_eventlist_t *events)
{
/*
* Remove events from a task's event queue.
@@ -599,13 +735,13 @@ isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
XTRACE("isc_task_unsendrange");
- return (dequeue_events(task, sender, first, last, tag, events,
- ISC_FALSE));
+ return (dequeue_events((isc__task_t *)task, sender, first,
+ last, tag, events, ISC_FALSE));
}
-unsigned int
-isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
- void *tag, isc_eventlist_t *events)
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events)
{
/*
* Remove events from a task's event queue.
@@ -613,13 +749,15 @@ isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
XTRACE("isc_task_unsend");
- return (dequeue_events(task, sender, type, type, tag, events,
- ISC_FALSE));
+ return (dequeue_events((isc__task_t *)task, sender, type,
+ type, tag, events, ISC_FALSE));
}
-isc_result_t
-isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg)
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_onshutdown(isc_task_t *task0, isc_taskaction_t action,
+ const void *arg)
{
+ isc__task_t *task = (isc__task_t *)task0;
isc_boolean_t disallowed = ISC_FALSE;
isc_result_t result = ISC_R_SUCCESS;
isc_event_t *event;
@@ -655,8 +793,9 @@ isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg)
return (result);
}
-void
-isc_task_shutdown(isc_task_t *task) {
+ISC_TASKFUNC_SCOPE void
+isc__task_shutdown(isc_task_t *task0) {
+ isc__task_t *task = (isc__task_t *)task0;
isc_boolean_t was_idle;
/*
@@ -673,8 +812,8 @@ isc_task_shutdown(isc_task_t *task) {
task_ready(task);
}
-void
-isc_task_destroy(isc_task_t **taskp) {
+ISC_TASKFUNC_SCOPE void
+isc__task_destroy(isc_task_t **taskp) {
/*
* Destroy '*taskp'.
@@ -686,8 +825,9 @@ isc_task_destroy(isc_task_t **taskp) {
isc_task_detach(taskp);
}
-void
-isc_task_setname(isc_task_t *task, const char *name, void *tag) {
+ISC_TASKFUNC_SCOPE void
+isc__task_setname(isc_task_t *task0, const char *name, void *tag) {
+ isc__task_t *task = (isc__task_t *)task0;
/*
* Name 'task'.
@@ -702,18 +842,28 @@ isc_task_setname(isc_task_t *task, const char *name, void *tag) {
UNLOCK(&task->lock);
}
-const char *
-isc_task_getname(isc_task_t *task) {
+ISC_TASKFUNC_SCOPE const char *
+isc__task_getname(isc_task_t *task0) {
+ isc__task_t *task = (isc__task_t *)task0;
+
+ REQUIRE(VALID_TASK(task));
+
return (task->name);
}
-void *
-isc_task_gettag(isc_task_t *task) {
+ISC_TASKFUNC_SCOPE void *
+isc__task_gettag(isc_task_t *task0) {
+ isc__task_t *task = (isc__task_t *)task0;
+
+ REQUIRE(VALID_TASK(task));
+
return (task->tag);
}
-void
-isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t) {
+ISC_TASKFUNC_SCOPE void
+isc__task_getcurrenttime(isc_task_t *task0, isc_stdtime_t *t) {
+ isc__task_t *task = (isc__task_t *)task0;
+
REQUIRE(VALID_TASK(task));
REQUIRE(t != NULL);
@@ -728,12 +878,12 @@ isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t) {
*** Task Manager.
***/
static void
-dispatch(isc_taskmgr_t *manager) {
- isc_task_t *task;
-#ifndef ISC_PLATFORM_USETHREADS
+dispatch(isc__taskmgr_t *manager) {
+ isc__task_t *task;
+#ifndef USE_WORKER_THREADS
unsigned int total_dispatch_count = 0;
- isc_tasklist_t ready_tasks;
-#endif /* ISC_PLATFORM_USETHREADS */
+ isc__tasklist_t ready_tasks;
+#endif /* USE_WORKER_THREADS */
REQUIRE(VALID_MANAGER(manager));
@@ -787,12 +937,12 @@ dispatch(isc_taskmgr_t *manager) {
* unlocks. The while expression is always protected by the lock.
*/
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
ISC_LIST_INIT(ready_tasks);
#endif
LOCK(&manager->lock);
while (!FINISHED(manager)) {
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
/*
* For reasons similar to those given in the comment in
* isc_task_send() above, it is safe for us to dequeue
@@ -812,11 +962,11 @@ dispatch(isc_taskmgr_t *manager) {
ISC_MSGSET_TASK,
ISC_MSG_AWAKE, "awake"));
}
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WORKER_THREADS */
if (total_dispatch_count >= DEFAULT_TASKMGR_QUANTUM ||
EMPTY(manager->ready_tasks))
break;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK,
ISC_MSG_WORKING, "working"));
@@ -859,13 +1009,15 @@ dispatch(isc_taskmgr_t *manager) {
"execute action"));
if (event->ev_action != NULL) {
UNLOCK(&task->lock);
- (event->ev_action)(task,event);
+ (event->ev_action)(
+ (isc_task_t *)task,
+ event);
LOCK(&task->lock);
}
dispatch_count++;
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
total_dispatch_count++;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
}
if (task->references == 0 &&
@@ -950,12 +1102,12 @@ dispatch(isc_taskmgr_t *manager) {
LOCK(&manager->lock);
manager->tasks_running--;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
if (manager->exclusive_requested &&
manager->tasks_running == 1) {
SIGNAL(&manager->exclusive_granted);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
if (requeue) {
/*
* We know we're awake, so we don't have
@@ -976,7 +1128,7 @@ dispatch(isc_taskmgr_t *manager) {
* were usually nonempty, the 'optimization'
* might even hurt rather than help.
*/
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
ENQUEUE(manager->ready_tasks, task,
ready_link);
#else
@@ -985,19 +1137,19 @@ dispatch(isc_taskmgr_t *manager) {
}
}
}
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
ISC_LIST_APPENDLIST(manager->ready_tasks, ready_tasks, ready_link);
#endif
UNLOCK(&manager->lock);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
static isc_threadresult_t
#ifdef _WIN32
WINAPI
#endif
run(void *uap) {
- isc_taskmgr_t *manager = uap;
+ isc__taskmgr_t *manager = uap;
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_STARTING, "starting"));
@@ -1007,33 +1159,42 @@ run(void *uap) {
XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_EXITING, "exiting"));
+#ifdef OPENSSL_LEAKS
+ ERR_remove_state(0);
+#endif
+
return ((isc_threadresult_t)0);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
static void
-manager_free(isc_taskmgr_t *manager) {
+manager_free(isc__taskmgr_t *manager) {
isc_mem_t *mctx;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
(void)isc_condition_destroy(&manager->exclusive_granted);
(void)isc_condition_destroy(&manager->work_available);
isc_mem_free(manager->mctx, manager->threads);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
DESTROYLOCK(&manager->lock);
- manager->magic = 0;
+ manager->common.impmagic = 0;
+ manager->common.magic = 0;
mctx = manager->mctx;
isc_mem_put(mctx, manager, sizeof(*manager));
isc_mem_detach(&mctx);
+
+#ifdef USE_SHARED_MANAGER
+ taskmgr = NULL;
+#endif /* USE_SHARED_MANAGER */
}
-isc_result_t
-isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
- unsigned int default_quantum, isc_taskmgr_t **managerp)
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum, isc_taskmgr_t **managerp)
{
isc_result_t result;
unsigned int i, started = 0;
- isc_taskmgr_t *manager;
+ isc__taskmgr_t *manager;
/*
* Create a new task manager.
@@ -1042,28 +1203,33 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
REQUIRE(workers > 0);
REQUIRE(managerp != NULL && *managerp == NULL);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
UNUSED(i);
UNUSED(started);
- UNUSED(workers);
+#endif
+#ifdef USE_SHARED_MANAGER
if (taskmgr != NULL) {
+ if (taskmgr->refs == 0)
+ return (ISC_R_SHUTTINGDOWN);
taskmgr->refs++;
- *managerp = taskmgr;
+ *managerp = (isc_taskmgr_t *)taskmgr;
return (ISC_R_SUCCESS);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
manager = isc_mem_get(mctx, sizeof(*manager));
if (manager == NULL)
return (ISC_R_NOMEMORY);
- manager->magic = TASK_MANAGER_MAGIC;
+ manager->common.methods = &taskmgrmethods;
+ manager->common.impmagic = TASK_MANAGER_MAGIC;
+ manager->common.magic = ISCAPI_TASKMGR_MAGIC;
manager->mctx = NULL;
result = isc_mutex_init(&manager->lock);
if (result != ISC_R_SUCCESS)
goto cleanup_mgr;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
manager->workers = 0;
manager->threads = isc_mem_allocate(mctx,
workers * sizeof(isc_thread_t));
@@ -1087,7 +1253,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
result = ISC_R_UNEXPECTED;
goto cleanup_workavailable;
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
if (default_quantum == 0)
default_quantum = DEFAULT_DEFAULT_QUANTUM;
manager->default_quantum = default_quantum;
@@ -1099,7 +1265,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
isc_mem_attach(mctx, &manager->mctx);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
LOCK(&manager->lock);
/*
* Start workers.
@@ -1119,16 +1285,17 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
return (ISC_R_NOTHREADS);
}
isc_thread_setconcurrency(workers);
-#else /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
+#ifdef USE_SHARED_MANAGER
manager->refs = 1;
taskmgr = manager;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
- *managerp = manager;
+ *managerp = (isc_taskmgr_t *)manager;
return (ISC_R_SUCCESS);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
cleanup_workavailable:
(void)isc_condition_destroy(&manager->work_available);
cleanup_threads:
@@ -1141,10 +1308,10 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
return (result);
}
-void
-isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
- isc_taskmgr_t *manager;
- isc_task_t *task;
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_destroy(isc_taskmgr_t **managerp) {
+ isc__taskmgr_t *manager;
+ isc__task_t *task;
unsigned int i;
/*
@@ -1152,18 +1319,20 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
*/
REQUIRE(managerp != NULL);
- manager = *managerp;
+ manager = (isc__taskmgr_t *)*managerp;
REQUIRE(VALID_MANAGER(manager));
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
UNUSED(i);
+#endif /* USE_WORKER_THREADS */
- if (manager->refs > 1) {
- manager->refs--;
+#ifdef USE_SHARED_MANAGER
+ manager->refs--;
+ if (manager->refs > 0) {
*managerp = NULL;
return;
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif
XTHREADTRACE("isc_taskmgr_destroy");
/*
@@ -1203,7 +1372,7 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
ENQUEUE(manager->ready_tasks, task, ready_link);
UNLOCK(&task->lock);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WORKER_THREADS
/*
* Wake up any sleeping workers. This ensures we get work done if
* there's work left to do, and if there are already no tasks left
@@ -1217,36 +1386,51 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
*/
for (i = 0; i < manager->workers; i++)
(void)isc_thread_join(manager->threads[i], NULL);
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WORKER_THREADS */
/*
* Dispatch the shutdown events.
*/
UNLOCK(&manager->lock);
- while (isc__taskmgr_ready())
- (void)isc__taskmgr_dispatch();
+ while (isc__taskmgr_ready((isc_taskmgr_t *)manager))
+ (void)isc__taskmgr_dispatch((isc_taskmgr_t *)manager);
+#ifdef BIND9
if (!ISC_LIST_EMPTY(manager->tasks))
isc_mem_printallactive(stderr);
+#endif
INSIST(ISC_LIST_EMPTY(manager->tasks));
-#endif /* ISC_PLATFORM_USETHREADS */
+#ifdef USE_SHARED_MANAGER
+ taskmgr = NULL;
+#endif
+#endif /* USE_WORKER_THREADS */
manager_free(manager);
*managerp = NULL;
}
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WORKER_THREADS
isc_boolean_t
-isc__taskmgr_ready(void) {
- if (taskmgr == NULL)
+isc__taskmgr_ready(isc_taskmgr_t *manager0) {
+ isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
+
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = taskmgr;
+#endif
+ if (manager == NULL)
return (ISC_FALSE);
- return (ISC_TF(!ISC_LIST_EMPTY(taskmgr->ready_tasks)));
+ return (ISC_TF(!ISC_LIST_EMPTY(manager->ready_tasks)));
}
isc_result_t
-isc__taskmgr_dispatch(void) {
- isc_taskmgr_t *manager = taskmgr;
+isc__taskmgr_dispatch(isc_taskmgr_t *manager0) {
+ isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
- if (taskmgr == NULL)
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = taskmgr;
+#endif
+ if (manager == NULL)
return (ISC_R_NOTFOUND);
dispatch(manager);
@@ -1254,12 +1438,13 @@ isc__taskmgr_dispatch(void) {
return (ISC_R_SUCCESS);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WORKER_THREADS */
-isc_result_t
-isc_task_beginexclusive(isc_task_t *task) {
-#ifdef ISC_PLATFORM_USETHREADS
- isc_taskmgr_t *manager = task->manager;
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_beginexclusive(isc_task_t *task0) {
+#ifdef USE_WORKER_THREADS
+ isc__task_t *task = (isc__task_t *)task0;
+ isc__taskmgr_t *manager = task->manager;
REQUIRE(task->state == task_state_running);
LOCK(&manager->lock);
if (manager->exclusive_requested) {
@@ -1272,15 +1457,17 @@ isc_task_beginexclusive(isc_task_t *task) {
}
UNLOCK(&manager->lock);
#else
- UNUSED(task);
+ UNUSED(task0);
#endif
return (ISC_R_SUCCESS);
}
-void
-isc_task_endexclusive(isc_task_t *task) {
-#ifdef ISC_PLATFORM_USETHREADS
- isc_taskmgr_t *manager = task->manager;
+ISC_TASKFUNC_SCOPE void
+isc__task_endexclusive(isc_task_t *task0) {
+#ifdef USE_WORKER_THREADS
+ isc__task_t *task = (isc__task_t *)task0;
+ isc__taskmgr_t *manager = task->manager;
+
REQUIRE(task->state == task_state_running);
LOCK(&manager->lock);
REQUIRE(manager->exclusive_requested);
@@ -1288,23 +1475,31 @@ isc_task_endexclusive(isc_task_t *task) {
BROADCAST(&manager->work_available);
UNLOCK(&manager->lock);
#else
- UNUSED(task);
+ UNUSED(task0);
#endif
}
+#ifdef USE_SOCKETIMPREGISTER
+isc_result_t
+isc__task_register() {
+ return (isc_task_register(isc__taskmgr_create));
+}
+#endif
+
isc_boolean_t
isc_task_exiting(isc_task_t *t) {
- isc_task_t *task = (isc_task_t *)t;
+ isc__task_t *task = (isc__task_t *)t;
REQUIRE(VALID_TASK(task));
return (TASK_SHUTTINGDOWN(task));
}
-#ifdef HAVE_LIBXML2
+
+#if defined(HAVE_LIBXML2) && defined(BIND9)
void
-isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer)
-{
- isc_task_t *task;
+isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
+ isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0;
+ isc__task_t *task;
LOCK(&mgr->lock);
@@ -1380,4 +1575,4 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer)
UNLOCK(&mgr->lock);
}
-#endif /* HAVE_LIBXML2 */
+#endif /* HAVE_LIBXML2 && BIND9 */
diff --git a/lib/isc/task_api.c b/lib/isc/task_api.c
new file mode 100644
index 000000000000..4e03db247f2c
--- /dev/null
+++ b/lib/isc/task_api.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: task_api.c,v 1.7 2010-12-22 23:46:59 tbox Exp $ */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <isc/app.h>
+#include <isc/magic.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/task.h>
+#include <isc/util.h>
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_taskmgrcreatefunc_t taskmgr_createfunc = NULL;
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_task_register(isc_taskmgrcreatefunc_t createfunc) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+ if (taskmgr_createfunc == NULL)
+ taskmgr_createfunc = createfunc;
+ else
+ result = ISC_R_EXISTS;
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ unsigned int workers, unsigned int default_quantum,
+ isc_taskmgr_t **managerp)
+{
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(taskmgr_createfunc != NULL);
+ result = (*taskmgr_createfunc)(mctx, workers, default_quantum,
+ managerp);
+
+ UNLOCK(&createlock);
+
+ if (result == ISC_R_SUCCESS)
+ isc_appctx_settaskmgr(actx, *managerp);
+
+ return (result);
+}
+
+isc_result_t
+isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum, isc_taskmgr_t **managerp)
+{
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(taskmgr_createfunc != NULL);
+ result = (*taskmgr_createfunc)(mctx, workers, default_quantum,
+ managerp);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
+ REQUIRE(managerp != NULL && ISCAPI_TASKMGR_VALID(*managerp));
+
+ (*managerp)->methods->destroy(managerp);
+
+ ENSURE(*managerp == NULL);
+}
+
+isc_result_t
+isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
+ isc_task_t **taskp)
+{
+ REQUIRE(ISCAPI_TASKMGR_VALID(manager));
+ REQUIRE(taskp != NULL && *taskp == NULL);
+
+ return (manager->methods->taskcreate(manager, quantum, taskp));
+}
+
+void
+isc_task_attach(isc_task_t *source, isc_task_t **targetp) {
+ REQUIRE(ISCAPI_TASK_VALID(source));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+
+ source->methods->attach(source, targetp);
+
+ ENSURE(*targetp == source);
+}
+
+void
+isc_task_detach(isc_task_t **taskp) {
+ REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp));
+
+ (*taskp)->methods->detach(taskp);
+
+ ENSURE(*taskp == NULL);
+}
+
+void
+isc_task_send(isc_task_t *task, isc_event_t **eventp) {
+ REQUIRE(ISCAPI_TASK_VALID(task));
+ REQUIRE(eventp != NULL && *eventp != NULL);
+
+ task->methods->send(task, eventp);
+
+ ENSURE(*eventp == NULL);
+}
+
+void
+isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
+ REQUIRE(taskp != NULL && ISCAPI_TASK_VALID(*taskp));
+ REQUIRE(eventp != NULL && *eventp != NULL);
+
+ (*taskp)->methods->sendanddetach(taskp, eventp);
+
+ ENSURE(*taskp == NULL && *eventp == NULL);
+}
+
+unsigned int
+isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events)
+{
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ return (task->methods->unsend(task, sender, type, tag, events));
+}
+
+isc_result_t
+isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, const void *arg)
+{
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ return (task->methods->onshutdown(task, action, arg));
+}
+
+void
+isc_task_shutdown(isc_task_t *task) {
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ task->methods->shutdown(task);
+}
+
+void
+isc_task_setname(isc_task_t *task, const char *name, void *tag) {
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ task->methods->setname(task, name, tag);
+}
+
+unsigned int
+isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag)
+{
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ return (task->methods->purgeevents(task, sender, type, tag));
+}
+
+isc_result_t
+isc_task_beginexclusive(isc_task_t *task) {
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ return (task->methods->beginexclusive(task));
+}
+
+void
+isc_task_endexclusive(isc_task_t *task) {
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ task->methods->endexclusive(task);
+}
+
+
+/*%
+ * This is necessary for libisc's internal timer implementation. Other
+ * implementation might skip implementing this.
+ */
+unsigned int
+isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag)
+{
+ REQUIRE(ISCAPI_TASK_VALID(task));
+
+ return (task->methods->purgerange(task, sender, first, last, tag));
+}
diff --git a/lib/isc/task_p.h b/lib/isc/task_p.h
index 7bf208ada747..1bcdca65ef3a 100644
--- a/lib/isc/task_p.h
+++ b/lib/isc/task_p.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: task_p.h,v 1.11 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: task_p.h,v 1.13 2009-09-02 23:48:02 tbox Exp $ */
#ifndef ISC_TASK_P_H
#define ISC_TASK_P_H
@@ -23,9 +23,9 @@
/*! \file */
isc_boolean_t
-isc__taskmgr_ready(void);
+isc__taskmgr_ready(isc_taskmgr_t *taskmgr);
isc_result_t
-isc__taskmgr_dispatch(void);
+isc__taskmgr_dispatch(isc_taskmgr_t *taskmgr);
#endif /* ISC_TASK_P_H */
diff --git a/lib/isc/timer.c b/lib/isc/timer.c
index 634268831dec..ab89cddaf8fb 100644
--- a/lib/isc/timer.c
+++ b/lib/isc/timer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: timer.c,v 1.84.58.4 2009-01-23 23:47:21 tbox Exp $ */
+/* $Id: timer.c,v 1.95.302.1.2.1 2011-06-02 23:47:36 tbox Exp $ */
/*! \file */
@@ -34,9 +34,22 @@
#include <isc/timer.h>
#include <isc/util.h>
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef OPENSSL_LEAKS
+#include <openssl/err.h>
+#endif
+
+/* See task.c about the following definition: */
+#ifdef BIND9
+#ifdef ISC_PLATFORM_USETHREADS
+#define USE_TIMER_THREAD
+#else
+#define USE_SHARED_MANAGER
+#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* BIND9 */
+
+#ifndef USE_TIMER_THREAD
#include "timer_p.h"
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
#ifdef ISC_TIMER_TRACE
#define XTRACE(s) fprintf(stderr, "%s\n", (s))
@@ -58,10 +71,13 @@
#define TIMER_MAGIC ISC_MAGIC('T', 'I', 'M', 'R')
#define VALID_TIMER(t) ISC_MAGIC_VALID(t, TIMER_MAGIC)
-struct isc_timer {
+typedef struct isc__timer isc__timer_t;
+typedef struct isc__timermgr isc__timermgr_t;
+
+struct isc__timer {
/*! Not locked. */
- unsigned int magic;
- isc_timermgr_t * manager;
+ isc_timer_t common;
+ isc__timermgr_t * manager;
isc_mutex_t lock;
/*! Locked by timer lock. */
unsigned int references;
@@ -75,45 +91,119 @@ struct isc_timer {
void * arg;
unsigned int index;
isc_time_t due;
- LINK(isc_timer_t) link;
+ LINK(isc__timer_t) link;
};
#define TIMER_MANAGER_MAGIC ISC_MAGIC('T', 'I', 'M', 'M')
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TIMER_MANAGER_MAGIC)
-struct isc_timermgr {
+struct isc__timermgr {
/* Not locked. */
- unsigned int magic;
+ isc_timermgr_t common;
isc_mem_t * mctx;
isc_mutex_t lock;
/* Locked by manager lock. */
isc_boolean_t done;
- LIST(isc_timer_t) timers;
+ LIST(isc__timer_t) timers;
unsigned int nscheduled;
isc_time_t due;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
isc_condition_t wakeup;
isc_thread_t thread;
-#else /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
+#ifdef USE_SHARED_MANAGER
unsigned int refs;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
isc_heap_t * heap;
};
-#ifndef ISC_PLATFORM_USETHREADS
+/*%
+ * The followings can be either static or public, depending on build
+ * environment.
+ */
+
+#ifdef BIND9
+#define ISC_TIMERFUNC_SCOPE
+#else
+#define ISC_TIMERFUNC_SCOPE static
+#endif
+
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_create(isc_timermgr_t *manager, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_timer_t **timerp);
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_reset(isc_timer_t *timer, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_boolean_t purge);
+ISC_TIMERFUNC_SCOPE isc_timertype_t
+isc__timer_gettype(isc_timer_t *timer);
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_touch(isc_timer_t *timer);
+ISC_TIMERFUNC_SCOPE void
+isc__timer_attach(isc_timer_t *timer0, isc_timer_t **timerp);
+ISC_TIMERFUNC_SCOPE void
+isc__timer_detach(isc_timer_t **timerp);
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
+ISC_TIMERFUNC_SCOPE void
+isc__timermgr_poke(isc_timermgr_t *manager0);
+ISC_TIMERFUNC_SCOPE void
+isc__timermgr_destroy(isc_timermgr_t **managerp);
+
+static struct isc__timermethods {
+ isc_timermethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *gettype;
+#endif
+} timermethods = {
+ {
+ isc__timer_attach,
+ isc__timer_detach,
+ isc__timer_reset,
+ isc__timer_touch
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__timer_gettype
+#endif
+};
+
+static struct isc__timermgrmethods {
+ isc_timermgrmethods_t methods;
+#ifndef BIND9
+ void *poke; /* see above */
+#endif
+} timermgrmethods = {
+ {
+ isc__timermgr_destroy,
+ isc__timer_create
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__timermgr_poke
+#endif
+};
+
+#ifdef USE_SHARED_MANAGER
/*!
- * If threads are not in use, there can be only one.
+ * If the manager is supposed to be shared, there can be only one.
*/
-static isc_timermgr_t *timermgr = NULL;
-#endif /* ISC_PLATFORM_USETHREADS */
+static isc__timermgr_t *timermgr = NULL;
+#endif /* USE_SHARED_MANAGER */
static inline isc_result_t
-schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
+schedule(isc__timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
isc_result_t result;
- isc_timermgr_t *manager;
+ isc__timermgr_t *manager;
isc_time_t due;
int cmp;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
isc_boolean_t timedwait;
#endif
@@ -123,13 +213,13 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
REQUIRE(timer->type != isc_timertype_inactive);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_TIMER_THREAD
UNUSED(signal_ok);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
manager = timer->manager;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
/*!
* If the manager was timed wait, we may need to signal the
* manager to force a wakeup.
@@ -199,7 +289,7 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
* the current "next" timer. We do this either by waking up the
* run thread, or explicitly setting the value in the manager.
*/
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
/*
* This is a temporary (probably) hack to fix a bug on tru64 5.1
@@ -232,19 +322,19 @@ schedule(isc_timer_t *timer, isc_time_t *now, isc_boolean_t signal_ok) {
"signal (schedule)"));
SIGNAL(&manager->wakeup);
}
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_TIMER_THREAD */
if (timer->index == 1 &&
isc_time_compare(&timer->due, &manager->due) < 0)
manager->due = timer->due;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
return (ISC_R_SUCCESS);
}
static inline void
-deschedule(isc_timer_t *timer) {
+deschedule(isc__timer_t *timer) {
isc_boolean_t need_wakeup = ISC_FALSE;
- isc_timermgr_t *manager;
+ isc__timermgr_t *manager;
/*
* The caller must ensure locking.
@@ -258,20 +348,20 @@ deschedule(isc_timer_t *timer) {
timer->index = 0;
INSIST(manager->nscheduled > 0);
manager->nscheduled--;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
if (need_wakeup) {
XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER,
ISC_MSG_SIGNALDESCHED,
"signal (deschedule)"));
SIGNAL(&manager->wakeup);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
}
}
static void
-destroy(isc_timer_t *timer) {
- isc_timermgr_t *manager = timer->manager;
+destroy(isc__timer_t *timer) {
+ isc__timermgr_t *manager = timer->manager;
/*
* The caller must ensure it is safe to destroy the timer.
@@ -291,17 +381,19 @@ destroy(isc_timer_t *timer) {
isc_task_detach(&timer->task);
DESTROYLOCK(&timer->lock);
- timer->magic = 0;
+ timer->common.impmagic = 0;
+ timer->common.magic = 0;
isc_mem_put(manager->mctx, timer, sizeof(*timer));
}
-isc_result_t
-isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
- isc_task_t *task, isc_taskaction_t action, const void *arg,
- isc_timer_t **timerp)
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_timer_t **timerp)
{
- isc_timer_t *timer;
+ isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
+ isc__timer_t *timer;
isc_result_t result;
isc_time_t now;
@@ -382,7 +474,9 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
return (result);
}
ISC_LINK_INIT(timer, link);
- timer->magic = TIMER_MAGIC;
+ timer->common.impmagic = TIMER_MAGIC;
+ timer->common.magic = ISCAPI_TIMER_MAGIC;
+ timer->common.methods = (isc_timermethods_t *)&timermethods;
LOCK(&manager->lock);
@@ -401,25 +495,27 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
UNLOCK(&manager->lock);
if (result != ISC_R_SUCCESS) {
- timer->magic = 0;
+ timer->common.impmagic = 0;
+ timer->common.magic = 0;
DESTROYLOCK(&timer->lock);
isc_task_detach(&timer->task);
isc_mem_put(manager->mctx, timer, sizeof(*timer));
return (result);
}
- *timerp = timer;
+ *timerp = (isc_timer_t *)timer;
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
- isc_boolean_t purge)
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_reset(isc_timer_t *timer0, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_boolean_t purge)
{
+ isc__timer_t *timer = (isc__timer_t *)timer0;
isc_time_t now;
- isc_timermgr_t *manager;
+ isc__timermgr_t *manager;
isc_result_t result;
/*
@@ -489,8 +585,9 @@ isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
return (result);
}
-isc_timertype_t
-isc_timer_gettype(isc_timer_t *timer) {
+ISC_TIMERFUNC_SCOPE isc_timertype_t
+isc__timer_gettype(isc_timer_t *timer0) {
+ isc__timer_t *timer = (isc__timer_t *)timer0;
isc_timertype_t t;
REQUIRE(VALID_TIMER(timer));
@@ -502,8 +599,9 @@ isc_timer_gettype(isc_timer_t *timer) {
return (t);
}
-isc_result_t
-isc_timer_touch(isc_timer_t *timer) {
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timer_touch(isc_timer_t *timer0) {
+ isc__timer_t *timer = (isc__timer_t *)timer0;
isc_result_t result;
isc_time_t now;
@@ -532,8 +630,10 @@ isc_timer_touch(isc_timer_t *timer) {
return (result);
}
-void
-isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp) {
+ISC_TIMERFUNC_SCOPE void
+isc__timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) {
+ isc__timer_t *timer = (isc__timer_t *)timer0;
+
/*
* Attach *timerp to timer.
*/
@@ -545,12 +645,12 @@ isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp) {
timer->references++;
UNLOCK(&timer->lock);
- *timerp = timer;
+ *timerp = (isc_timer_t *)timer;
}
-void
-isc_timer_detach(isc_timer_t **timerp) {
- isc_timer_t *timer;
+ISC_TIMERFUNC_SCOPE void
+isc__timer_detach(isc_timer_t **timerp) {
+ isc__timer_t *timer;
isc_boolean_t free_timer = ISC_FALSE;
/*
@@ -558,7 +658,7 @@ isc_timer_detach(isc_timer_t **timerp) {
*/
REQUIRE(timerp != NULL);
- timer = *timerp;
+ timer = (isc__timer_t *)*timerp;
REQUIRE(VALID_TIMER(timer));
LOCK(&timer->lock);
@@ -575,11 +675,11 @@ isc_timer_detach(isc_timer_t **timerp) {
}
static void
-dispatch(isc_timermgr_t *manager, isc_time_t *now) {
+dispatch(isc__timermgr_t *manager, isc_time_t *now) {
isc_boolean_t done = ISC_FALSE, post_event, need_schedule;
isc_timerevent_t *event;
isc_eventtype_t type = 0;
- isc_timer_t *timer;
+ isc__timer_t *timer;
isc_result_t result;
isc_boolean_t idle;
@@ -693,13 +793,13 @@ dispatch(isc_timermgr_t *manager, isc_time_t *now) {
}
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
static isc_threadresult_t
#ifdef _WIN32 /* XXXDCL */
WINAPI
#endif
run(void *uap) {
- isc_timermgr_t *manager = uap;
+ isc__timermgr_t *manager = uap;
isc_time_t now;
isc_result_t result;
@@ -732,13 +832,17 @@ run(void *uap) {
}
UNLOCK(&manager->lock);
+#ifdef OPENSSL_LEAKS
+ ERR_remove_state(0);
+#endif
+
return ((isc_threadresult_t)0);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
static isc_boolean_t
sooner(void *v1, void *v2) {
- isc_timer_t *t1, *t2;
+ isc__timer_t *t1, *t2;
t1 = v1;
t2 = v2;
@@ -752,7 +856,7 @@ sooner(void *v1, void *v2) {
static void
set_index(void *what, unsigned int index) {
- isc_timer_t *timer;
+ isc__timer_t *timer;
timer = what;
REQUIRE(VALID_TIMER(timer));
@@ -760,9 +864,9 @@ set_index(void *what, unsigned int index) {
timer->index = index;
}
-isc_result_t
-isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
- isc_timermgr_t *manager;
+ISC_TIMERFUNC_SCOPE isc_result_t
+isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
+ isc__timermgr_t *manager;
isc_result_t result;
/*
@@ -771,19 +875,21 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
REQUIRE(managerp != NULL && *managerp == NULL);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
if (timermgr != NULL) {
timermgr->refs++;
- *managerp = timermgr;
+ *managerp = (isc_timermgr_t *)timermgr;
return (ISC_R_SUCCESS);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
manager = isc_mem_get(mctx, sizeof(*manager));
if (manager == NULL)
return (ISC_R_NOMEMORY);
- manager->magic = TIMER_MANAGER_MAGIC;
+ manager->common.impmagic = TIMER_MANAGER_MAGIC;
+ manager->common.magic = ISCAPI_TIMERMGR_MAGIC;
+ manager->common.methods = (isc_timermgrmethods_t *)&timermgrmethods;
manager->mctx = NULL;
manager->done = ISC_FALSE;
INIT_LIST(manager->timers);
@@ -803,7 +909,7 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
return (result);
}
isc_mem_attach(mctx, &manager->mctx);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
if (isc_condition_init(&manager->wakeup) != ISC_R_SUCCESS) {
isc_mem_detach(&manager->mctx);
DESTROYLOCK(&manager->lock);
@@ -828,30 +934,33 @@ isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
ISC_MSG_FAILED, "failed"));
return (ISC_R_UNEXPECTED);
}
-#else /* ISC_PLATFORM_USETHREADS */
+#endif
+#ifdef USE_SHARED_MANAGER
manager->refs = 1;
timermgr = manager;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
- *managerp = manager;
+ *managerp = (isc_timermgr_t *)manager;
return (ISC_R_SUCCESS);
}
-void
-isc_timermgr_poke(isc_timermgr_t *manager) {
-#ifdef ISC_PLATFORM_USETHREADS
+ISC_TIMERFUNC_SCOPE void
+isc__timermgr_poke(isc_timermgr_t *manager0) {
+#ifdef USE_TIMER_THREAD
+ isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
+
REQUIRE(VALID_MANAGER(manager));
SIGNAL(&manager->wakeup);
#else
- UNUSED(manager);
+ UNUSED(manager0);
#endif
}
-void
-isc_timermgr_destroy(isc_timermgr_t **managerp) {
- isc_timermgr_t *manager;
+ISC_TIMERFUNC_SCOPE void
+isc__timermgr_destroy(isc_timermgr_t **managerp) {
+ isc__timermgr_t *manager;
isc_mem_t *mctx;
/*
@@ -859,34 +968,37 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) {
*/
REQUIRE(managerp != NULL);
- manager = *managerp;
+ manager = (isc__timermgr_t *)*managerp;
REQUIRE(VALID_MANAGER(manager));
LOCK(&manager->lock);
-#ifndef ISC_PLATFORM_USETHREADS
- if (manager->refs > 1) {
- manager->refs--;
+#ifdef USE_SHARED_MANAGER
+ manager->refs--;
+ if (manager->refs > 0) {
UNLOCK(&manager->lock);
*managerp = NULL;
return;
}
+ timermgr = NULL;
+#endif /* USE_SHARED_MANAGER */
- isc__timermgr_dispatch();
-#endif /* ISC_PLATFORM_USETHREADS */
+#ifndef USE_TIMER_THREAD
+ isc__timermgr_dispatch((isc_timermgr_t *)manager);
+#endif
REQUIRE(EMPTY(manager->timers));
manager->done = ISC_TRUE;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER,
ISC_MSG_SIGNALDESTROY, "signal (destroy)"));
SIGNAL(&manager->wakeup);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
UNLOCK(&manager->lock);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
/*
* Wait for thread to exit.
*/
@@ -895,39 +1007,63 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) {
"isc_thread_join() %s",
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"));
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
/*
* Clean up.
*/
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_TIMER_THREAD
(void)isc_condition_destroy(&manager->wakeup);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
DESTROYLOCK(&manager->lock);
isc_heap_destroy(&manager->heap);
- manager->magic = 0;
+ manager->common.impmagic = 0;
+ manager->common.magic = 0;
mctx = manager->mctx;
isc_mem_put(mctx, manager, sizeof(*manager));
isc_mem_detach(&mctx);
*managerp = NULL;
+
+#ifdef USE_SHARED_MANAGER
+ timermgr = NULL;
+#endif
}
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_TIMER_THREAD
isc_result_t
-isc__timermgr_nextevent(isc_time_t *when) {
- if (timermgr == NULL || timermgr->nscheduled == 0)
+isc__timermgr_nextevent(isc_timermgr_t *manager0, isc_time_t *when) {
+ isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
+
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = timermgr;
+#endif
+ if (manager == NULL || manager->nscheduled == 0)
return (ISC_R_NOTFOUND);
- *when = timermgr->due;
+ *when = manager->due;
return (ISC_R_SUCCESS);
}
void
-isc__timermgr_dispatch(void) {
+isc__timermgr_dispatch(isc_timermgr_t *manager0) {
+ isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
isc_time_t now;
- if (timermgr == NULL)
+
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = timermgr;
+#endif
+ if (manager == NULL)
return;
TIME_NOW(&now);
- dispatch(timermgr, &now);
+ dispatch(manager, &now);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_TIMER_THREAD */
+
+#ifdef USE_TIMERIMPREGISTER
+isc_result_t
+isc__timer_register() {
+ return (isc_timer_register(isc__timermgr_create));
+}
+#endif
diff --git a/lib/isc/timer_api.c b/lib/isc/timer_api.c
new file mode 100644
index 000000000000..5a9bf9d859ca
--- /dev/null
+++ b/lib/isc/timer_api.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: timer_api.c,v 1.4 2009-09-02 23:48:02 tbox Exp $ */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <isc/app.h>
+#include <isc/magic.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_timermgrcreatefunc_t timermgr_createfunc = NULL;
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_timer_register(isc_timermgrcreatefunc_t createfunc) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+ if (timermgr_createfunc == NULL)
+ timermgr_createfunc = createfunc;
+ else
+ result = ISC_R_EXISTS;
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+isc_result_t
+isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_timermgr_t **managerp)
+{
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(timermgr_createfunc != NULL);
+ result = (*timermgr_createfunc)(mctx, managerp);
+
+ UNLOCK(&createlock);
+
+ if (result == ISC_R_SUCCESS)
+ isc_appctx_settimermgr(actx, *managerp);
+
+ return (result);
+}
+
+isc_result_t
+isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
+ isc_result_t result;
+
+ LOCK(&createlock);
+
+ REQUIRE(timermgr_createfunc != NULL);
+ result = (*timermgr_createfunc)(mctx, managerp);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_timermgr_destroy(isc_timermgr_t **managerp) {
+ REQUIRE(*managerp != NULL && ISCAPI_TIMERMGR_VALID(*managerp));
+
+ (*managerp)->methods->destroy(managerp);
+
+ ENSURE(*managerp == NULL);
+}
+
+isc_result_t
+isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_timer_t **timerp)
+{
+ REQUIRE(ISCAPI_TIMERMGR_VALID(manager));
+
+ return (manager->methods->timercreate(manager, type, expires,
+ interval, task, action, arg,
+ timerp));
+}
+
+void
+isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp) {
+ REQUIRE(ISCAPI_TIMER_VALID(timer));
+ REQUIRE(timerp != NULL && *timerp == NULL);
+
+ timer->methods->attach(timer, timerp);
+
+ ENSURE(*timerp == timer);
+}
+
+void
+isc_timer_detach(isc_timer_t **timerp) {
+ REQUIRE(timerp != NULL && ISCAPI_TIMER_VALID(*timerp));
+
+ (*timerp)->methods->detach(timerp);
+
+ ENSURE(*timerp == NULL);
+}
+
+isc_result_t
+isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_boolean_t purge)
+{
+ REQUIRE(ISCAPI_TIMER_VALID(timer));
+
+ return (timer->methods->reset(timer, type, expires, interval, purge));
+}
+
+isc_result_t
+isc_timer_touch(isc_timer_t *timer) {
+ REQUIRE(ISCAPI_TIMER_VALID(timer));
+
+ return (timer->methods->touch(timer));
+}
diff --git a/lib/isc/timer_p.h b/lib/isc/timer_p.h
index b41f92232765..657b695502b5 100644
--- a/lib/isc/timer_p.h
+++ b/lib/isc/timer_p.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: timer_p.h,v 1.10 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: timer_p.h,v 1.12 2009-09-02 23:48:02 tbox Exp $ */
#ifndef ISC_TIMER_P_H
#define ISC_TIMER_P_H
@@ -23,9 +23,9 @@
/*! \file */
isc_result_t
-isc__timermgr_nextevent(isc_time_t *when);
+isc__timermgr_nextevent(isc_timermgr_t *timermgr, isc_time_t *when);
void
-isc__timermgr_dispatch(void);
+isc__timermgr_dispatch(isc_timermgr_t *timermgr);
#endif /* ISC_TIMER_P_H */
diff --git a/lib/isc/unix/Makefile.in b/lib/isc/unix/Makefile.in
index 7d23b9696846..2c91756f5f14 100644
--- a/lib/isc/unix/Makefile.in
+++ b/lib/isc/unix/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.41 2007-06-19 23:47:18 tbox Exp $
+# $Id: Makefile.in,v 1.44 2009-12-05 23:31:41 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/lib/isc/unix/app.c b/lib/isc/unix/app.c
index 6bd16603d14a..4dc513008253 100644
--- a/lib/isc/unix/app.c
+++ b/lib/isc/unix/app.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: app.c,v 1.60 2008-10-15 03:41:17 marka Exp $ */
+/* $Id: app.c,v 1.64 2009-11-04 05:58:46 marka Exp $ */
/*! \file */
@@ -37,6 +37,7 @@
#include <isc/app.h>
#include <isc/boolean.h>
#include <isc/condition.h>
+#include <isc/mem.h>
#include <isc/msgs.h>
#include <isc/mutex.h>
#include <isc/event.h>
@@ -47,31 +48,129 @@
#include <isc/time.h>
#include <isc/util.h>
+/*%
+ * For BIND9 internal applications built with threads, we use a single app
+ * context and let multiple worker, I/O, timer threads do actual jobs.
+ * For other cases (including BIND9 built without threads) an app context acts
+ * as an event loop dispatching various events.
+ */
+#if defined(ISC_PLATFORM_USETHREADS) && defined(BIND9)
+#define USE_THREADS_SINGLECTX
+#endif
+
#ifdef ISC_PLATFORM_USETHREADS
#include <pthread.h>
-#else /* ISC_PLATFORM_USETHREADS */
+#endif
+
+#ifndef USE_THREADS_SINGLECTX
#include "../timer_p.h"
#include "../task_p.h"
#include "socket_p.h"
+#endif /* USE_THREADS_SINGLECTX */
+
+#ifdef ISC_PLATFORM_USETHREADS
+static pthread_t blockedthread;
#endif /* ISC_PLATFORM_USETHREADS */
-static isc_eventlist_t on_run;
-static isc_mutex_t lock;
-static isc_boolean_t shutdown_requested = ISC_FALSE;
-static isc_boolean_t running = ISC_FALSE;
-/*!
- * We assume that 'want_shutdown' can be read and written atomically.
+/*%
+ * The following can be either static or public, depending on build environment.
*/
-static volatile isc_boolean_t want_shutdown = ISC_FALSE;
+
+#ifdef BIND9
+#define ISC_APPFUNC_SCOPE
+#else
+#define ISC_APPFUNC_SCOPE static
+#endif
+
+ISC_APPFUNC_SCOPE isc_result_t isc__app_start(void);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxstart(isc_appctx_t *ctx);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_onrun(isc_mem_t *mctx,
+ isc_task_t *task,
+ isc_taskaction_t action,
+ void *arg);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxrun(isc_appctx_t *ctx);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_run(void);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxshutdown(isc_appctx_t *ctx);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_shutdown(void);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_reload(void);
+ISC_APPFUNC_SCOPE isc_result_t isc__app_ctxsuspend(isc_appctx_t *ctx);
+ISC_APPFUNC_SCOPE void isc__app_ctxfinish(isc_appctx_t *ctx);
+ISC_APPFUNC_SCOPE void isc__app_finish(void);
+ISC_APPFUNC_SCOPE void isc__app_block(void);
+ISC_APPFUNC_SCOPE void isc__app_unblock(void);
+ISC_APPFUNC_SCOPE isc_result_t isc__appctx_create(isc_mem_t *mctx,
+ isc_appctx_t **ctxp);
+ISC_APPFUNC_SCOPE void isc__appctx_destroy(isc_appctx_t **ctxp);
+ISC_APPFUNC_SCOPE void isc__appctx_settaskmgr(isc_appctx_t *ctx,
+ isc_taskmgr_t *taskmgr);
+ISC_APPFUNC_SCOPE void isc__appctx_setsocketmgr(isc_appctx_t *ctx,
+ isc_socketmgr_t *socketmgr);
+ISC_APPFUNC_SCOPE void isc__appctx_settimermgr(isc_appctx_t *ctx,
+ isc_timermgr_t *timermgr);
+
/*
- * We assume that 'want_reload' can be read and written atomically.
+ * The application context of this module. This implementation actually
+ * doesn't use it. (This may change in the future).
*/
-static volatile isc_boolean_t want_reload = ISC_FALSE;
+#define APPCTX_MAGIC ISC_MAGIC('A', 'p', 'c', 'x')
+#define VALID_APPCTX(c) ISC_MAGIC_VALID(c, APPCTX_MAGIC)
+
+typedef struct isc__appctx {
+ isc_appctx_t common;
+ isc_mem_t *mctx;
+ isc_mutex_t lock;
+ isc_eventlist_t on_run;
+ isc_boolean_t shutdown_requested;
+ isc_boolean_t running;
+
+ /*!
+ * We assume that 'want_shutdown' can be read and written atomically.
+ */
+ isc_boolean_t want_shutdown;
+ /*
+ * We assume that 'want_reload' can be read and written atomically.
+ */
+ isc_boolean_t want_reload;
-static isc_boolean_t blocked = ISC_FALSE;
-#ifdef ISC_PLATFORM_USETHREADS
-static pthread_t blockedthread;
-#endif /* ISC_PLATFORM_USETHREADS */
+ isc_boolean_t blocked;
+
+ isc_taskmgr_t *taskmgr;
+ isc_socketmgr_t *socketmgr;
+ isc_timermgr_t *timermgr;
+} isc__appctx_t;
+
+static isc__appctx_t isc_g_appctx;
+
+static struct {
+ isc_appmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *run, *shutdown, *start, *onrun, *reload, *finish,
+ *block, *unblock;
+#endif
+} appmethods = {
+ {
+ isc__appctx_destroy,
+ isc__app_ctxstart,
+ isc__app_ctxrun,
+ isc__app_ctxsuspend,
+ isc__app_ctxshutdown,
+ isc__app_ctxfinish,
+ isc__appctx_settaskmgr,
+ isc__appctx_setsocketmgr,
+ isc__appctx_settimermgr
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__app_run, (void *)isc__app_shutdown,
+ (void *)isc__app_start, (void *)isc__app_onrun, (void *)isc__app_reload,
+ (void *)isc__app_finish, (void *)isc__app_block,
+ (void *)isc__app_unblock
+#endif
+};
#ifdef HAVE_LINUXTHREADS
/*!
@@ -91,13 +190,13 @@ static pthread_t main_thread;
static void
exit_action(int arg) {
UNUSED(arg);
- want_shutdown = ISC_TRUE;
+ isc_g_appctx.want_shutdown = ISC_TRUE;
}
static void
reload_action(int arg) {
UNUSED(arg);
- want_reload = ISC_TRUE;
+ isc_g_appctx.want_reload = ISC_TRUE;
}
#endif
@@ -123,12 +222,12 @@ handle_signal(int sig, void (*handler)(int)) {
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_app_start(void) {
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_ctxstart(isc_appctx_t *ctx0) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
isc_result_t result;
- int presult;
- sigset_t sset;
- char strbuf[ISC_STRERRORSIZE];
+
+ REQUIRE(VALID_APPCTX(ctx));
/*
* Start an ISC library application.
@@ -151,7 +250,35 @@ isc_app_start(void) {
main_thread = pthread_self();
#endif
- result = isc_mutex_init(&lock);
+ result = isc_mutex_init(&ctx->lock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ ISC_LIST_INIT(ctx->on_run);
+
+ ctx->shutdown_requested = ISC_FALSE;
+ ctx->running = ISC_FALSE;
+ ctx->want_shutdown = ISC_FALSE;
+ ctx->want_reload = ISC_FALSE;
+ ctx->blocked = ISC_FALSE;
+
+ return (ISC_R_SUCCESS);
+}
+
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_start(void) {
+ isc_result_t result;
+ int presult;
+ sigset_t sset;
+ char strbuf[ISC_STRERRORSIZE];
+
+ isc_g_appctx.common.impmagic = APPCTX_MAGIC;
+ isc_g_appctx.common.magic = ISCAPI_APPCTX_MAGIC;
+ isc_g_appctx.common.methods = &appmethods.methods;
+ isc_g_appctx.mctx = NULL;
+ /* The remaining members will be initialized in ctxstart() */
+
+ result = isc__app_ctxstart((isc_appctx_t *)&isc_g_appctx);
if (result != ISC_R_SUCCESS)
return (result);
@@ -253,22 +380,20 @@ isc_app_start(void) {
}
#endif /* ISC_PLATFORM_USETHREADS */
- ISC_LIST_INIT(on_run);
-
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
void *arg)
{
isc_event_t *event;
isc_task_t *cloned_task = NULL;
isc_result_t result;
- LOCK(&lock);
+ LOCK(&isc_g_appctx.lock);
- if (running) {
+ if (isc_g_appctx.running) {
result = ISC_R_ALREADYRUNNING;
goto unlock;
}
@@ -285,24 +410,25 @@ isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
goto unlock;
}
- ISC_LIST_APPEND(on_run, event, ev_link);
+ ISC_LIST_APPEND(isc_g_appctx.on_run, event, ev_link);
result = ISC_R_SUCCESS;
unlock:
- UNLOCK(&lock);
+ UNLOCK(&isc_g_appctx.lock);
return (result);
}
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_THREADS_SINGLECTX
/*!
* Event loop for nonthreaded programs.
*/
static isc_result_t
-evloop(void) {
+evloop(isc__appctx_t *ctx) {
isc_result_t result;
- while (!want_shutdown) {
+
+ while (!ctx->want_shutdown) {
int n;
isc_time_t when, now;
struct timeval tv, *tvp;
@@ -310,14 +436,27 @@ evloop(void) {
isc_boolean_t readytasks;
isc_boolean_t call_timer_dispatch = ISC_FALSE;
- readytasks = isc__taskmgr_ready();
+ /*
+ * Check the reload (or suspend) case first for exiting the
+ * loop as fast as possible in case:
+ * - the direct call to isc__taskmgr_dispatch() in
+ * isc__app_ctxrun() completes all the tasks so far,
+ * - there is thus currently no active task, and
+ * - there is a timer event
+ */
+ if (ctx->want_reload) {
+ ctx->want_reload = ISC_FALSE;
+ return (ISC_R_RELOAD);
+ }
+
+ readytasks = isc__taskmgr_ready(ctx->taskmgr);
if (readytasks) {
tv.tv_sec = 0;
tv.tv_usec = 0;
tvp = &tv;
call_timer_dispatch = ISC_TRUE;
} else {
- result = isc__timermgr_nextevent(&when);
+ result = isc__timermgr_nextevent(ctx->timermgr, &when);
if (result != ISC_R_SUCCESS)
tvp = NULL;
else {
@@ -334,7 +473,7 @@ evloop(void) {
}
swait = NULL;
- n = isc__socketmgr_waitevents(tvp, &swait);
+ n = isc__socketmgr_waitevents(ctx->socketmgr, tvp, &swait);
if (n == 0 || call_timer_dispatch) {
/*
@@ -351,20 +490,17 @@ evloop(void) {
* call, since this loop only runs in the non-thread
* mode.
*/
- isc__timermgr_dispatch();
+ isc__timermgr_dispatch(ctx->timermgr);
}
if (n > 0)
- (void)isc__socketmgr_dispatch(swait);
- (void)isc__taskmgr_dispatch();
-
- if (want_reload) {
- want_reload = ISC_FALSE;
- return (ISC_R_RELOAD);
- }
+ (void)isc__socketmgr_dispatch(ctx->socketmgr, swait);
+ (void)isc__taskmgr_dispatch(ctx->taskmgr);
}
return (ISC_R_SUCCESS);
}
+#endif /* USE_THREADS_SINGLECTX */
+#ifndef ISC_PLATFORM_USETHREADS
/*
* This is a gross hack to support waiting for condition
* variables in nonthreaded programs in a limited way;
@@ -400,11 +536,11 @@ isc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp) {
INSIST(*mp == 1); /* Mutex must be locked on entry. */
--*mp;
- result = evloop();
+ result = evloop(&isc_g_appctx);
if (result == ISC_R_RELOAD)
- want_reload = ISC_TRUE;
+ isc_g_appctx.want_reload = ISC_TRUE;
if (signalled) {
- want_shutdown = ISC_FALSE;
+ isc_g_appctx.want_shutdown = ISC_FALSE;
signalled = ISC_FALSE;
}
@@ -420,43 +556,46 @@ isc__nothread_signal_hack(isc_condition_t *cp) {
INSIST(in_recursive_evloop);
- want_shutdown = ISC_TRUE;
+ isc_g_appctx.want_shutdown = ISC_TRUE;
signalled = ISC_TRUE;
return (ISC_R_SUCCESS);
}
#endif /* ISC_PLATFORM_USETHREADS */
-isc_result_t
-isc_app_run(void) {
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_ctxrun(isc_appctx_t *ctx0) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
int result;
isc_event_t *event, *next_event;
isc_task_t *task;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_THREADS_SINGLECTX
sigset_t sset;
char strbuf[ISC_STRERRORSIZE];
#ifdef HAVE_SIGWAIT
int sig;
#endif
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_THREADS_SINGLECTX */
+
+ REQUIRE(VALID_APPCTX(ctx));
#ifdef HAVE_LINUXTHREADS
REQUIRE(main_thread == pthread_self());
#endif
- LOCK(&lock);
+ LOCK(&ctx->lock);
- if (!running) {
- running = ISC_TRUE;
+ if (!ctx->running) {
+ ctx->running = ISC_TRUE;
/*
* Post any on-run events (in FIFO order).
*/
- for (event = ISC_LIST_HEAD(on_run);
+ for (event = ISC_LIST_HEAD(ctx->on_run);
event != NULL;
event = next_event) {
next_event = ISC_LIST_NEXT(event, ev_link);
- ISC_LIST_UNLINK(on_run, event, ev_link);
+ ISC_LIST_UNLINK(ctx->on_run, event, ev_link);
task = event->ev_sender;
event->ev_sender = NULL;
isc_task_sendanddetach(&task, &event);
@@ -464,7 +603,7 @@ isc_app_run(void) {
}
- UNLOCK(&lock);
+ UNLOCK(&ctx->lock);
#ifndef HAVE_SIGWAIT
/*
@@ -473,19 +612,27 @@ isc_app_run(void) {
* We do this here to ensure that the signal handler is installed
* (i.e. that it wasn't a "one-shot" handler).
*/
- result = handle_signal(SIGHUP, reload_action);
- if (result != ISC_R_SUCCESS)
- return (ISC_R_SUCCESS);
+ if (ctx == &isc_g_appctx) {
+ result = handle_signal(SIGHUP, reload_action);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_R_SUCCESS);
+ }
#endif
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_THREADS_SINGLECTX
+ /*
+ * When we are using multiple contexts, we don't rely on signals.
+ */
+ if (ctx != &isc_g_appctx)
+ return (ISC_R_SUCCESS);
+
/*
* There is no danger if isc_app_shutdown() is called before we wait
* for signals. Signals are blocked, so any such signal will simply
* be made pending and we will get it when we call sigwait().
*/
- while (!want_shutdown) {
+ while (!ctx->want_shutdown) {
#ifdef HAVE_SIGWAIT
/*
* Wait for SIGHUP, SIGINT, or SIGTERM.
@@ -503,21 +650,19 @@ isc_app_run(void) {
#ifndef HAVE_UNIXWARE_SIGWAIT
result = sigwait(&sset, &sig);
if (result == 0) {
- if (sig == SIGINT ||
- sig == SIGTERM)
- want_shutdown = ISC_TRUE;
+ if (sig == SIGINT || sig == SIGTERM)
+ ctx->want_shutdown = ISC_TRUE;
else if (sig == SIGHUP)
- want_reload = ISC_TRUE;
+ ctx->want_reload = ISC_TRUE;
}
#else /* Using UnixWare sigwait semantics. */
sig = sigwait(&sset);
if (sig >= 0) {
- if (sig == SIGINT ||
- sig == SIGTERM)
- want_shutdown = ISC_TRUE;
+ if (sig == SIGINT || sig == SIGTERM)
+ ctx->want_shutdown = ISC_TRUE;
else if (sig == SIGHUP)
- want_reload = ISC_TRUE;
+ ctx->want_reload = ISC_TRUE;
}
#endif /* HAVE_UNIXWARE_SIGWAIT */
@@ -528,131 +673,174 @@ isc_app_run(void) {
if (sigemptyset(&sset) != 0) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_run() sigsetops: %s", strbuf);
+ "isc_app_run() sigsetops: %s",
+ strbuf);
return (ISC_R_UNEXPECTED);
}
result = sigsuspend(&sset);
#endif /* HAVE_SIGWAIT */
- if (want_reload) {
- want_reload = ISC_FALSE;
+ if (ctx->want_reload) {
+ ctx->want_reload = ISC_FALSE;
return (ISC_R_RELOAD);
}
- if (want_shutdown && blocked)
+ if (ctx->want_shutdown && ctx->blocked)
exit(1);
}
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_THREADS_SINGLECTX */
- (void)isc__taskmgr_dispatch();
+ (void)isc__taskmgr_dispatch(ctx->taskmgr);
- result = evloop();
+ result = evloop(ctx);
if (result != ISC_R_SUCCESS)
return (result);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_THREADS_SINGLECTX */
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_app_shutdown(void) {
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_run() {
+ return (isc__app_ctxrun((isc_appctx_t *)&isc_g_appctx));
+}
+
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_ctxshutdown(isc_appctx_t *ctx0) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
isc_boolean_t want_kill = ISC_TRUE;
char strbuf[ISC_STRERRORSIZE];
- LOCK(&lock);
+ REQUIRE(VALID_APPCTX(ctx));
- REQUIRE(running);
+ LOCK(&ctx->lock);
- if (shutdown_requested)
+ REQUIRE(ctx->running);
+
+ if (ctx->shutdown_requested)
want_kill = ISC_FALSE;
else
- shutdown_requested = ISC_TRUE;
+ ctx->shutdown_requested = ISC_TRUE;
- UNLOCK(&lock);
+ UNLOCK(&ctx->lock);
if (want_kill) {
+ if (ctx != &isc_g_appctx)
+ ctx->want_shutdown = ISC_TRUE;
+ else {
#ifdef HAVE_LINUXTHREADS
- int result;
-
- result = pthread_kill(main_thread, SIGTERM);
- if (result != 0) {
- isc__strerror(result, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_shutdown() pthread_kill: %s",
- strbuf);
- return (ISC_R_UNEXPECTED);
- }
+ int result;
+
+ result = pthread_kill(main_thread, SIGTERM);
+ if (result != 0) {
+ isc__strerror(result, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_app_shutdown() "
+ "pthread_kill: %s",
+ strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
#else
- if (kill(getpid(), SIGTERM) < 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_shutdown() kill: %s", strbuf);
- return (ISC_R_UNEXPECTED);
+ if (kill(getpid(), SIGTERM) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_app_shutdown() "
+ "kill: %s", strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
+#endif /* HAVE_LINUXTHREADS */
}
-#endif
}
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_app_reload(void) {
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_shutdown() {
+ return (isc__app_ctxshutdown((isc_appctx_t *)&isc_g_appctx));
+}
+
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_ctxsuspend(isc_appctx_t *ctx0) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
isc_boolean_t want_kill = ISC_TRUE;
char strbuf[ISC_STRERRORSIZE];
- LOCK(&lock);
+ REQUIRE(VALID_APPCTX(ctx));
+
+ LOCK(&ctx->lock);
- REQUIRE(running);
+ REQUIRE(ctx->running);
/*
* Don't send the reload signal if we're shutting down.
*/
- if (shutdown_requested)
+ if (ctx->shutdown_requested)
want_kill = ISC_FALSE;
- UNLOCK(&lock);
+ UNLOCK(&ctx->lock);
if (want_kill) {
+ if (ctx != &isc_g_appctx)
+ ctx->want_reload = ISC_TRUE;
+ else {
#ifdef HAVE_LINUXTHREADS
- int result;
-
- result = pthread_kill(main_thread, SIGHUP);
- if (result != 0) {
- isc__strerror(result, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_reload() pthread_kill: %s",
- strbuf);
- return (ISC_R_UNEXPECTED);
- }
+ int result;
+
+ result = pthread_kill(main_thread, SIGHUP);
+ if (result != 0) {
+ isc__strerror(result, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_app_reload() "
+ "pthread_kill: %s",
+ strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
#else
- if (kill(getpid(), SIGHUP) < 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_app_reload() kill: %s", strbuf);
- return (ISC_R_UNEXPECTED);
- }
+ if (kill(getpid(), SIGHUP) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_app_reload() "
+ "kill: %s", strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
#endif
+ }
}
return (ISC_R_SUCCESS);
}
-void
-isc_app_finish(void) {
- DESTROYLOCK(&lock);
+ISC_APPFUNC_SCOPE isc_result_t
+isc__app_reload(void) {
+ return (isc__app_ctxsuspend((isc_appctx_t *)&isc_g_appctx));
+}
+
+ISC_APPFUNC_SCOPE void
+isc__app_ctxfinish(isc_appctx_t *ctx0) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
+
+ REQUIRE(VALID_APPCTX(ctx));
+
+ DESTROYLOCK(&ctx->lock);
+}
+
+ISC_APPFUNC_SCOPE void
+isc__app_finish(void) {
+ isc__app_ctxfinish((isc_appctx_t *)&isc_g_appctx);
}
-void
-isc_app_block(void) {
+ISC_APPFUNC_SCOPE void
+isc__app_block(void) {
#ifdef ISC_PLATFORM_USETHREADS
sigset_t sset;
#endif /* ISC_PLATFORM_USETHREADS */
- REQUIRE(running);
- REQUIRE(!blocked);
+ REQUIRE(isc_g_appctx.running);
+ REQUIRE(!isc_g_appctx.blocked);
- blocked = ISC_TRUE;
+ isc_g_appctx.blocked = ISC_TRUE;
#ifdef ISC_PLATFORM_USETHREADS
blockedthread = pthread_self();
RUNTIME_CHECK(sigemptyset(&sset) == 0 &&
@@ -662,16 +850,16 @@ isc_app_block(void) {
#endif /* ISC_PLATFORM_USETHREADS */
}
-void
-isc_app_unblock(void) {
+ISC_APPFUNC_SCOPE void
+isc__app_unblock(void) {
#ifdef ISC_PLATFORM_USETHREADS
sigset_t sset;
#endif /* ISC_PLATFORM_USETHREADS */
- REQUIRE(running);
- REQUIRE(blocked);
+ REQUIRE(isc_g_appctx.running);
+ REQUIRE(isc_g_appctx.blocked);
- blocked = ISC_FALSE;
+ isc_g_appctx.blocked = ISC_FALSE;
#ifdef ISC_PLATFORM_USETHREADS
REQUIRE(blockedthread == pthread_self());
@@ -682,3 +870,77 @@ isc_app_unblock(void) {
RUNTIME_CHECK(pthread_sigmask(SIG_BLOCK, &sset, NULL) == 0);
#endif /* ISC_PLATFORM_USETHREADS */
}
+
+ISC_APPFUNC_SCOPE isc_result_t
+isc__appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp) {
+ isc__appctx_t *ctx;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(ctxp != NULL && *ctxp == NULL);
+
+ ctx = isc_mem_get(mctx, sizeof(*ctx));
+ if (ctx == NULL)
+ return (ISC_R_NOMEMORY);
+
+ ctx->common.impmagic = APPCTX_MAGIC;
+ ctx->common.magic = ISCAPI_APPCTX_MAGIC;
+ ctx->common.methods = &appmethods.methods;
+
+ ctx->mctx = NULL;
+ isc_mem_attach(mctx, &ctx->mctx);
+
+ ctx->taskmgr = NULL;
+ ctx->socketmgr = NULL;
+ ctx->timermgr = NULL;
+
+ *ctxp = (isc_appctx_t *)ctx;
+
+ return (ISC_R_SUCCESS);
+}
+
+ISC_APPFUNC_SCOPE void
+isc__appctx_destroy(isc_appctx_t **ctxp) {
+ isc__appctx_t *ctx;
+
+ REQUIRE(ctxp != NULL);
+ ctx = (isc__appctx_t *)*ctxp;
+ REQUIRE(VALID_APPCTX(ctx));
+
+ isc_mem_putanddetach(&ctx->mctx, ctx, sizeof(*ctx));
+
+ *ctxp = NULL;
+}
+
+ISC_APPFUNC_SCOPE void
+isc__appctx_settaskmgr(isc_appctx_t *ctx0, isc_taskmgr_t *taskmgr) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
+
+ REQUIRE(VALID_APPCTX(ctx));
+
+ ctx->taskmgr = taskmgr;
+}
+
+ISC_APPFUNC_SCOPE void
+isc__appctx_setsocketmgr(isc_appctx_t *ctx0, isc_socketmgr_t *socketmgr) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
+
+ REQUIRE(VALID_APPCTX(ctx));
+
+ ctx->socketmgr = socketmgr;
+}
+
+ISC_APPFUNC_SCOPE void
+isc__appctx_settimermgr(isc_appctx_t *ctx0, isc_timermgr_t *timermgr) {
+ isc__appctx_t *ctx = (isc__appctx_t *)ctx0;
+
+ REQUIRE(VALID_APPCTX(ctx));
+
+ ctx->timermgr = timermgr;
+}
+
+#ifdef USE_APPIMPREGISTER
+isc_result_t
+isc__app_register() {
+ return (isc_app_register(isc__appctx_create));
+}
+#endif
diff --git a/lib/isc/unix/dir.c b/lib/isc/unix/dir.c
index 8053c42980ef..0caf882e0bc3 100644
--- a/lib/isc/unix/dir.c
+++ b/lib/isc/unix/dir.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dir.c,v 1.25.332.3 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: dir.c,v 1.29 2009-02-16 23:48:04 tbox Exp $ */
/*! \file
* \author Principal Authors: DCL */
diff --git a/lib/isc/unix/entropy.c b/lib/isc/unix/entropy.c
index bdff8d933eee..9044632842a6 100644
--- a/lib/isc/unix/entropy.c
+++ b/lib/isc/unix/entropy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: entropy.c,v 1.80.332.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: entropy.c,v 1.82 2008-12-01 23:47:45 tbox Exp $ */
/* \file unix/entropy.c
* \brief
diff --git a/lib/isc/unix/file.c b/lib/isc/unix/file.c
index ae737b8bf9be..25d856cc6c78 100644
--- a/lib/isc/unix/file.c
+++ b/lib/isc/unix/file.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -48,7 +48,7 @@
* SUCH DAMAGE.
*/
-/* $Id: file.c,v 1.51.332.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: file.c,v 1.57 2011-01-11 23:47:14 tbox Exp $ */
/*! \file */
@@ -68,6 +68,7 @@
#include <isc/dir.h>
#include <isc/file.h>
#include <isc/log.h>
+#include <isc/mem.h>
#include <isc/random.h>
#include <isc/string.h>
#include <isc/time.h>
@@ -242,16 +243,26 @@ isc_file_renameunique(const char *file, char *templet) {
return (ISC_R_SUCCESS);
}
-
isc_result_t
isc_file_openunique(char *templet, FILE **fp) {
+ int mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
+ return (isc_file_openuniquemode(templet, mode, fp));
+}
+
+isc_result_t
+isc_file_openuniqueprivate(char *templet, FILE **fp) {
+ int mode = S_IWUSR|S_IRUSR;
+ return (isc_file_openuniquemode(templet, mode, fp));
+}
+
+isc_result_t
+isc_file_openuniquemode(char *templet, int mode, FILE **fp) {
int fd;
FILE *f;
isc_result_t result = ISC_R_SUCCESS;
char *x;
char *cp;
isc_uint32_t which;
- int mode;
REQUIRE(templet != NULL);
REQUIRE(fp != NULL && *fp == NULL);
@@ -269,7 +280,6 @@ isc_file_openunique(char *templet, FILE **fp) {
x = cp--;
}
- mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
while ((fd = open(templet, O_RDWR|O_CREAT|O_EXCL, mode)) == -1) {
if (errno != EEXIST)
@@ -442,3 +452,73 @@ isc_file_truncate(const char *filename, isc_offset_t size) {
result = isc__errno2result(errno);
return (result);
}
+
+isc_result_t
+isc_file_safecreate(const char *filename, FILE **fp) {
+ isc_result_t result;
+ int flags;
+ struct stat sb;
+ FILE *f;
+ int fd;
+
+ REQUIRE(filename != NULL);
+ REQUIRE(fp != NULL && *fp == NULL);
+
+ result = file_stats(filename, &sb);
+ if (result == ISC_R_SUCCESS) {
+ if ((sb.st_mode & S_IFREG) == 0)
+ return (ISC_R_INVALIDFILE);
+ flags = O_WRONLY | O_TRUNC;
+ } else if (result == ISC_R_FILENOTFOUND) {
+ flags = O_WRONLY | O_CREAT | O_EXCL;
+ } else
+ return (result);
+
+ fd = open(filename, flags, S_IRUSR | S_IWUSR);
+ if (fd == -1)
+ return (isc__errno2result(errno));
+
+ f = fdopen(fd, "w");
+ if (f == NULL) {
+ result = isc__errno2result(errno);
+ close(fd);
+ return (result);
+ }
+
+ *fp = f;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename)
+{
+ char *dir, *file, *slash;
+
+ slash = strrchr(path, '/');
+
+ if (slash == path) {
+ file = ++slash;
+ dir = isc_mem_strdup(mctx, "/");
+ } else if (slash != NULL) {
+ file = ++slash;
+ dir = isc_mem_allocate(mctx, slash - path);
+ if (dir != NULL)
+ strlcpy(dir, path, slash - path);
+ } else {
+ file = path;
+ dir = isc_mem_strdup(mctx, ".");
+ }
+
+ if (dir == NULL)
+ return (ISC_R_NOMEMORY);
+
+ if (*file == '\0') {
+ isc_mem_free(mctx, dir);
+ return (ISC_R_INVALIDFILE);
+ }
+
+ *dirname = dir;
+ *basename = file;
+
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/isc/unix/ifiter_getifaddrs.c b/lib/isc/unix/ifiter_getifaddrs.c
index 1e9c81417664..90a3faf84818 100644
--- a/lib/isc/unix/ifiter_getifaddrs.c
+++ b/lib/isc/unix/ifiter_getifaddrs.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ifiter_getifaddrs.c,v 1.11.120.2 2009-09-24 23:47:34 tbox Exp $ */
+/* $Id: ifiter_getifaddrs.c,v 1.13 2009-09-24 23:48:13 tbox Exp $ */
/*! \file
* \brief
diff --git a/lib/isc/unix/ifiter_ioctl.c b/lib/isc/unix/ifiter_ioctl.c
index c004f614860c..010b3658188e 100644
--- a/lib/isc/unix/ifiter_ioctl.c
+++ b/lib/isc/unix/ifiter_ioctl.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ifiter_ioctl.c,v 1.60.120.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: ifiter_ioctl.c,v 1.62 2009-01-18 23:48:14 tbox Exp $ */
/*! \file
* \brief
diff --git a/lib/isc/unix/include/isc/net.h b/lib/isc/unix/include/isc/net.h
index 5fad7930d345..112f1d7dc1be 100644
--- a/lib/isc/unix/include/isc/net.h
+++ b/lib/isc/unix/include/isc/net.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: net.h,v 1.48.84.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: net.h,v 1.50 2008-12-01 04:14:54 marka Exp $ */
#ifndef ISC_NET_H
#define ISC_NET_H 1
diff --git a/lib/isc/unix/include/isc/offset.h b/lib/isc/unix/include/isc/offset.h
index 91f43c37fc05..2920899faf90 100644
--- a/lib/isc/unix/include/isc/offset.h
+++ b/lib/isc/unix/include/isc/offset.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: offset.h,v 1.15.332.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: offset.h,v 1.17 2008-12-01 23:47:45 tbox Exp $ */
#ifndef ISC_OFFSET_H
#define ISC_OFFSET_H 1
diff --git a/lib/isc/unix/include/isc/strerror.h b/lib/isc/unix/include/isc/strerror.h
index e094e962ae18..ac8d496871fc 100644
--- a/lib/isc/unix/include/isc/strerror.h
+++ b/lib/isc/unix/include/isc/strerror.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: strerror.h,v 1.8.332.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: strerror.h,v 1.10 2008-12-01 23:47:45 tbox Exp $ */
#ifndef ISC_STRERROR_H
#define ISC_STRERROR_H
diff --git a/lib/isc/unix/include/isc/time.h b/lib/isc/unix/include/isc/time.h
index 2149011cb114..19f081077e15 100644
--- a/lib/isc/unix/include/isc/time.h
+++ b/lib/isc/unix/include/isc/time.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: time.h,v 1.38.56.2 2009-01-05 23:47:23 tbox Exp $ */
+/* $Id: time.h,v 1.40 2009-01-05 23:47:54 tbox Exp $ */
#ifndef ISC_TIME_H
#define ISC_TIME_H 1
diff --git a/lib/isc/unix/interfaceiter.c b/lib/isc/unix/interfaceiter.c
index 2d60a3365131..37fc3b1ab528 100644
--- a/lib/isc/unix/interfaceiter.c
+++ b/lib/isc/unix/interfaceiter.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: interfaceiter.c,v 1.44.120.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: interfaceiter.c,v 1.45 2008-12-01 03:51:47 marka Exp $ */
/*! \file */
diff --git a/lib/isc/unix/resource.c b/lib/isc/unix/resource.c
index 1061282f2233..99a4b8c5fc94 100644
--- a/lib/isc/unix/resource.c
+++ b/lib/isc/unix/resource.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resource.c,v 1.21.66.2 2009-02-13 23:47:39 tbox Exp $ */
+/* $Id: resource.c,v 1.23 2009-02-13 23:48:14 tbox Exp $ */
#include <config.h>
diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c
index 055e8837684c..ec7487e856ac 100644
--- a/lib/isc/unix/socket.c
+++ b/lib/isc/unix/socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket.c,v 1.308.12.17 2010-12-22 03:28:13 marka Exp $ */
+/* $Id: socket.c,v 1.333.14.2.2.1 2011-06-02 23:47:36 tbox Exp $ */
/*! \file */
@@ -76,9 +76,19 @@
#include "errno2result.h"
-#ifndef ISC_PLATFORM_USETHREADS
+/* See task.c about the following definition: */
+#ifdef BIND9
+#ifdef ISC_PLATFORM_USETHREADS
+#define USE_WATCHER_THREAD
+#else
+#define USE_SHARED_MANAGER
+#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* BIND9 */
+
+#ifndef USE_WATCHER_THREAD
#include "socket_p.h"
-#endif /* ISC_PLATFORM_USETHREADS */
+#include "../task_p.h"
+#endif /* USE_WATCHER_THREAD */
#if defined(SO_BSDCOMPAT) && defined(__linux__)
#include <sys/utsname.h>
@@ -101,7 +111,7 @@ typedef struct {
#define USE_SELECT
#endif /* ISC_PLATFORM_HAVEKQUEUE */
-#ifndef ISC_PLATFORM_USETHREADS
+#ifndef USE_WATCHER_THREAD
#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL)
struct isc_socketwait {
int nevents;
@@ -114,7 +124,7 @@ struct isc_socketwait {
int maxfd;
};
#endif /* USE_KQUEUE */
-#endif /* !ISC_PLATFORM_USETHREADS */
+#endif /* !USE_WATCHER_THREAD */
/*%
* Maximum number of allowable open sockets. This is also the maximum
@@ -248,7 +258,7 @@ typedef enum { poll_idle, poll_active, poll_checking } pollstate_t;
typedef isc_event_t intev_t;
#define SOCKET_MAGIC ISC_MAGIC('I', 'O', 'i', 'o')
-#define VALID_SOCKET(t) ISC_MAGIC_VALID(t, SOCKET_MAGIC)
+#define VALID_SOCKET(s) ISC_MAGIC_VALID(s, SOCKET_MAGIC)
/*!
* IPv6 control information. If the socket is an IPv6 socket we want
@@ -282,16 +292,21 @@ typedef isc_event_t intev_t;
*/
#define NRETRIES 10
-struct isc_socket {
+typedef struct isc__socket isc__socket_t;
+typedef struct isc__socketmgr isc__socketmgr_t;
+
+#define NEWCONNSOCK(ev) ((isc__socket_t *)(ev)->newsocket)
+
+struct isc__socket {
/* Not locked. */
- unsigned int magic;
- isc_socketmgr_t *manager;
+ isc_socket_t common;
+ isc__socketmgr_t *manager;
isc_mutex_t lock;
isc_sockettype_t type;
const isc_statscounter_t *statsindex;
/* Locked by socket lock. */
- ISC_LINK(isc_socket_t) link;
+ ISC_LINK(isc__socket_t) link;
unsigned int references;
int fd;
int pf;
@@ -339,9 +354,9 @@ struct isc_socket {
#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g')
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC)
-struct isc_socketmgr {
+struct isc__socketmgr {
/* Not locked. */
- unsigned int magic;
+ isc_socketmgr_t common;
isc_mem_t *mctx;
isc_mutex_t lock;
isc_mutex_t *fdlock;
@@ -370,14 +385,14 @@ struct isc_socketmgr {
#endif
/* Locked by fdlock. */
- isc_socket_t **fds;
+ isc__socket_t **fds;
int *fdstate;
#ifdef USE_DEVPOLL
pollinfo_t *fdpollinfo;
#endif
/* Locked by manager lock. */
- ISC_LIST(isc_socket_t) socklist;
+ ISC_LIST(isc__socket_t) socklist;
#ifdef USE_SELECT
fd_set *read_fds;
fd_set *read_fds_copy;
@@ -386,17 +401,18 @@ struct isc_socketmgr {
int maxfd;
#endif /* USE_SELECT */
int reserved; /* unlocked */
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
isc_thread_t watcher;
isc_condition_t shutdown_ok;
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WATCHER_THREAD */
unsigned int refs;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
+ int maxudp;
};
-#ifndef ISC_PLATFORM_USETHREADS
-static isc_socketmgr_t *socketmgr = NULL;
-#endif /* ISC_PLATFORM_USETHREADS */
+#ifdef USE_SHARED_MANAGER
+static isc__socketmgr_t *socketmgr = NULL;
+#endif /* USE_SHARED_MANAGER */
#define CLOSED 0 /* this one must be zero */
#define MANAGED 1
@@ -412,26 +428,165 @@ static isc_socketmgr_t *socketmgr = NULL;
# define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER)
#endif
-static void send_recvdone_event(isc_socket_t *, isc_socketevent_t **);
-static void send_senddone_event(isc_socket_t *, isc_socketevent_t **);
-static void free_socket(isc_socket_t **);
-static isc_result_t allocate_socket(isc_socketmgr_t *, isc_sockettype_t,
- isc_socket_t **);
-static void destroy(isc_socket_t **);
+static void send_recvdone_event(isc__socket_t *, isc_socketevent_t **);
+static void send_senddone_event(isc__socket_t *, isc_socketevent_t **);
+static void free_socket(isc__socket_t **);
+static isc_result_t allocate_socket(isc__socketmgr_t *, isc_sockettype_t,
+ isc__socket_t **);
+static void destroy(isc__socket_t **);
static void internal_accept(isc_task_t *, isc_event_t *);
static void internal_connect(isc_task_t *, isc_event_t *);
static void internal_recv(isc_task_t *, isc_event_t *);
static void internal_send(isc_task_t *, isc_event_t *);
static void internal_fdwatch_write(isc_task_t *, isc_event_t *);
static void internal_fdwatch_read(isc_task_t *, isc_event_t *);
-static void process_cmsg(isc_socket_t *, struct msghdr *, isc_socketevent_t *);
-static void build_msghdr_send(isc_socket_t *, isc_socketevent_t *,
+static void process_cmsg(isc__socket_t *, struct msghdr *, isc_socketevent_t *);
+static void build_msghdr_send(isc__socket_t *, isc_socketevent_t *,
struct msghdr *, struct iovec *, size_t *);
-static void build_msghdr_recv(isc_socket_t *, isc_socketevent_t *,
+static void build_msghdr_recv(isc__socket_t *, isc_socketevent_t *,
struct msghdr *, struct iovec *, size_t *);
-#ifdef ISC_PLATFORM_USETHREADS
-static isc_boolean_t process_ctlfd(isc_socketmgr_t *manager);
+#ifdef USE_WATCHER_THREAD
+static isc_boolean_t process_ctlfd(isc__socketmgr_t *manager);
+#endif
+
+/*%
+ * The following can be either static or public, depending on build environment.
+ */
+
+#ifdef BIND9
+#define ISC_SOCKETFUNC_SCOPE
+#else
+#define ISC_SOCKETFUNC_SCOPE static
+#endif
+
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
+ isc_socket_t **socketp);
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_attach(isc_socket_t *sock, isc_socket_t **socketp);
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_detach(isc_socket_t **socketp);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
+ unsigned int maxsocks);
+ISC_SOCKETFUNC_SCOPE void
+isc__socketmgr_destroy(isc_socketmgr_t **managerp);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recv(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recv2(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_socketevent_t *event, unsigned int flags);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_send(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendto(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendto2(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
+ isc_socketevent_t *event, unsigned int flags);
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
+ isc_uint32_t owner, isc_uint32_t group);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
+ unsigned int options);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_filter(isc_socket_t *sock, const char *filter);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_listen(isc_socket_t *sock, unsigned int backlog);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_accept(isc_socket_t *sock,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp);
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how);
+ISC_SOCKETFUNC_SCOPE isc_sockettype_t
+isc__socket_gettype(isc_socket_t *sock);
+ISC_SOCKETFUNC_SCOPE isc_boolean_t
+isc__socket_isbound(isc_socket_t *sock);
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes);
+#if defined(HAVE_LIBXML2) && defined(BIND9)
+ISC_SOCKETFUNC_SCOPE void
+isc__socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer);
+#endif
+
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags,
+ isc_sockfdwatch_t callback, void *cbarg,
+ isc_task_t *task, isc_socket_t **socketp);
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_fdwatchpoke(isc_socket_t *sock, int flags);
+
+static struct {
+ isc_socketmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *recvv, *send, *sendv, *sendto2, *cleanunix, *permunix, *filter,
+ *listen, *accept, *getpeername, *isbound;
+#endif
+} socketmethods = {
+ {
+ isc__socket_attach,
+ isc__socket_detach,
+ isc__socket_bind,
+ isc__socket_sendto,
+ isc__socket_connect,
+ isc__socket_recv,
+ isc__socket_cancel,
+ isc__socket_getsockname,
+ isc__socket_gettype,
+ isc__socket_ipv6only,
+ isc__socket_fdwatchpoke
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__socket_recvv, (void *)isc__socket_send,
+ (void *)isc__socket_sendv, (void *)isc__socket_sendto2,
+ (void *)isc__socket_cleanunix, (void *)isc__socket_permunix,
+ (void *)isc__socket_filter, (void *)isc__socket_listen,
+ (void *)isc__socket_accept, (void *)isc__socket_getpeername,
+ (void *)isc__socket_isbound
#endif
+};
+
+static isc_socketmgrmethods_t socketmgrmethods = {
+ isc__socketmgr_destroy,
+ isc__socket_create,
+ isc__socket_fdwatchcreate
+};
#define SELECT_POKE_SHUTDOWN (-1)
#define SELECT_POKE_NOTHING (-2)
@@ -531,12 +686,14 @@ static const isc_statscounter_t fdwatchstatsindex[] = {
isc_sockstatscounter_fdwatchrecvfail
};
+#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) || \
+ defined(USE_WATCHER_THREAD)
static void
-manager_log(isc_socketmgr_t *sockmgr,
+manager_log(isc__socketmgr_t *sockmgr,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
static void
-manager_log(isc_socketmgr_t *sockmgr,
+manager_log(isc__socketmgr_t *sockmgr,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
const char *fmt, ...)
{
@@ -553,14 +710,15 @@ manager_log(isc_socketmgr_t *sockmgr,
isc_log_write(isc_lctx, category, module, level,
"sockmgr %p: %s", sockmgr, msgbuf);
}
+#endif
static void
-socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
+socket_log(isc__socket_t *sock, isc_sockaddr_t *address,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
isc_msgcat_t *msgcat, int msgset, int message,
const char *fmt, ...) ISC_FORMAT_PRINTF(9, 10);
static void
-socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
+socket_log(isc__socket_t *sock, isc_sockaddr_t *address,
isc_logcategory_t *category, isc_logmodule_t *module, int level,
isc_msgcat_t *msgcat, int msgset, int message,
const char *fmt, ...)
@@ -595,7 +753,7 @@ socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
* setting IPV6_V6ONLY.
*/
static void
-FIX_IPV6_RECVPKTINFO(isc_socket_t *sock)
+FIX_IPV6_RECVPKTINFO(isc__socket_t *sock)
{
char strbuf[ISC_STRERRORSIZE];
int on = 1;
@@ -632,7 +790,7 @@ inc_stats(isc_stats_t *stats, isc_statscounter_t counterid) {
}
static inline isc_result_t
-watch_fd(isc_socketmgr_t *manager, int fd, int msg) {
+watch_fd(isc__socketmgr_t *manager, int fd, int msg) {
isc_result_t result = ISC_R_SUCCESS;
#ifdef USE_KQUEUE
@@ -700,7 +858,7 @@ watch_fd(isc_socketmgr_t *manager, int fd, int msg) {
}
static inline isc_result_t
-unwatch_fd(isc_socketmgr_t *manager, int fd, int msg) {
+unwatch_fd(isc__socketmgr_t *manager, int fd, int msg) {
isc_result_t result = ISC_R_SUCCESS;
#ifdef USE_KQUEUE
@@ -787,7 +945,7 @@ unwatch_fd(isc_socketmgr_t *manager, int fd, int msg) {
}
static void
-wakeup_socket(isc_socketmgr_t *manager, int fd, int msg) {
+wakeup_socket(isc__socketmgr_t *manager, int fd, int msg) {
isc_result_t result;
int lockid = FDLOCK_ID(fd);
@@ -848,14 +1006,14 @@ wakeup_socket(isc_socketmgr_t *manager, int fd, int msg) {
}
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
/*
* Poke the select loop when there is something for us to do.
* The write is required (by POSIX) to complete. That is, we
* will not get partial writes.
*/
static void
-select_poke(isc_socketmgr_t *mgr, int fd, int msg) {
+select_poke(isc__socketmgr_t *mgr, int fd, int msg) {
int cc;
int buf[2];
char strbuf[ISC_STRERRORSIZE];
@@ -894,7 +1052,7 @@ select_poke(isc_socketmgr_t *mgr, int fd, int msg) {
* Read a message on the internal fd.
*/
static void
-select_readmsg(isc_socketmgr_t *mgr, int *fd, int *msg) {
+select_readmsg(isc__socketmgr_t *mgr, int *fd, int *msg) {
int buf[2];
int cc;
char strbuf[ISC_STRERRORSIZE];
@@ -921,19 +1079,19 @@ select_readmsg(isc_socketmgr_t *mgr, int *fd, int *msg) {
*fd = buf[0];
*msg = buf[1];
}
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WATCHER_THREAD */
/*
* Update the state of the socketmgr when something changes.
*/
static void
-select_poke(isc_socketmgr_t *manager, int fd, int msg) {
+select_poke(isc__socketmgr_t *manager, int fd, int msg) {
if (msg == SELECT_POKE_SHUTDOWN)
return;
else if (fd >= 0)
wakeup_socket(manager, fd, msg);
return;
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
/*
* Make a fd non-blocking.
@@ -1026,7 +1184,7 @@ cmsg_space(ISC_SOCKADDR_LEN_T len) {
* Process control messages received on a socket.
*/
static void
-process_cmsg(isc_socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
+process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
#ifdef USE_CMSG
struct cmsghdr *cmsgp;
#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
@@ -1129,7 +1287,7 @@ process_cmsg(isc_socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
* this transaction can send.
*/
static void
-build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
+build_msghdr_send(isc__socket_t *sock, isc_socketevent_t *dev,
struct msghdr *msg, struct iovec *iov, size_t *write_countp)
{
unsigned int iovcount;
@@ -1248,7 +1406,7 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
* this transaction can receive.
*/
static void
-build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev,
+build_msghdr_recv(isc__socket_t *sock, isc_socketevent_t *dev,
struct msghdr *msg, struct iovec *iov, size_t *read_countp)
{
unsigned int iovcount;
@@ -1369,7 +1527,7 @@ build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev,
}
static void
-set_dev_address(isc_sockaddr_t *address, isc_socket_t *sock,
+set_dev_address(isc_sockaddr_t *address, isc__socket_t *sock,
isc_socketevent_t *dev)
{
if (sock->type == isc_sockettype_udp) {
@@ -1393,7 +1551,7 @@ destroy_socketevent(isc_event_t *event) {
}
static isc_socketevent_t *
-allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype,
+allocate_socketevent(isc__socket_t *sock, isc_eventtype_t eventtype,
isc_taskaction_t action, const void *arg)
{
isc_socketevent_t *ev;
@@ -1446,7 +1604,7 @@ dump_msg(struct msghdr *msg) {
#define DOIO_EOF 3 /* EOF, no event sent */
static int
-doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
+doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) {
int cc;
struct iovec iov[MAXSCATTERGATHER_RECV];
size_t read_count;
@@ -1554,6 +1712,12 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
}
return (DOIO_SOFT);
}
+ /*
+ * Simulate a firewall blocking UDP responses bigger than
+ * 512 bytes.
+ */
+ if (sock->manager->maxudp != 0 && cc > sock->manager->maxudp)
+ return (DOIO_SOFT);
}
socket_log(sock, &dev->address, IOEVENT,
@@ -1630,7 +1794,7 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
* No other return values are possible.
*/
static int
-doio_send(isc_socket_t *sock, isc_socketevent_t *dev) {
+doio_send(isc__socket_t *sock, isc_socketevent_t *dev) {
int cc;
struct iovec iov[MAXSCATTERGATHER_SEND];
size_t write_count;
@@ -1741,7 +1905,7 @@ doio_send(isc_socket_t *sock, isc_socketevent_t *dev) {
* references exist.
*/
static void
-closesocket(isc_socketmgr_t *manager, isc_socket_t *sock, int fd) {
+closesocket(isc__socketmgr_t *manager, isc__socket_t *sock, int fd) {
isc_sockettype_t type = sock->type;
int lockid = FDLOCK_ID(fd);
@@ -1804,10 +1968,10 @@ closesocket(isc_socketmgr_t *manager, isc_socket_t *sock, int fd) {
}
static void
-destroy(isc_socket_t **sockp) {
+destroy(isc__socket_t **sockp) {
int fd;
- isc_socket_t *sock = *sockp;
- isc_socketmgr_t *manager = sock->manager;
+ isc__socket_t *sock = *sockp;
+ isc__socketmgr_t *manager = sock->manager;
socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET,
ISC_MSG_DESTROYING, "destroying");
@@ -1828,10 +1992,10 @@ destroy(isc_socket_t **sockp) {
ISC_LIST_UNLINK(manager->socklist, sock, link);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (ISC_LIST_EMPTY(manager->socklist))
SIGNAL(&manager->shutdown_ok);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
UNLOCK(&manager->lock);
@@ -1839,10 +2003,10 @@ destroy(isc_socket_t **sockp) {
}
static isc_result_t
-allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
- isc_socket_t **socketp)
+allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
+ isc__socket_t **socketp)
{
- isc_socket_t *sock;
+ isc__socket_t *sock;
isc_result_t result;
ISC_SOCKADDR_LEN_T cmsgbuflen;
@@ -1853,7 +2017,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
result = ISC_R_UNEXPECTED;
- sock->magic = 0;
+ sock->common.magic = 0;
+ sock->common.impmagic = 0;
sock->references = 0;
sock->manager = manager;
@@ -1917,7 +2082,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
*/
result = isc_mutex_init(&sock->lock);
if (result != ISC_R_SUCCESS) {
- sock->magic = 0;
+ sock->common.magic = 0;
+ sock->common.impmagic = 0;
goto error;
}
@@ -1931,7 +2097,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTW,
NULL, sock, sock, NULL, NULL);
- sock->magic = SOCKET_MAGIC;
+ sock->common.magic = ISCAPI_SOCKET_MAGIC;
+ sock->common.impmagic = SOCKET_MAGIC;
*socketp = sock;
return (ISC_R_SUCCESS);
@@ -1956,8 +2123,8 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
* also close the socket.
*/
static void
-free_socket(isc_socket_t **socketp) {
- isc_socket_t *sock = *socketp;
+free_socket(isc__socket_t **socketp) {
+ isc__socket_t *sock = *socketp;
INSIST(sock->references == 0);
INSIST(VALID_SOCKET(sock));
@@ -1977,7 +2144,8 @@ free_socket(isc_socket_t **socketp) {
isc_mem_put(sock->manager->mctx, sock->sendcmsgbuf,
sock->sendcmsgbuflen);
- sock->magic = 0;
+ sock->common.magic = 0;
+ sock->common.impmagic = 0;
DESTROYLOCK(&sock->lock);
@@ -2025,7 +2193,7 @@ clear_bsdcompat(void) {
#endif
static isc_result_t
-opensocket(isc_socketmgr_t *manager, isc_socket_t *sock) {
+opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) {
char strbuf[ISC_STRERRORSIZE];
const char *err = "socket";
int tries = 0;
@@ -2316,11 +2484,12 @@ opensocket(isc_socketmgr_t *manager, isc_socket_t *sock) {
* called with 'arg' as the arg value. The new socket is returned
* in 'socketp'.
*/
-isc_result_t
-isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
- isc_socket_t **socketp)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type,
+ isc_socket_t **socketp)
{
- isc_socket_t *sock = NULL;
+ isc__socket_t *sock = NULL;
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
isc_result_t result;
int lockid;
@@ -2356,8 +2525,9 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
return (result);
}
+ sock->common.methods = (isc_socketmethods_t *)&socketmethods;
sock->references = 1;
- *socketp = sock;
+ *socketp = (isc_socket_t *)sock;
/*
* Note we don't have to lock the socket like we normally would because
@@ -2388,9 +2558,11 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_socket_open(isc_socket_t *sock) {
+#ifdef BIND9
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_open(isc_socket_t *sock0) {
isc_result_t result;
+ isc__socket_t *sock = (isc__socket_t *)sock0;
REQUIRE(VALID_SOCKET(sock));
@@ -2430,6 +2602,7 @@ isc_socket_open(isc_socket_t *sock) {
return (result);
}
+#endif /* BIND9 */
/*
* Create a new 'type' socket managed by 'manager'. Events
@@ -2437,12 +2610,13 @@ isc_socket_open(isc_socket_t *sock) {
* called with 'arg' as the arg value. The new socket is returned
* in 'socketp'.
*/
-isc_result_t
-isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags,
- isc_sockfdwatch_t callback, void *cbarg,
- isc_task_t *task, isc_socket_t **socketp)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_fdwatchcreate(isc_socketmgr_t *manager0, int fd, int flags,
+ isc_sockfdwatch_t callback, void *cbarg,
+ isc_task_t *task, isc_socket_t **socketp)
{
- isc_socket_t *sock = NULL;
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
+ isc__socket_t *sock = NULL;
isc_result_t result;
int lockid;
@@ -2460,8 +2634,9 @@ isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags,
sock->fdwatchtask = task;
sock->statsindex = fdwatchstatsindex;
+ sock->common.methods = (isc_socketmethods_t *)&socketmethods;
sock->references = 1;
- *socketp = sock;
+ *socketp = (isc_socket_t *)sock;
/*
* Note we don't have to lock the socket like we normally would because
@@ -2494,10 +2669,50 @@ isc_socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags,
}
/*
+ * Indicate to the manager that it should watch the socket again.
+ * This can be used to restart watching if the previous event handler
+ * didn't indicate there was more data to be processed. Primarily
+ * it is for writing but could be used for reading if desired
+ */
+
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_fdwatchpoke(isc_socket_t *sock0, int flags)
+{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
+
+ REQUIRE(VALID_SOCKET(sock));
+
+ /*
+ * We check both flags first to allow us to get the lock
+ * once but only if we need it.
+ */
+
+ if ((flags & (ISC_SOCKFDWATCH_READ | ISC_SOCKFDWATCH_WRITE)) != 0) {
+ LOCK(&sock->lock);
+ if (((flags & ISC_SOCKFDWATCH_READ) != 0) &&
+ !sock->pending_recv)
+ select_poke(sock->manager, sock->fd,
+ SELECT_POKE_READ);
+ if (((flags & ISC_SOCKFDWATCH_WRITE) != 0) &&
+ !sock->pending_send)
+ select_poke(sock->manager, sock->fd,
+ SELECT_POKE_WRITE);
+ UNLOCK(&sock->lock);
+ }
+
+ socket_log(sock, NULL, TRACE, isc_msgcat, ISC_MSGSET_SOCKET,
+ ISC_MSG_POKED, "fdwatch-poked flags: %d", flags);
+
+ return (ISC_R_SUCCESS);
+}
+
+/*
* Attach to a socket. Caller must explicitly detach when it is done.
*/
-void
-isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_attach(isc_socket_t *sock0, isc_socket_t **socketp) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
+
REQUIRE(VALID_SOCKET(sock));
REQUIRE(socketp != NULL && *socketp == NULL);
@@ -2505,20 +2720,20 @@ isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
sock->references++;
UNLOCK(&sock->lock);
- *socketp = sock;
+ *socketp = (isc_socket_t *)sock;
}
/*
* Dereference a socket. If this is the last reference to it, clean things
* up by destroying the socket.
*/
-void
-isc_socket_detach(isc_socket_t **socketp) {
- isc_socket_t *sock;
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_detach(isc_socket_t **socketp) {
+ isc__socket_t *sock;
isc_boolean_t kill_socket = ISC_FALSE;
REQUIRE(socketp != NULL);
- sock = *socketp;
+ sock = (isc__socket_t *)*socketp;
REQUIRE(VALID_SOCKET(sock));
LOCK(&sock->lock);
@@ -2534,10 +2749,12 @@ isc_socket_detach(isc_socket_t **socketp) {
*socketp = NULL;
}
-isc_result_t
-isc_socket_close(isc_socket_t *sock) {
+#ifdef BIND9
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_close(isc_socket_t *sock0) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
int fd;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
isc_sockettype_t type;
REQUIRE(VALID_SOCKET(sock));
@@ -2575,6 +2792,7 @@ isc_socket_close(isc_socket_t *sock) {
return (ISC_R_SUCCESS);
}
+#endif /* BIND9 */
/*
* I/O is possible on a given socket. Schedule an event to this task that
@@ -2585,7 +2803,7 @@ isc_socket_close(isc_socket_t *sock) {
* The socket and manager must be locked before calling this function.
*/
static void
-dispatch_recv(isc_socket_t *sock) {
+dispatch_recv(isc__socket_t *sock) {
intev_t *iev;
isc_socketevent_t *ev;
isc_task_t *sender;
@@ -2619,7 +2837,7 @@ dispatch_recv(isc_socket_t *sock) {
}
static void
-dispatch_send(isc_socket_t *sock) {
+dispatch_send(isc__socket_t *sock) {
intev_t *iev;
isc_socketevent_t *ev;
isc_task_t *sender;
@@ -2656,7 +2874,7 @@ dispatch_send(isc_socket_t *sock) {
* Dispatch an internal accept event.
*/
static void
-dispatch_accept(isc_socket_t *sock) {
+dispatch_accept(isc__socket_t *sock) {
intev_t *iev;
isc_socket_newconnev_t *ev;
@@ -2682,7 +2900,7 @@ dispatch_accept(isc_socket_t *sock) {
}
static void
-dispatch_connect(isc_socket_t *sock) {
+dispatch_connect(isc__socket_t *sock) {
intev_t *iev;
isc_socket_connev_t *ev;
@@ -2712,7 +2930,7 @@ dispatch_connect(isc_socket_t *sock) {
* Caller must have the socket locked if the event is attached to the socket.
*/
static void
-send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev) {
+send_recvdone_event(isc__socket_t *sock, isc_socketevent_t **dev) {
isc_task_t *task;
task = (*dev)->ev_sender;
@@ -2735,7 +2953,7 @@ send_recvdone_event(isc_socket_t *sock, isc_socketevent_t **dev) {
* Caller must have the socket locked if the event is attached to the socket.
*/
static void
-send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev) {
+send_senddone_event(isc__socket_t *sock, isc_socketevent_t **dev) {
isc_task_t *task;
INSIST(dev != NULL && *dev != NULL);
@@ -2766,8 +2984,8 @@ send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev) {
*/
static void
internal_accept(isc_task_t *me, isc_event_t *ev) {
- isc_socket_t *sock;
- isc_socketmgr_t *manager;
+ isc__socket_t *sock;
+ isc__socketmgr_t *manager;
isc_socket_newconnev_t *dev;
isc_task_t *task;
ISC_SOCKADDR_LEN_T addrlen;
@@ -2822,9 +3040,9 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
* daemons such as BIND 8 and Apache.
*/
- addrlen = sizeof(dev->newsocket->peer_address.type);
- memset(&dev->newsocket->peer_address.type, 0, addrlen);
- fd = accept(sock->fd, &dev->newsocket->peer_address.type.sa,
+ addrlen = sizeof(NEWCONNSOCK(dev)->peer_address.type);
+ memset(&NEWCONNSOCK(dev)->peer_address.type, 0, addrlen);
+ fd = accept(sock->fd, &NEWCONNSOCK(dev)->peer_address.type.sa,
(void *)&addrlen);
#ifdef F_DUPFD
@@ -2894,14 +3112,14 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
(void)close(fd);
goto soft_error;
- } else if (dev->newsocket->peer_address.type.sa.sa_family !=
+ } else if (NEWCONNSOCK(dev)->peer_address.type.sa.sa_family !=
sock->pf)
{
UNEXPECTED_ERROR(__FILE__, __LINE__,
"internal_accept(): "
"accept() returned peer address "
"family %u (expected %u)",
- dev->newsocket->peer_address.
+ NEWCONNSOCK(dev)->peer_address.
type.sa.sa_family,
sock->pf);
(void)close(fd);
@@ -2920,8 +3138,8 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
}
if (fd != -1) {
- dev->newsocket->peer_address.length = addrlen;
- dev->newsocket->pf = sock->pf;
+ NEWCONNSOCK(dev)->peer_address.length = addrlen;
+ NEWCONNSOCK(dev)->pf = sock->pf;
}
/*
@@ -2950,28 +3168,28 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
int lockid = FDLOCK_ID(fd);
LOCK(&manager->fdlock[lockid]);
- manager->fds[fd] = dev->newsocket;
+ manager->fds[fd] = NEWCONNSOCK(dev);
manager->fdstate[fd] = MANAGED;
UNLOCK(&manager->fdlock[lockid]);
LOCK(&manager->lock);
- ISC_LIST_APPEND(manager->socklist, dev->newsocket, link);
+ ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link);
- dev->newsocket->fd = fd;
- dev->newsocket->bound = 1;
- dev->newsocket->connected = 1;
+ NEWCONNSOCK(dev)->fd = fd;
+ NEWCONNSOCK(dev)->bound = 1;
+ NEWCONNSOCK(dev)->connected = 1;
/*
* Save away the remote address
*/
- dev->address = dev->newsocket->peer_address;
+ dev->address = NEWCONNSOCK(dev)->peer_address;
#ifdef USE_SELECT
if (manager->maxfd < fd)
manager->maxfd = fd;
#endif
- socket_log(sock, &dev->newsocket->peer_address, CREATION,
+ socket_log(sock, &NEWCONNSOCK(dev)->peer_address, CREATION,
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN,
"accepted connection, new socket %p",
dev->newsocket);
@@ -2981,8 +3199,8 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
inc_stats(manager->stats, sock->statsindex[STATID_ACCEPT]);
} else {
inc_stats(manager->stats, sock->statsindex[STATID_ACCEPTFAIL]);
- dev->newsocket->references--;
- free_socket(&dev->newsocket);
+ NEWCONNSOCK(dev)->references--;
+ free_socket((isc__socket_t **)&dev->newsocket);
}
/*
@@ -3006,7 +3224,7 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
static void
internal_recv(isc_task_t *me, isc_event_t *ev) {
isc_socketevent_t *dev;
- isc_socket_t *sock;
+ isc__socket_t *sock;
INSIST(ev->ev_type == ISC_SOCKEVENT_INTR);
@@ -3071,14 +3289,14 @@ internal_recv(isc_task_t *me, isc_event_t *ev) {
static void
internal_send(isc_task_t *me, isc_event_t *ev) {
isc_socketevent_t *dev;
- isc_socket_t *sock;
+ isc__socket_t *sock;
INSIST(ev->ev_type == ISC_SOCKEVENT_INTW);
/*
* Find out what socket this is and lock it.
*/
- sock = (isc_socket_t *)ev->ev_sender;
+ sock = (isc__socket_t *)ev->ev_sender;
INSIST(VALID_SOCKET(sock));
LOCK(&sock->lock);
@@ -3125,7 +3343,7 @@ internal_send(isc_task_t *me, isc_event_t *ev) {
static void
internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) {
- isc_socket_t *sock;
+ isc__socket_t *sock;
int more_data;
INSIST(ev->ev_type == ISC_SOCKEVENT_INTW);
@@ -3133,7 +3351,7 @@ internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) {
/*
* Find out what socket this is and lock it.
*/
- sock = (isc_socket_t *)ev->ev_sender;
+ sock = (isc__socket_t *)ev->ev_sender;
INSIST(VALID_SOCKET(sock));
LOCK(&sock->lock);
@@ -3144,7 +3362,8 @@ internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) {
INSIST(sock->pending_send == 1);
UNLOCK(&sock->lock);
- more_data = (sock->fdwatchcb)(me, sock, sock->fdwatcharg);
+ more_data = (sock->fdwatchcb)(me, (isc_socket_t *)sock,
+ sock->fdwatcharg, ISC_SOCKFDWATCH_WRITE);
LOCK(&sock->lock);
sock->pending_send = 0;
@@ -3165,7 +3384,7 @@ internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) {
static void
internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) {
- isc_socket_t *sock;
+ isc__socket_t *sock;
int more_data;
INSIST(ev->ev_type == ISC_SOCKEVENT_INTR);
@@ -3173,7 +3392,7 @@ internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) {
/*
* Find out what socket this is and lock it.
*/
- sock = (isc_socket_t *)ev->ev_sender;
+ sock = (isc__socket_t *)ev->ev_sender;
INSIST(VALID_SOCKET(sock));
LOCK(&sock->lock);
@@ -3184,7 +3403,8 @@ internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) {
INSIST(sock->pending_recv == 1);
UNLOCK(&sock->lock);
- more_data = (sock->fdwatchcb)(me, sock, sock->fdwatcharg);
+ more_data = (sock->fdwatchcb)(me, (isc_socket_t *)sock,
+ sock->fdwatcharg, ISC_SOCKFDWATCH_READ);
LOCK(&sock->lock);
sock->pending_recv = 0;
@@ -3208,10 +3428,10 @@ internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) {
* and unlocking twice if both reads and writes are possible.
*/
static void
-process_fd(isc_socketmgr_t *manager, int fd, isc_boolean_t readable,
+process_fd(isc__socketmgr_t *manager, int fd, isc_boolean_t readable,
isc_boolean_t writeable)
{
- isc_socket_t *sock;
+ isc__socket_t *sock;
isc_boolean_t unlock_sock;
isc_boolean_t unwatch_read = ISC_FALSE, unwatch_write = ISC_FALSE;
int lockid = FDLOCK_ID(fd);
@@ -3277,11 +3497,11 @@ check_write:
#ifdef USE_KQUEUE
static isc_boolean_t
-process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) {
+process_fds(isc__socketmgr_t *manager, struct kevent *events, int nevents) {
int i;
isc_boolean_t readable, writable;
isc_boolean_t done = ISC_FALSE;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
isc_boolean_t have_ctlevent = ISC_FALSE;
#endif
@@ -3299,7 +3519,7 @@ process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) {
for (i = 0; i < nevents; i++) {
REQUIRE(events[i].ident < manager->maxsocks);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (events[i].ident == (uintptr_t)manager->pipe_fds[0]) {
have_ctlevent = ISC_TRUE;
continue;
@@ -3310,7 +3530,7 @@ process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) {
process_fd(manager, events[i].ident, readable, writable);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (have_ctlevent)
done = process_ctlfd(manager);
#endif
@@ -3319,10 +3539,11 @@ process_fds(isc_socketmgr_t *manager, struct kevent *events, int nevents) {
}
#elif defined(USE_EPOLL)
static isc_boolean_t
-process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) {
+process_fds(isc__socketmgr_t *manager, struct epoll_event *events, int nevents)
+{
int i;
isc_boolean_t done = ISC_FALSE;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
isc_boolean_t have_ctlevent = ISC_FALSE;
#endif
@@ -3335,7 +3556,7 @@ process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) {
for (i = 0; i < nevents; i++) {
REQUIRE(events[i].data.fd < (int)manager->maxsocks);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (events[i].data.fd == manager->pipe_fds[0]) {
have_ctlevent = ISC_TRUE;
continue;
@@ -3357,7 +3578,7 @@ process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) {
(events[i].events & EPOLLOUT) != 0);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (have_ctlevent)
done = process_ctlfd(manager);
#endif
@@ -3366,10 +3587,10 @@ process_fds(isc_socketmgr_t *manager, struct epoll_event *events, int nevents) {
}
#elif defined(USE_DEVPOLL)
static isc_boolean_t
-process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) {
+process_fds(isc__socketmgr_t *manager, struct pollfd *events, int nevents) {
int i;
isc_boolean_t done = ISC_FALSE;
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
isc_boolean_t have_ctlevent = ISC_FALSE;
#endif
@@ -3382,7 +3603,7 @@ process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) {
for (i = 0; i < nevents; i++) {
REQUIRE(events[i].fd < (int)manager->maxsocks);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (events[i].fd == manager->pipe_fds[0]) {
have_ctlevent = ISC_TRUE;
continue;
@@ -3393,7 +3614,7 @@ process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) {
(events[i].events & POLLOUT) != 0);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (have_ctlevent)
done = process_ctlfd(manager);
#endif
@@ -3402,27 +3623,27 @@ process_fds(isc_socketmgr_t *manager, struct pollfd *events, int nevents) {
}
#elif defined(USE_SELECT)
static void
-process_fds(isc_socketmgr_t *manager, int maxfd,
- fd_set *readfds, fd_set *writefds)
+process_fds(isc__socketmgr_t *manager, int maxfd, fd_set *readfds,
+ fd_set *writefds)
{
int i;
REQUIRE(maxfd <= (int)manager->maxsocks);
for (i = 0; i < maxfd; i++) {
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (i == manager->pipe_fds[0] || i == manager->pipe_fds[1])
continue;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
process_fd(manager, i, FD_ISSET(i, readfds),
FD_ISSET(i, writefds));
}
}
#endif
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
static isc_boolean_t
-process_ctlfd(isc_socketmgr_t *manager) {
+process_ctlfd(isc__socketmgr_t *manager) {
int msg, fd;
for (;;) {
@@ -3470,7 +3691,7 @@ process_ctlfd(isc_socketmgr_t *manager) {
*/
static isc_threadresult_t
watcher(void *uap) {
- isc_socketmgr_t *manager = uap;
+ isc__socketmgr_t *manager = uap;
isc_boolean_t done;
int ctlfd;
int cc;
@@ -3585,22 +3806,34 @@ watcher(void *uap) {
return ((isc_threadresult_t)0);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
-void
-isc__socketmgr_setreserved(isc_socketmgr_t *manager, isc_uint32_t reserved) {
+#ifdef BIND9
+ISC_SOCKETFUNC_SCOPE void
+isc__socketmgr_setreserved(isc_socketmgr_t *manager0, isc_uint32_t reserved) {
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
REQUIRE(VALID_MANAGER(manager));
manager->reserved = reserved;
}
+ISC_SOCKETFUNC_SCOPE void
+isc___socketmgr_maxudp(isc_socketmgr_t *manager0, int maxudp) {
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
+
+ REQUIRE(VALID_MANAGER(manager));
+
+ manager->maxudp = maxudp;
+}
+#endif /* BIND9 */
+
/*
* Create a new socket manager.
*/
static isc_result_t
-setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
+setup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) {
isc_result_t result;
#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL)
char strbuf[ISC_STRERRORSIZE];
@@ -3626,7 +3859,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
return (result);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
if (result != ISC_R_SUCCESS) {
close(manager->kqueue_fd);
@@ -3634,7 +3867,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
sizeof(struct kevent) * manager->nevents);
return (result);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#elif defined(USE_EPOLL)
manager->nevents = ISC_SOCKET_MAXEVENTS;
manager->events = isc_mem_get(mctx, sizeof(struct epoll_event) *
@@ -3654,7 +3887,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
sizeof(struct epoll_event) * manager->nevents);
return (result);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
if (result != ISC_R_SUCCESS) {
close(manager->epoll_fd);
@@ -3662,7 +3895,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
sizeof(struct epoll_event) * manager->nevents);
return (result);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#elif defined(USE_DEVPOLL)
/*
* XXXJT: /dev/poll seems to reject large numbers of events,
@@ -3700,7 +3933,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
sizeof(pollinfo_t) * manager->maxsocks);
return (result);
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
result = watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
if (result != ISC_R_SUCCESS) {
close(manager->devpoll_fd);
@@ -3710,7 +3943,7 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
sizeof(pollinfo_t) * manager->maxsocks);
return (result);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#elif defined(USE_SELECT)
UNUSED(result);
@@ -3758,20 +3991,20 @@ setup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
memset(manager->read_fds, 0, manager->fd_bufsize);
memset(manager->write_fds, 0, manager->fd_bufsize);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
(void)watch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
manager->maxfd = manager->pipe_fds[0];
-#else /* ISC_PLATFORM_USETHREADS */
+#else /* USE_WATCHER_THREAD */
manager->maxfd = 0;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#endif /* USE_KQUEUE */
return (ISC_R_SUCCESS);
}
static void
-cleanup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
-#ifdef ISC_PLATFORM_USETHREADS
+cleanup_watcher(isc_mem_t *mctx, isc__socketmgr_t *manager) {
+#ifdef USE_WATCHER_THREAD
isc_result_t result;
result = unwatch_fd(manager, manager->pipe_fds[0], SELECT_POKE_READ);
@@ -3781,7 +4014,7 @@ cleanup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"));
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
#ifdef USE_KQUEUE
close(manager->kqueue_fd);
@@ -3809,35 +4042,35 @@ cleanup_watcher(isc_mem_t *mctx, isc_socketmgr_t *manager) {
#endif /* USE_KQUEUE */
}
-isc_result_t
-isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
- return (isc_socketmgr_create2(mctx, managerp, 0));
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
+ return (isc__socketmgr_create2(mctx, managerp, 0));
}
-isc_result_t
-isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
- unsigned int maxsocks)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
+ unsigned int maxsocks)
{
int i;
- isc_socketmgr_t *manager;
-#ifdef ISC_PLATFORM_USETHREADS
+ isc__socketmgr_t *manager;
+#ifdef USE_WATCHER_THREAD
char strbuf[ISC_STRERRORSIZE];
#endif
isc_result_t result;
REQUIRE(managerp != NULL && *managerp == NULL);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
if (socketmgr != NULL) {
/* Don't allow maxsocks to be updated */
if (maxsocks > 0 && socketmgr->maxsocks != maxsocks)
return (ISC_R_EXISTS);
socketmgr->refs++;
- *managerp = socketmgr;
+ *managerp = (isc_socketmgr_t *)socketmgr;
return (ISC_R_SUCCESS);
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
if (maxsocks == 0)
maxsocks = ISC_SOCKET_MAXSOCKETS;
@@ -3850,8 +4083,9 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
memset(manager, 0, sizeof(*manager));
manager->maxsocks = maxsocks;
manager->reserved = 0;
+ manager->maxudp = 0;
manager->fds = isc_mem_get(mctx,
- manager->maxsocks * sizeof(isc_socket_t *));
+ manager->maxsocks * sizeof(isc__socket_t *));
if (manager->fds == NULL) {
result = ISC_R_NOMEMORY;
goto free_manager;
@@ -3863,7 +4097,9 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
}
manager->stats = NULL;
- manager->magic = SOCKET_MANAGER_MAGIC;
+ manager->common.methods = &socketmgrmethods;
+ manager->common.magic = ISCAPI_SOCKETMGR_MAGIC;
+ manager->common.impmagic = SOCKET_MANAGER_MAGIC;
manager->mctx = NULL;
memset(manager->fds, 0, manager->maxsocks * sizeof(isc_socket_t *));
ISC_LIST_INIT(manager->socklist);
@@ -3887,7 +4123,7 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
}
}
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_condition_init() %s",
@@ -3916,9 +4152,11 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
#if 0
RUNTIME_CHECK(make_nonblock(manager->pipe_fds[1]) == ISC_R_SUCCESS);
#endif
-#else /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
+
+#ifdef USE_SHARED_MANAGER
manager->refs = 1;
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_SHARED_MANAGER */
/*
* Set up initial state for the select loop
@@ -3927,7 +4165,7 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
if (result != ISC_R_SUCCESS)
goto cleanup;
memset(manager->fdstate, 0, manager->maxsocks * sizeof(int));
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
/*
* Start up the select/poll thread.
*/
@@ -3941,26 +4179,26 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
result = ISC_R_UNEXPECTED;
goto cleanup;
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
isc_mem_attach(mctx, &manager->mctx);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
socketmgr = manager;
-#endif /* ISC_PLATFORM_USETHREADS */
- *managerp = manager;
+#endif /* USE_SHARED_MANAGER */
+ *managerp = (isc_socketmgr_t *)manager;
return (ISC_R_SUCCESS);
cleanup:
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
(void)close(manager->pipe_fds[0]);
(void)close(manager->pipe_fds[1]);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
cleanup_condition:
(void)isc_condition_destroy(&manager->shutdown_ok);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
cleanup_lock:
@@ -3988,8 +4226,10 @@ free_manager:
return (result);
}
+#ifdef BIND9
isc_result_t
-isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) {
+isc__socketmgr_getmaxsockets(isc_socketmgr_t *manager0, unsigned int *nsockp) {
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(nsockp != NULL);
@@ -3999,7 +4239,9 @@ isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp) {
}
void
-isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) {
+isc__socketmgr_setstats(isc_socketmgr_t *manager0, isc_stats_t *stats) {
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
+
REQUIRE(VALID_MANAGER(manager));
REQUIRE(ISC_LIST_EMPTY(manager->socklist));
REQUIRE(manager->stats == NULL);
@@ -4007,10 +4249,11 @@ isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) {
isc_stats_attach(stats, &manager->stats);
}
+#endif
-void
-isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
- isc_socketmgr_t *manager;
+ISC_SOCKETFUNC_SCOPE void
+isc__socketmgr_destroy(isc_socketmgr_t **managerp) {
+ isc__socketmgr_t *manager;
int i;
isc_mem_t *mctx;
@@ -4019,42 +4262,36 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
*/
REQUIRE(managerp != NULL);
- manager = *managerp;
+ manager = (isc__socketmgr_t *)*managerp;
REQUIRE(VALID_MANAGER(manager));
-#ifndef ISC_PLATFORM_USETHREADS
- if (manager->refs > 1) {
- manager->refs--;
+#ifdef USE_SHARED_MANAGER
+ manager->refs--;
+ if (manager->refs > 0) {
*managerp = NULL;
return;
}
-#endif /* ISC_PLATFORM_USETHREADS */
+ socketmgr = NULL;
+#endif /* USE_SHARED_MANAGER */
LOCK(&manager->lock);
-#ifdef ISC_PLATFORM_USETHREADS
/*
* Wait for all sockets to be destroyed.
*/
while (!ISC_LIST_EMPTY(manager->socklist)) {
+#ifdef USE_WATCHER_THREAD
manager_log(manager, CREATION, "%s",
isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET,
ISC_MSG_SOCKETSREMAIN,
"sockets exist"));
WAIT(&manager->shutdown_ok, &manager->lock);
+#else /* USE_WATCHER_THREAD */
+ UNLOCK(&manager->lock);
+ isc__taskmgr_dispatch(NULL);
+ LOCK(&manager->lock);
+#endif /* USE_WATCHER_THREAD */
}
-#else /* ISC_PLATFORM_USETHREADS */
- /*
- * Hope all sockets have been destroyed.
- */
- if (!ISC_LIST_EMPTY(manager->socklist)) {
- manager_log(manager, CREATION, "%s",
- isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET,
- ISC_MSG_SOCKETSREMAIN,
- "sockets exist"));
- INSIST(0);
- }
-#endif /* ISC_PLATFORM_USETHREADS */
UNLOCK(&manager->lock);
@@ -4065,7 +4302,7 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
*/
select_poke(manager, 0, SELECT_POKE_SHUTDOWN);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
/*
* Wait for thread to exit.
*/
@@ -4074,25 +4311,25 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
"isc_thread_join() %s",
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
ISC_MSG_FAILED, "failed"));
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
/*
* Clean up.
*/
cleanup_watcher(manager->mctx, manager);
-#ifdef ISC_PLATFORM_USETHREADS
+#ifdef USE_WATCHER_THREAD
(void)close(manager->pipe_fds[0]);
(void)close(manager->pipe_fds[1]);
(void)isc_condition_destroy(&manager->shutdown_ok);
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
for (i = 0; i < (int)manager->maxsocks; i++)
if (manager->fdstate[i] == CLOSE_PENDING) /* no need to lock */
(void)close(i);
isc_mem_put(manager->mctx, manager->fds,
- manager->maxsocks * sizeof(isc_socket_t *));
+ manager->maxsocks * sizeof(isc__socket_t *));
isc_mem_put(manager->mctx, manager->fdstate,
manager->maxsocks * sizeof(int));
@@ -4106,17 +4343,22 @@ isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
FDLOCK_COUNT * sizeof(isc_mutex_t));
}
DESTROYLOCK(&manager->lock);
- manager->magic = 0;
+ manager->common.magic = 0;
+ manager->common.impmagic = 0;
mctx= manager->mctx;
isc_mem_put(mctx, manager, sizeof(*manager));
isc_mem_detach(&mctx);
*managerp = NULL;
+
+#ifdef USE_SHARED_MANAGER
+ socketmgr = NULL;
+#endif
}
static isc_result_t
-socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
+socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
unsigned int flags)
{
int io_state;
@@ -4187,13 +4429,14 @@ socket_recv(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
return (result);
}
-isc_result_t
-isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
- unsigned int minimum, isc_task_t *task,
- isc_taskaction_t action, const void *arg)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recvv(isc_socket_t *sock0, isc_bufferlist_t *buflist,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socketevent_t *dev;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
unsigned int iocount;
isc_buffer_t *buffer;
@@ -4241,12 +4484,14 @@ isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
return (socket_recv(sock, dev, task, 0));
}
-isc_result_t
-isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recv(isc_socket_t *sock0, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socketevent_t *dev;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
REQUIRE(VALID_SOCKET(sock));
REQUIRE(action != NULL);
@@ -4260,14 +4505,16 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region, unsigned int minimum,
if (dev == NULL)
return (ISC_R_NOMEMORY);
- return (isc_socket_recv2(sock, region, minimum, task, dev, 0));
+ return (isc__socket_recv2(sock0, region, minimum, task, dev, 0));
}
-isc_result_t
-isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
- unsigned int minimum, isc_task_t *task,
- isc_socketevent_t *event, unsigned int flags)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_recv2(isc_socket_t *sock0, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_socketevent_t *event, unsigned int flags)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
+
event->ev_sender = sock;
event->result = ISC_R_UNEXPECTED;
ISC_LIST_INIT(event->bufferlist);
@@ -4292,7 +4539,7 @@ isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
}
static isc_result_t
-socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
+socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
unsigned int flags)
{
@@ -4383,24 +4630,25 @@ socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
return (result);
}
-isc_result_t
-isc_socket_send(isc_socket_t *sock, isc_region_t *region,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_send(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg)
{
/*
* REQUIRE() checking is performed in isc_socket_sendto().
*/
- return (isc_socket_sendto(sock, region, task, action, arg, NULL,
- NULL));
+ return (isc__socket_sendto(sock, region, task, action, arg, NULL,
+ NULL));
}
-isc_result_t
-isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
- isc_task_t *task, isc_taskaction_t action, const void *arg,
- isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendto(isc_socket_t *sock0, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socketevent_t *dev;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
REQUIRE(VALID_SOCKET(sock));
REQUIRE(region != NULL);
@@ -4422,21 +4670,22 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
return (socket_send(sock, dev, task, address, pktinfo, 0));
}
-isc_result_t
-isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
- isc_task_t *task, isc_taskaction_t action, const void *arg)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg)
{
- return (isc_socket_sendtov(sock, buflist, task, action, arg, NULL,
- NULL));
+ return (isc__socket_sendtov(sock, buflist, task, action, arg, NULL,
+ NULL));
}
-isc_result_t
-isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
- isc_task_t *task, isc_taskaction_t action, const void *arg,
- isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendtov(isc_socket_t *sock0, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socketevent_t *dev;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
unsigned int iocount;
isc_buffer_t *buffer;
@@ -4470,12 +4719,15 @@ isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
return (socket_send(sock, dev, task, address, pktinfo, 0));
}
-isc_result_t
-isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
- isc_task_t *task,
- isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
- isc_socketevent_t *event, unsigned int flags)
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_sendto2(isc_socket_t *sock0, isc_region_t *region,
+ isc_task_t *task,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
+ isc_socketevent_t *event, unsigned int flags)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
+
+ REQUIRE(VALID_SOCKET(sock));
REQUIRE((flags & ~(ISC_SOCKFLAG_IMMEDIATE|ISC_SOCKFLAG_NORETRY)) == 0);
if ((flags & ISC_SOCKFLAG_NORETRY) != 0)
REQUIRE(sock->type == isc_sockettype_udp);
@@ -4490,8 +4742,8 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
return (socket_send(sock, event, task, address, pktinfo, flags));
}
-void
-isc_socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) {
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) {
#ifdef ISC_PLATFORM_HAVESYSUNH
int s;
struct stat sb;
@@ -4620,8 +4872,8 @@ isc_socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) {
#endif
}
-isc_result_t
-isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
isc_uint32_t owner, isc_uint32_t group)
{
#ifdef ISC_PLATFORM_HAVESYSUNH
@@ -4674,12 +4926,15 @@ isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
#endif
}
-isc_result_t
-isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
- unsigned int options) {
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_bind(isc_socket_t *sock0, isc_sockaddr_t *sockaddr,
+ unsigned int options) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
char strbuf[ISC_STRERRORSIZE];
int on = 1;
+ REQUIRE(VALID_SOCKET(sock));
+
LOCK(&sock->lock);
INSIST(!sock->bound);
@@ -4745,8 +5000,9 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
*/
#undef ENABLE_ACCEPTFILTER
-isc_result_t
-isc_socket_filter(isc_socket_t *sock, const char *filter) {
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_filter(isc_socket_t *sock0, const char *filter) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
#if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER)
char strbuf[ISC_STRERRORSIZE];
struct accept_filter_arg afa;
@@ -4784,8 +5040,9 @@ isc_socket_filter(isc_socket_t *sock, const char *filter) {
* is a new connection we'll have to allocate a new one anyway, so we might
* as well keep things simple rather than having to track them.
*/
-isc_result_t
-isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_listen(isc_socket_t *sock0, unsigned int backlog) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
char strbuf[ISC_STRERRORSIZE];
REQUIRE(VALID_SOCKET(sock));
@@ -4818,14 +5075,15 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
/*
* This should try to do aggressive accept() XXXMLG
*/
-isc_result_t
-isc_socket_accept(isc_socket_t *sock,
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_accept(isc_socket_t *sock0,
isc_task_t *task, isc_taskaction_t action, const void *arg)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socket_newconnev_t *dev;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
isc_task_t *ntask = NULL;
- isc_socket_t *nsock;
+ isc__socket_t *nsock;
isc_result_t result;
isc_boolean_t do_poke = ISC_FALSE;
@@ -4872,7 +5130,7 @@ isc_socket_accept(isc_socket_t *sock,
nsock->statsindex = sock->statsindex;
dev->ev_sender = ntask;
- dev->newsocket = nsock;
+ dev->newsocket = (isc_socket_t *)nsock;
/*
* Poke watcher here. We still have the socket locked, so there
@@ -4891,13 +5149,14 @@ isc_socket_accept(isc_socket_t *sock,
return (ISC_R_SUCCESS);
}
-isc_result_t
-isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_connect(isc_socket_t *sock0, isc_sockaddr_t *addr,
isc_task_t *task, isc_taskaction_t action, const void *arg)
{
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_socket_connev_t *dev;
isc_task_t *ntask = NULL;
- isc_socketmgr_t *manager;
+ isc__socketmgr_t *manager;
int cc;
char strbuf[ISC_STRERRORSIZE];
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
@@ -5037,7 +5296,7 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
*/
static void
internal_connect(isc_task_t *me, isc_event_t *ev) {
- isc_socket_t *sock;
+ isc__socket_t *sock;
isc_socket_connev_t *dev;
isc_task_t *task;
int cc;
@@ -5151,8 +5410,9 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
isc_task_sendanddetach(&task, ISC_EVENT_PTR(&dev));
}
-isc_result_t
-isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_getpeername(isc_socket_t *sock0, isc_sockaddr_t *addressp) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_result_t result;
REQUIRE(VALID_SOCKET(sock));
@@ -5172,8 +5432,9 @@ isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
return (result);
}
-isc_result_t
-isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
+ISC_SOCKETFUNC_SCOPE isc_result_t
+isc__socket_getsockname(isc_socket_t *sock0, isc_sockaddr_t *addressp) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
ISC_SOCKADDR_LEN_T len;
isc_result_t result;
char strbuf[ISC_STRERRORSIZE];
@@ -5210,8 +5471,9 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
* Run through the list of events on this socket, and cancel the ones
* queued for task "task" of type "how". "how" is a bitmask.
*/
-void
-isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
REQUIRE(VALID_SOCKET(sock));
@@ -5290,8 +5552,8 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
ISC_LIST_UNLINK(sock->accept_list, dev,
ev_link);
- dev->newsocket->references--;
- free_socket(&dev->newsocket);
+ NEWCONNSOCK(dev)->references--;
+ free_socket((isc__socket_t **)&dev->newsocket);
dev->result = ISC_R_CANCELED;
dev->ev_sender = sock;
@@ -5330,17 +5592,22 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
UNLOCK(&sock->lock);
}
-isc_sockettype_t
-isc_socket_gettype(isc_socket_t *sock) {
+ISC_SOCKETFUNC_SCOPE isc_sockettype_t
+isc__socket_gettype(isc_socket_t *sock0) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
+
REQUIRE(VALID_SOCKET(sock));
return (sock->type);
}
-isc_boolean_t
-isc_socket_isbound(isc_socket_t *sock) {
+ISC_SOCKETFUNC_SCOPE isc_boolean_t
+isc__socket_isbound(isc_socket_t *sock0) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
isc_boolean_t val;
+ REQUIRE(VALID_SOCKET(sock));
+
LOCK(&sock->lock);
val = ((sock->bound) ? ISC_TRUE : ISC_FALSE);
UNLOCK(&sock->lock);
@@ -5348,8 +5615,9 @@ isc_socket_isbound(isc_socket_t *sock) {
return (val);
}
-void
-isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
+ISC_SOCKETFUNC_SCOPE void
+isc__socket_ipv6only(isc_socket_t *sock0, isc_boolean_t yes) {
+ isc__socket_t *sock = (isc__socket_t *)sock0;
#if defined(IPV6_V6ONLY)
int onoff = yes ? 1 : 0;
#else
@@ -5379,12 +5647,21 @@ isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
#endif
}
-#ifndef ISC_PLATFORM_USETHREADS
-/* In our assumed scenario, we can simply use a single static object. */
+#ifndef USE_WATCHER_THREAD
+/*
+ * In our assumed scenario, we can simply use a single static object.
+ * XXX: this is not true if the application uses multiple threads with
+ * 'multi-context' mode. Fixing this is a future TODO item.
+ */
static isc_socketwait_t swait_private;
int
-isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) {
+isc__socketmgr_waitevents(isc_socketmgr_t *manager0, struct timeval *tvp,
+ isc_socketwait_t **swaitp)
+{
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
+
+
int n;
#ifdef USE_KQUEUE
struct timespec ts, *tsp;
@@ -5398,7 +5675,11 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) {
REQUIRE(swaitp != NULL && *swaitp == NULL);
- if (socketmgr == NULL)
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = socketmgr;
+#endif
+ if (manager == NULL)
return (0);
#ifdef USE_KQUEUE
@@ -5408,8 +5689,8 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) {
tsp = &ts;
} else
tsp = NULL;
- swait_private.nevents = kevent(socketmgr->kqueue_fd, NULL, 0,
- socketmgr->events, socketmgr->nevents,
+ swait_private.nevents = kevent(manager->kqueue_fd, NULL, 0,
+ manager->events, manager->nevents,
tsp);
n = swait_private.nevents;
#elif defined(USE_EPOLL)
@@ -5417,29 +5698,28 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) {
timeout = tvp->tv_sec * 1000 + (tvp->tv_usec + 999) / 1000;
else
timeout = -1;
- swait_private.nevents = epoll_wait(socketmgr->epoll_fd,
- socketmgr->events,
- socketmgr->nevents, timeout);
+ swait_private.nevents = epoll_wait(manager->epoll_fd,
+ manager->events,
+ manager->nevents, timeout);
n = swait_private.nevents;
#elif defined(USE_DEVPOLL)
- dvp.dp_fds = socketmgr->events;
- dvp.dp_nfds = socketmgr->nevents;
+ dvp.dp_fds = manager->events;
+ dvp.dp_nfds = manager->nevents;
if (tvp != NULL) {
dvp.dp_timeout = tvp->tv_sec * 1000 +
(tvp->tv_usec + 999) / 1000;
} else
dvp.dp_timeout = -1;
- swait_private.nevents = ioctl(socketmgr->devpoll_fd, DP_POLL, &dvp);
+ swait_private.nevents = ioctl(manager->devpoll_fd, DP_POLL, &dvp);
n = swait_private.nevents;
#elif defined(USE_SELECT)
- memcpy(socketmgr->read_fds_copy, socketmgr->read_fds,
- socketmgr->fd_bufsize);
- memcpy(socketmgr->write_fds_copy, socketmgr->write_fds,
- socketmgr->fd_bufsize);
+ memcpy(manager->read_fds_copy, manager->read_fds, manager->fd_bufsize);
+ memcpy(manager->write_fds_copy, manager->write_fds,
+ manager->fd_bufsize);
- swait_private.readset = socketmgr->read_fds_copy;
- swait_private.writeset = socketmgr->write_fds_copy;
- swait_private.maxfd = socketmgr->maxfd + 1;
+ swait_private.readset = manager->read_fds_copy;
+ swait_private.writeset = manager->write_fds_copy;
+ swait_private.maxfd = manager->maxfd + 1;
n = select(swait_private.maxfd, swait_private.readset,
swait_private.writeset, NULL, tvp);
@@ -5450,24 +5730,32 @@ isc__socketmgr_waitevents(struct timeval *tvp, isc_socketwait_t **swaitp) {
}
isc_result_t
-isc__socketmgr_dispatch(isc_socketwait_t *swait) {
+isc__socketmgr_dispatch(isc_socketmgr_t *manager0, isc_socketwait_t *swait) {
+ isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
+
REQUIRE(swait == &swait_private);
- if (socketmgr == NULL)
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = socketmgr;
+#endif
+ if (manager == NULL)
return (ISC_R_NOTFOUND);
#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL)
- (void)process_fds(socketmgr, socketmgr->events, swait->nevents);
+ (void)process_fds(manager, manager->events, swait->nevents);
return (ISC_R_SUCCESS);
#elif defined(USE_SELECT)
- process_fds(socketmgr, swait->maxfd, swait->readset, swait->writeset);
+ process_fds(manager, swait->maxfd, swait->readset, swait->writeset);
return (ISC_R_SUCCESS);
#endif
}
-#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* USE_WATCHER_THREAD */
+#ifdef BIND9
void
-isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) {
+isc__socket_setname(isc_socket_t *socket0, const char *name, void *tag) {
+ isc__socket_t *socket = (isc__socket_t *)socket0;
/*
* Name 'socket'.
@@ -5482,17 +5770,29 @@ isc_socket_setname(isc_socket_t *socket, const char *name, void *tag) {
UNLOCK(&socket->lock);
}
-const char *
-isc_socket_getname(isc_socket_t *socket) {
+ISC_SOCKETFUNC_SCOPE const char *
+isc__socket_getname(isc_socket_t *socket0) {
+ isc__socket_t *socket = (isc__socket_t *)socket0;
+
return (socket->name);
}
void *
-isc_socket_gettag(isc_socket_t *socket) {
+isc__socket_gettag(isc_socket_t *socket0) {
+ isc__socket_t *socket = (isc__socket_t *)socket0;
+
return (socket->tag);
}
+#endif /* BIND9 */
-#ifdef HAVE_LIBXML2
+#ifdef USE_SOCKETIMPREGISTER
+isc_result_t
+isc__socket_register() {
+ return (isc_socket_register(isc__socketmgr_create));
+}
+#endif
+
+#if defined(HAVE_LIBXML2) && defined(BIND9)
static const char *
_socktype(isc_sockettype_t type)
@@ -5509,21 +5809,21 @@ _socktype(isc_sockettype_t type)
return ("not-initialized");
}
-void
-isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer)
-{
- isc_socket_t *sock;
+ISC_SOCKETFUNC_SCOPE void
+isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) {
+ isc__socketmgr_t *mgr = (isc__socketmgr_t *)mgr0;
+ isc__socket_t *sock;
char peerbuf[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_t addr;
ISC_SOCKADDR_LEN_T len;
LOCK(&mgr->lock);
-#ifndef ISC_PLATFORM_USETHREADS
+#ifdef USE_SHARED_MANAGER
xmlTextWriterStartElement(writer, ISC_XMLCHAR "references");
xmlTextWriterWriteFormatString(writer, "%d", mgr->refs);
xmlTextWriterEndElement(writer);
-#endif
+#endif /* USE_SHARED_MANAGER */
xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets");
sock = ISC_LIST_HEAD(mgr->socklist);
diff --git a/lib/isc/unix/socket_p.h b/lib/isc/unix/socket_p.h
index b9a234765b1e..b6c4b6a909af 100644
--- a/lib/isc/unix/socket_p.h
+++ b/lib/isc/unix/socket_p.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket_p.h,v 1.13 2008-06-23 23:47:11 tbox Exp $ */
+/* $Id: socket_p.h,v 1.15 2009-09-02 23:48:03 tbox Exp $ */
#ifndef ISC_SOCKET_P_H
#define ISC_SOCKET_P_H
@@ -27,6 +27,7 @@
#endif
typedef struct isc_socketwait isc_socketwait_t;
-int isc__socketmgr_waitevents(struct timeval *, isc_socketwait_t **);
-isc_result_t isc__socketmgr_dispatch(isc_socketwait_t *);
+int isc__socketmgr_waitevents(isc_socketmgr_t *, struct timeval *,
+ isc_socketwait_t **);
+isc_result_t isc__socketmgr_dispatch(isc_socketmgr_t *, isc_socketwait_t *);
#endif /* ISC_SOCKET_P_H */
diff --git a/lib/isc/unix/strerror.c b/lib/isc/unix/strerror.c
index 08ea52d2b2bc..4a61a975ebb5 100644
--- a/lib/isc/unix/strerror.c
+++ b/lib/isc/unix/strerror.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: strerror.c,v 1.8.332.2 2009-02-16 23:47:15 tbox Exp $ */
+/* $Id: strerror.c,v 1.10 2009-02-16 23:48:04 tbox Exp $ */
/*! \file */
diff --git a/lib/isccc/Makefile.in b/lib/isccc/Makefile.in
index fb08fcdfe679..14171724600c 100644
--- a/lib/isccc/Makefile.in
+++ b/lib/isccc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001, 2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.9 2007-06-19 23:47:21 tbox Exp $
+# $Id: Makefile.in,v 1.12.244.1.2.1 2011-06-02 23:47:37 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -71,7 +71,7 @@ libisccc.la: ${OBJS}
${LIBTOOL_MODE_LINK} \
${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccc.la -rpath ${libdir} \
-version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
- ${OBJS} ${LIBS} ${ISCLIBS}
+ ${OBJS} ${ISCLIBS} ${LIBS}
timestamp: libisccc.@A@
touch timestamp
diff --git a/lib/isccc/api b/lib/isccc/api
index 2240cdda3ac8..94575eb4ef20 100644
--- a/lib/isccc/api
+++ b/lib/isccc/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 50
-LIBREVISION = 1
+LIBINTERFACE = 80
+LIBREVISION = 0
LIBAGE = 0
diff --git a/lib/isccfg/Makefile.in b/lib/isccfg/Makefile.in
index 4c55a16bcd20..37b0a26777b2 100644
--- a/lib/isccfg/Makefile.in
+++ b/lib/isccfg/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.18 2007-06-19 23:47:22 tbox Exp $
+# $Id: Makefile.in,v 1.21.244.1.2.1 2011-06-02 23:47:37 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -27,7 +27,7 @@ top_srcdir = @top_srcdir@
CINCLUDES = -I. ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES}
-CDEFINES = @USE_DLZ@
+CDEFINES = @USE_DLZ@
CWARNINGS =
ISCLIBS = ../../lib/isc/libisc.@A@
@@ -68,7 +68,7 @@ libisccfg.la: ${OBJS}
${LIBTOOL_MODE_LINK} \
${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccfg.la -rpath ${libdir} \
-version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
- ${OBJS} ${LIBS} ${DNSLIBS} ${ISCCCLIBS} ${ISCLIBS}
+ ${OBJS} ${DNSLIBS} ${ISCCCLIBS} ${ISCLIBS} ${LIBS}
timestamp: libisccfg.@A@
touch timestamp
diff --git a/lib/isccfg/aclconf.c b/lib/isccfg/aclconf.c
index 6bf0ad8968be..44d436a41664 100644
--- a/lib/isccfg/aclconf.c
+++ b/lib/isccfg/aclconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: aclconf.c,v 1.22.34.4 2009-10-01 23:47:17 tbox Exp $ */
+/* $Id: aclconf.c,v 1.29 2010-08-13 23:47:03 tbox Exp $ */
#include <config.h>
@@ -39,7 +39,7 @@ cfg_aclconfctx_init(cfg_aclconfctx_t *ctx) {
}
void
-cfg_aclconfctx_destroy(cfg_aclconfctx_t *ctx) {
+cfg_aclconfctx_clear(cfg_aclconfctx_t *ctx) {
dns_acl_t *dacl, *next;
for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache);
@@ -51,6 +51,23 @@ cfg_aclconfctx_destroy(cfg_aclconfctx_t *ctx) {
}
}
+void
+cfg_aclconfctx_clone(cfg_aclconfctx_t *src, cfg_aclconfctx_t *dest) {
+ dns_acl_t *dacl, *next;
+ REQUIRE(src != NULL && dest != NULL);
+
+ cfg_aclconfctx_init(dest);
+ for (dacl = ISC_LIST_HEAD(src->named_acl_cache);
+ dacl != NULL;
+ dacl = next)
+ {
+ dns_acl_t *copy;
+ next = ISC_LIST_NEXT(dacl, nextincache);
+ dns_acl_attach(dacl, &copy);
+ ISC_LIST_APPEND(dest->named_acl_cache, copy, nextincache);
+ }
+}
+
/*
* Find the definition of the named acl whose name is "name".
*/
@@ -150,7 +167,7 @@ convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx,
isc_buffer_add(&buf, keylen);
dns_fixedname_init(&fixname);
result = dns_name_fromtext(dns_fixedname_name(&fixname), &buf,
- dns_rootname, ISC_FALSE, NULL);
+ dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(keyobj, lctx, ISC_LOG_WARNING,
"key name '%s' is not a valid domain name",
diff --git a/lib/isccfg/api b/lib/isccfg/api
index fbbf923b5324..7821c32a541b 100644
--- a/lib/isccfg/api
+++ b/lib/isccfg/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 50
-LIBREVISION = 3
-LIBAGE = 0
+LIBINTERFACE = 81
+LIBREVISION = 1
+LIBAGE = 1
diff --git a/lib/isccfg/dnsconf.c b/lib/isccfg/dnsconf.c
new file mode 100644
index 000000000000..7091d6363318
--- /dev/null
+++ b/lib/isccfg/dnsconf.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: dnsconf.c,v 1.4 2009-09-02 23:48:03 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <isccfg/cfg.h>
+#include <isccfg/grammar.h>
+
+/*%
+ * A trusted key, as used in the "trusted-keys" statement.
+ */
+static cfg_tuplefielddef_t trustedkey_fields[] = {
+ { "name", &cfg_type_astring, 0 },
+ { "flags", &cfg_type_uint32, 0 },
+ { "protocol", &cfg_type_uint32, 0 },
+ { "algorithm", &cfg_type_uint32, 0 },
+ { "key", &cfg_type_qstring, 0 },
+ { NULL, NULL, 0 }
+};
+
+static cfg_type_t cfg_type_trustedkey = {
+ "trustedkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, trustedkey_fields
+};
+
+static cfg_type_t cfg_type_trustedkeys = {
+ "trusted-keys", cfg_parse_bracketed_list, cfg_print_bracketed_list,
+ cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_trustedkey
+};
+
+/*%
+ * Clauses that can be found within the top level of the dns.conf
+ * file only.
+ */
+static cfg_clausedef_t
+dnsconf_clauses[] = {
+ { "trusted-keys", &cfg_type_trustedkeys, CFG_CLAUSEFLAG_MULTI },
+ { NULL, NULL, 0 }
+};
+
+/*% The top-level dns.conf syntax. */
+
+static cfg_clausedef_t *
+dnsconf_clausesets[] = {
+ dnsconf_clauses,
+ NULL
+};
+
+LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_dnsconf = {
+ "dnsconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
+ &cfg_rep_map, dnsconf_clausesets
+};
diff --git a/lib/isccfg/include/isccfg/aclconf.h b/lib/isccfg/include/isccfg/aclconf.h
index f2ab70feda25..49aef03ad6aa 100644
--- a/lib/isccfg/include/isccfg/aclconf.h
+++ b/lib/isccfg/include/isccfg/aclconf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: aclconf.h,v 1.10 2007-10-12 04:17:18 each Exp $ */
+/* $Id: aclconf.h,v 1.12 2010-08-13 23:47:04 tbox Exp $ */
#ifndef ISCCFG_ACLCONF_H
#define ISCCFG_ACLCONF_H 1
@@ -44,9 +44,15 @@ cfg_aclconfctx_init(cfg_aclconfctx_t *ctx);
*/
void
-cfg_aclconfctx_destroy(cfg_aclconfctx_t *ctx);
+cfg_aclconfctx_clone(cfg_aclconfctx_t *src, cfg_aclconfctx_t *dest);
/*
- * Destroy an ACL configuration context.
+ * Copy the contents of one ACL configuration context into another.
+ */
+
+void
+cfg_aclconfctx_clear(cfg_aclconfctx_t *ctx);
+/*
+ * Clear the contents of an ACL configuration context.
*/
isc_result_t
diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h
index 06efa3548309..82900d6a6c38 100644
--- a/lib/isccfg/include/isccfg/cfg.h
+++ b/lib/isccfg/include/isccfg/cfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: cfg.h,v 1.44 2007-10-12 04:17:18 each Exp $ */
+/* $Id: cfg.h,v 1.46 2010-08-13 23:47:04 tbox Exp $ */
#ifndef ISCCFG_CFG_H
#define ISCCFG_CFG_H 1
@@ -35,6 +35,7 @@
#include <isc/formatcheck.h>
#include <isc/lang.h>
+#include <isc/refcount.h>
#include <isc/types.h>
#include <isc/list.h>
@@ -70,7 +71,7 @@ typedef struct cfg_obj cfg_obj_t;
typedef struct cfg_listelt cfg_listelt_t;
/*%
- * A callback function to be called when parsing an option
+ * A callback function to be called when parsing an option
* that needs to be interpreted at parsing time, like
* "directory".
*/
@@ -83,6 +84,12 @@ typedef isc_result_t
ISC_LANG_BEGINDECLS
+void
+cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest);
+/*%<
+ * Reference a parser object.
+ */
+
isc_result_t
cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret);
/*%<
@@ -123,7 +130,7 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer,
* (isc_parse_buffer()).
*
* Returns an error if the file does not parse correctly.
- *
+ *
* Requires:
*\li "filename" is valid.
*\li "mem" is valid.
@@ -140,13 +147,14 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer,
void
cfg_parser_destroy(cfg_parser_t **pctxp);
/*%<
- * Destroy a configuration parser.
+ * Remove a reference to a configuration parser; destroy it if there are no
+ * more references.
*/
isc_boolean_t
cfg_obj_isvoid(const cfg_obj_t *obj);
/*%<
- * Return true iff 'obj' is of void type (e.g., an optional
+ * Return true iff 'obj' is of void type (e.g., an optional
* value not specified).
*/
@@ -355,7 +363,7 @@ cfg_list_length(const cfg_obj_t *obj, isc_boolean_t recurse);
* all contained lists.
*/
-const cfg_obj_t *
+cfg_obj_t *
cfg_listelt_value(const cfg_listelt_t *elt);
/*%<
* Returns the configuration object associated with cfg_listelt_t.
@@ -389,17 +397,25 @@ cfg_print_grammar(const cfg_type_t *type,
isc_boolean_t
cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type);
/*%<
- * Return true iff 'obj' is of type 'type'.
+ * Return true iff 'obj' is of type 'type'.
*/
-void cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj);
+void
+cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest);
+/*%<
+ * Reference a configuration object.
+ */
+
+void
+cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj);
/*%<
- * Destroy a configuration object.
+ * Delete a reference to a configuration object; destroy the object if
+ * there are no more references.
*/
void
cfg_obj_log(const cfg_obj_t *obj, isc_log_t *lctx, int level,
- const char *fmt, ...)
+ const char *fmt, ...)
ISC_FORMAT_PRINTF(4, 5);
/*%<
* Log a message concerning configuration object 'obj' to the logging
diff --git a/lib/isccfg/include/isccfg/dnsconf.h b/lib/isccfg/include/isccfg/dnsconf.h
new file mode 100644
index 000000000000..bb713389462e
--- /dev/null
+++ b/lib/isccfg/include/isccfg/dnsconf.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: dnsconf.h,v 1.3 2009-09-02 23:48:03 tbox Exp $ */
+
+#ifndef ISCCFG_NAMEDCONF_H
+#define ISCCFG_NAMEDCONF_H 1
+
+/*! \file
+ * \brief
+ * This module defines the named.conf, rndc.conf, and rndc.key grammars.
+ */
+
+#include <isccfg/cfg.h>
+
+/*
+ * Configuration object types.
+ */
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_dnsconf;
+/*%< A complete dns.conf file. */
+
+#endif /* ISCCFG_CFG_H */
diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h
index b8b845bf6477..afc95bc37816 100644
--- a/lib/isccfg/include/isccfg/grammar.h
+++ b/lib/isccfg/include/isccfg/grammar.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: grammar.h,v 1.17 2008-09-25 04:02:39 tbox Exp $ */
+/* $Id: grammar.h,v 1.24 2011-01-04 23:47:14 tbox Exp $ */
#ifndef ISCCFG_GRAMMAR_H
#define ISCCFG_GRAMMAR_H 1
@@ -53,6 +53,8 @@
#define CFG_CLAUSEFLAG_CALLBACK 0x00000020
/*% A option that is only used in testing. */
#define CFG_CLAUSEFLAG_TESTONLY 0x00000040
+/*% A configuration option that was not configured at compile time. */
+#define CFG_CLAUSEFLAG_NOTCONFIGURED 0x00000080
typedef struct cfg_clausedef cfg_clausedef_t;
typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;
@@ -157,6 +159,7 @@ struct cfg_obj {
isc_sockaddr_t sockaddr;
cfg_netprefix_t netprefix;
} value;
+ isc_refcount_t references; /*%< reference counter */
const char * file;
unsigned int line;
};
@@ -210,10 +213,21 @@ struct cfg_parser {
*/
unsigned int line;
+ /*%
+ * Parser context flags, used for maintaining state
+ * from one token to the next.
+ */
+ unsigned int flags;
+
+ /*%< Reference counter */
+ isc_refcount_t references;
+
cfg_parsecallback_t callback;
void *callbackarg;
};
+/* Parser context flags */
+#define CFG_PCTX_SKIP 0x1
/*@{*/
/*%
@@ -314,10 +328,16 @@ cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);
isc_result_t
cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+isc_result_t
+cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+
void
cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj);
void
+cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+void
cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type);
isc_result_t
diff --git a/lib/isccfg/include/isccfg/log.h b/lib/isccfg/include/isccfg/log.h
index f45e4c24322b..2c9dc124c48e 100644
--- a/lib/isccfg/include/isccfg/log.h
+++ b/lib/isccfg/include/isccfg/log.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: log.h,v 1.12.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: log.h,v 1.14 2009-01-18 23:48:14 tbox Exp $ */
#ifndef ISCCFG_LOG_H
#define ISCCFG_LOG_H 1
diff --git a/lib/isccfg/include/isccfg/namedconf.h b/lib/isccfg/include/isccfg/namedconf.h
index 34aa3e88323d..9242cf3a8ebb 100644
--- a/lib/isccfg/include/isccfg/namedconf.h
+++ b/lib/isccfg/include/isccfg/namedconf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: namedconf.h,v 1.9.332.2 2009-06-25 23:47:28 tbox Exp $ */
+/* $Id: namedconf.h,v 1.18 2010-08-11 18:14:20 each Exp $ */
#ifndef ISCCFG_NAMEDCONF_H
#define ISCCFG_NAMEDCONF_H 1
@@ -33,12 +33,24 @@
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_namedconf;
/*%< A complete named.conf file. */
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_bindkeys;
+/*%< A bind.keys file. */
+
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_newzones;
+/*%< A new-zones file (for zones added by 'rndc addzone'). */
+
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_addzoneconf;
+/*%< A single zone passed via the addzone rndc command. */
+
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndcconf;
/*%< A complete rndc.conf file. */
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndckey;
/*%< A complete rndc.key file. */
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sessionkey;
+/*%< A complete session.key file. */
+
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref;
/*%< A key reference, used as an ACL element */
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index f291507a547d..f80d34ba810b 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: namedconf.c,v 1.92.44.2 2010-05-13 23:47:49 tbox Exp $ */
+/* $Id: namedconf.c,v 1.131.8.1 2011-02-03 05:50:08 marka Exp $ */
/*! \file */
@@ -24,6 +24,7 @@
#include <string.h>
#include <isc/lex.h>
+#include <isc/mem.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/util.h>
@@ -35,9 +36,9 @@
#define TOKEN_STRING(pctx) (pctx->token.value.as_textregion.base)
/*% Check a return value. */
-#define CHECK(op) \
- do { result = (op); \
- if (result != ISC_R_SUCCESS) goto cleanup; \
+#define CHECK(op) \
+ do { result = (op); \
+ if (result != ISC_R_SUCCESS) goto cleanup; \
} while (0)
/*% Clean up a configuration object if non-NULL. */
@@ -57,7 +58,17 @@ static isc_result_t
parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
static isc_result_t
-parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
+parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+static isc_result_t
+parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+static void
+print_updatepolicy(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
+static void
+doc_updatepolicy(cfg_printer_t *pctx, const cfg_type_t *type);
static void
print_keyvalue(cfg_printer_t *pctx, const cfg_obj_t *obj);
@@ -111,6 +122,7 @@ static cfg_type_t cfg_type_zone;
static cfg_type_t cfg_type_zoneopts;
static cfg_type_t cfg_type_dynamically_loadable_zones;
static cfg_type_t cfg_type_dynamically_loadable_zones_opts;
+static cfg_type_t cfg_type_v4_aaaa;
/*
* Clauses that can be found in a 'dynamically loadable zones' statement
@@ -241,30 +253,76 @@ static cfg_tuplefielddef_t pubkey_fields[] = {
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_pubkey = {
- "pubkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, pubkey_fields };
+ "pubkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, pubkey_fields };
/*%
* A list of RR types, used in grant statements.
* Note that the old parser allows quotes around the RR type names.
*/
static cfg_type_t cfg_type_rrtypelist = {
- "rrtypelist", cfg_parse_spacelist, cfg_print_spacelist, cfg_doc_terminal,
- &cfg_rep_list, &cfg_type_astring
+ "rrtypelist", cfg_parse_spacelist, cfg_print_spacelist,
+ cfg_doc_terminal, &cfg_rep_list, &cfg_type_astring
};
static const char *mode_enums[] = { "grant", "deny", NULL };
static cfg_type_t cfg_type_mode = {
- "mode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string,
- &mode_enums
+ "mode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
+ &cfg_rep_string, &mode_enums
};
+static isc_result_t
+parse_matchtype(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret) {
+ isc_result_t result;
+
+ CHECK(cfg_peektoken(pctx, 0));
+ if (pctx->token.type == isc_tokentype_string &&
+ strcasecmp(TOKEN_STRING(pctx), "zonesub") == 0) {
+ pctx->flags |= CFG_PCTX_SKIP;
+ }
+ return (cfg_parse_enum(pctx, type, ret));
+
+ cleanup:
+ return (result);
+}
+
+static isc_result_t
+parse_matchname(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+ isc_result_t result;
+ cfg_obj_t *obj = NULL;
+
+ if ((pctx->flags & CFG_PCTX_SKIP) != 0) {
+ pctx->flags &= ~CFG_PCTX_SKIP;
+ CHECK(cfg_parse_void(pctx, NULL, &obj));
+ } else
+ result = cfg_parse_astring(pctx, type, &obj);
+
+ *ret = obj;
+ cleanup:
+ return (result);
+}
+
+static void
+doc_matchname(cfg_printer_t *pctx, const cfg_type_t *type) {
+ cfg_print_chars(pctx, "[ ", 2);
+ cfg_doc_obj(pctx, type->of);
+ cfg_print_chars(pctx, " ]", 2);
+}
+
static const char *matchtype_enums[] = {
"name", "subdomain", "wildcard", "self", "selfsub", "selfwild",
"krb5-self", "ms-self", "krb5-subdomain", "ms-subdomain",
- "tcp-self", "6to4-self", NULL };
+ "tcp-self", "6to4-self", "zonesub", "external", NULL };
+
static cfg_type_t cfg_type_matchtype = {
- "matchtype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string,
- &matchtype_enums
+ "matchtype", parse_matchtype, cfg_print_ustring,
+ cfg_doc_enum, &cfg_rep_string, &matchtype_enums
+};
+
+static cfg_type_t cfg_type_matchname = {
+ "optional_matchname", parse_matchname, cfg_print_ustring,
+ &doc_matchname, &cfg_rep_tuple, &cfg_type_ustring
};
/*%
@@ -274,18 +332,70 @@ static cfg_tuplefielddef_t grant_fields[] = {
{ "mode", &cfg_type_mode, 0 },
{ "identity", &cfg_type_astring, 0 }, /* domain name */
{ "matchtype", &cfg_type_matchtype, 0 },
- { "name", &cfg_type_astring, 0 }, /* domain name */
+ { "name", &cfg_type_matchname, 0 }, /* domain name */
{ "types", &cfg_type_rrtypelist, 0 },
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_grant = {
- "grant", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, grant_fields };
+ "grant", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, grant_fields
+};
static cfg_type_t cfg_type_updatepolicy = {
- "update_policy", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list,
- &cfg_rep_list, &cfg_type_grant
+ "update_policy", parse_updatepolicy, print_updatepolicy,
+ doc_updatepolicy, &cfg_rep_list, &cfg_type_grant
};
+static isc_result_t
+parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret) {
+ isc_result_t result;
+ CHECK(cfg_gettoken(pctx, 0));
+ if (pctx->token.type == isc_tokentype_special &&
+ pctx->token.value.as_char == '{') {
+ cfg_ungettoken(pctx);
+ return (cfg_parse_bracketed_list(pctx, type, ret));
+ }
+
+ if (pctx->token.type == isc_tokentype_string &&
+ strcasecmp(TOKEN_STRING(pctx), "local") == 0) {
+ cfg_obj_t *obj = NULL;
+ CHECK(cfg_create_obj(pctx, &cfg_type_ustring, &obj));
+ obj->value.string.length = strlen("local");
+ obj->value.string.base = isc_mem_get(pctx->mctx,
+ obj->value.string.length + 1);
+ if (obj->value.string.base == NULL) {
+ isc_mem_put(pctx->mctx, obj, sizeof(*obj));
+ return (ISC_R_NOMEMORY);
+ }
+ memcpy(obj->value.string.base, "local", 5);
+ obj->value.string.base[5] = '\0';
+ *ret = obj;
+ return (ISC_R_SUCCESS);
+ }
+
+ cfg_ungettoken(pctx);
+ return (ISC_R_UNEXPECTEDTOKEN);
+
+ cleanup:
+ return (result);
+}
+
+static void
+print_updatepolicy(cfg_printer_t *pctx, const cfg_obj_t *obj) {
+ if (cfg_obj_isstring(obj))
+ cfg_print_ustring(pctx, obj);
+ else
+ cfg_print_bracketed_list(pctx, obj);
+}
+
+static void
+doc_updatepolicy(cfg_printer_t *pctx, const cfg_type_t *type) {
+ cfg_print_cstr(pctx, "( local | { ");
+ cfg_doc_obj(pctx, type->of);
+ cfg_print_cstr(pctx, "; ... }");
+}
+
/*%
* A view statement.
*/
@@ -296,7 +406,9 @@ static cfg_tuplefielddef_t view_fields[] = {
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_view = {
- "view", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, view_fields };
+ "view", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, view_fields
+};
/*%
* A zone statement.
@@ -308,7 +420,9 @@ static cfg_tuplefielddef_t zone_fields[] = {
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_zone = {
- "zone", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, zone_fields };
+ "zone", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, zone_fields
+};
/*%
* A "category" clause in the "logging" statement.
@@ -319,13 +433,15 @@ static cfg_tuplefielddef_t category_fields[] = {
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_category = {
- "category", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, category_fields };
+ "category", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, category_fields
+};
/*%
- * A trusted key, as used in the "trusted-keys" statement.
+ * A dnssec key, as used in the "trusted-keys" statement.
*/
-static cfg_tuplefielddef_t trustedkey_fields[] = {
+static cfg_tuplefielddef_t dnsseckey_fields[] = {
{ "name", &cfg_type_astring, 0 },
{ "flags", &cfg_type_uint32, 0 },
{ "protocol", &cfg_type_uint32, 0 },
@@ -333,9 +449,27 @@ static cfg_tuplefielddef_t trustedkey_fields[] = {
{ "key", &cfg_type_qstring, 0 },
{ NULL, NULL, 0 }
};
-static cfg_type_t cfg_type_trustedkey = {
- "trustedkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
- trustedkey_fields
+static cfg_type_t cfg_type_dnsseckey = {
+ "dnsseckey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, dnsseckey_fields
+};
+
+/*%
+ * A managed key initialization specifier, as used in the
+ * "managed-keys" statement.
+ */
+static cfg_tuplefielddef_t managedkey_fields[] = {
+ { "name", &cfg_type_astring, 0 },
+ { "init", &cfg_type_ustring, 0 }, /* must be literal "initial-key" */
+ { "flags", &cfg_type_uint32, 0 },
+ { "protocol", &cfg_type_uint32, 0 },
+ { "algorithm", &cfg_type_uint32, 0 },
+ { "key", &cfg_type_qstring, 0 },
+ { NULL, NULL, 0 }
+};
+static cfg_type_t cfg_type_managedkey = {
+ "managedkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, managedkey_fields
};
static keyword_type_t wild_class_kw = { "class", &cfg_type_ustring };
@@ -397,6 +531,7 @@ static cfg_tuplefielddef_t checknames_fields[] = {
{ "mode", &cfg_type_checkmode, 0 },
{ NULL, NULL, 0 }
};
+
static cfg_type_t cfg_type_checknames = {
"checknames", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
checknames_fields
@@ -407,6 +542,13 @@ static cfg_type_t cfg_type_bracketed_sockaddrlist = {
&cfg_rep_list, &cfg_type_sockaddr
};
+static const char *autodnssec_enums[] = { "allow", "maintain", "create",
+ "off", NULL };
+static cfg_type_t cfg_type_autodnssec = {
+ "autodnssec", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
+ &cfg_rep_string, &autodnssec_enums
+};
+
static cfg_type_t cfg_type_rrsetorder = {
"rrsetorder", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list,
&cfg_rep_list, &cfg_type_rrsetorderingelement
@@ -421,13 +563,27 @@ static cfg_type_t cfg_type_optional_port = {
/*% A list of keys, as in the "key" clause of the controls statement. */
static cfg_type_t cfg_type_keylist = {
- "keylist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list,
- &cfg_type_astring
+ "keylist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
+ cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring
+};
+
+/*% A list of dnssec keys, as in "trusted-keys" */
+static cfg_type_t cfg_type_dnsseckeys = {
+ "dnsseckeys", cfg_parse_bracketed_list, cfg_print_bracketed_list,
+ cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_dnsseckey
};
-static cfg_type_t cfg_type_trustedkeys = {
- "trusted-keys", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list,
- &cfg_type_trustedkey
+/*%
+ * A list of managed key entries, as in "trusted-keys". Currently
+ * (9.7.0) this has a format similar to dnssec keys, except the keyname
+ * is followed by the keyword "initial-key". In future releases, this
+ * keyword may take other values indicating different methods for the
+ * key to be initialized.
+ */
+
+static cfg_type_t cfg_type_managedkeys = {
+ "managedkeys", cfg_parse_bracketed_list, cfg_print_bracketed_list,
+ cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_managedkey
};
static const char *forwardtype_enums[] = { "first", "only", NULL };
@@ -437,7 +593,8 @@ static cfg_type_t cfg_type_forwardtype = {
};
static const char *zonetype_enums[] = {
- "master", "slave", "stub", "hint", "forward", "delegation-only", NULL };
+ "master", "slave", "stub", "static-stub", "hint", "forward",
+ "delegation-only", NULL };
static cfg_type_t cfg_type_zonetype = {
"zonetype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
&cfg_rep_string, &zonetype_enums
@@ -479,6 +636,7 @@ parse_qstringornone(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret)
{
isc_result_t result;
+
CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
if (pctx->token.type == isc_tokentype_string &&
strcasecmp(TOKEN_STRING(pctx), "none") == 0)
@@ -496,13 +654,65 @@ doc_qstringornone(cfg_printer_t *pctx, const cfg_type_t *type) {
}
static cfg_type_t cfg_type_qstringornone = {
- "qstringornone", parse_qstringornone, NULL, doc_qstringornone, NULL, NULL };
+ "qstringornone", parse_qstringornone, NULL, doc_qstringornone,
+ NULL, NULL
+};
/*%
- * keyword hostname
+ * A boolean ("yes" or "no"), or the special keyword "auto".
+ * Used in the dnssec-validation option.
*/
+static void
+print_auto(cfg_printer_t *pctx, const cfg_obj_t *obj) {
+ UNUSED(obj);
+ cfg_print_cstr(pctx, "auto");
+}
+
+static cfg_type_t cfg_type_auto = {
+ "auto", NULL, print_auto, NULL, &cfg_rep_void, NULL
+};
+
+static isc_result_t
+parse_boolorauto(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret)
+{
+ isc_result_t result;
+
+ CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
+ if (pctx->token.type == isc_tokentype_string &&
+ strcasecmp(TOKEN_STRING(pctx), "auto") == 0)
+ return (cfg_create_obj(pctx, &cfg_type_auto, ret));
+ cfg_ungettoken(pctx);
+ return (cfg_parse_boolean(pctx, type, ret));
+ cleanup:
+ return (result);
+}
static void
+print_boolorauto(cfg_printer_t *pctx, const cfg_obj_t *obj) {
+ if (obj->type->rep == &cfg_rep_void)
+ cfg_print_chars(pctx, "auto", 4);
+ else if (obj->value.boolean)
+ cfg_print_chars(pctx, "yes", 3);
+ else
+ cfg_print_chars(pctx, "no", 2);
+}
+
+static void
+doc_boolorauto(cfg_printer_t *pctx, const cfg_type_t *type) {
+ UNUSED(type);
+ cfg_print_cstr(pctx, "( yes | no | auto )");
+}
+
+static cfg_type_t cfg_type_boolorauto = {
+ "boolorauto", parse_boolorauto, print_boolorauto,
+ doc_boolorauto, NULL, NULL
+};
+
+/*%
+ * keyword hostname
+ */
+static void
print_hostname(cfg_printer_t *pctx, const cfg_obj_t *obj) {
UNUSED(obj);
cfg_print_cstr(pctx, "hostname");
@@ -652,7 +862,18 @@ namedconf_or_view_clauses[] = {
/* only 1 DLZ per view allowed */
{ "dlz", &cfg_type_dynamically_loadable_zones, 0 },
{ "server", &cfg_type_server, CFG_CLAUSEFLAG_MULTI },
- { "trusted-keys", &cfg_type_trustedkeys, CFG_CLAUSEFLAG_MULTI },
+ { "trusted-keys", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI },
+ { "managed-keys", &cfg_type_managedkeys, CFG_CLAUSEFLAG_MULTI },
+ { NULL, NULL, 0 }
+};
+
+/*%
+ * Clauses that can occur in the bind.keys file.
+ */
+static cfg_clausedef_t
+bindkeys_clauses[] = {
+ { "trusted-keys", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI },
+ { "managed-keys", &cfg_type_managedkeys, CFG_CLAUSEFLAG_MULTI },
{ NULL, NULL, 0 }
};
@@ -661,18 +882,21 @@ namedconf_or_view_clauses[] = {
*/
static cfg_clausedef_t
options_clauses[] = {
- { "use-v4-udp-ports", &cfg_type_bracketed_portlist, 0 },
- { "use-v6-udp-ports", &cfg_type_bracketed_portlist, 0 },
{ "avoid-v4-udp-ports", &cfg_type_bracketed_portlist, 0 },
{ "avoid-v6-udp-ports", &cfg_type_bracketed_portlist, 0 },
+ { "bindkeys-file", &cfg_type_qstring, 0 },
{ "blackhole", &cfg_type_bracketed_aml, 0 },
{ "coresize", &cfg_type_size, 0 },
{ "datasize", &cfg_type_size, 0 },
+ { "session-keyfile", &cfg_type_qstringornone, 0 },
+ { "session-keyname", &cfg_type_astring, 0 },
+ { "session-keyalg", &cfg_type_astring, 0 },
{ "deallocate-on-exit", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CALLBACK },
{ "dump-file", &cfg_type_qstring, 0 },
{ "fake-iquery", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "files", &cfg_type_size, 0 },
+ { "flush-zones-on-shutdown", &cfg_type_boolean, 0 },
{ "has-old-clients", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "heartbeat-interval", &cfg_type_uint32, 0 },
{ "host-statistics", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTIMP },
@@ -681,6 +905,7 @@ options_clauses[] = {
{ "interface-interval", &cfg_type_uint32, 0 },
{ "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
{ "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
+ { "managed-keys-directory", &cfg_type_qstring, 0 },
{ "match-mapped-addresses", &cfg_type_boolean, 0 },
{ "memstatistics-file", &cfg_type_qstring, 0 },
{ "memstatistics", &cfg_type_boolean, 0 },
@@ -693,6 +918,7 @@ options_clauses[] = {
{ "random-device", &cfg_type_qstring, 0 },
{ "recursive-clients", &cfg_type_uint32, 0 },
{ "reserved-sockets", &cfg_type_uint32, 0 },
+ { "secroots-file", &cfg_type_qstring, 0 },
{ "serial-queries", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE },
{ "serial-query-rate", &cfg_type_uint32, 0 },
{ "server-id", &cfg_type_serverid, 0 },
@@ -703,6 +929,7 @@ options_clauses[] = {
{ "tcp-listen-queue", &cfg_type_uint32, 0 },
{ "tkey-dhkey", &cfg_type_tkey_dhkey, 0 },
{ "tkey-gssapi-credential", &cfg_type_qstring, 0 },
+ { "tkey-gssapi-keytab", &cfg_type_qstring, 0 },
{ "tkey-domain", &cfg_type_qstring, 0 },
{ "transfers-per-ns", &cfg_type_uint32, 0 },
{ "transfers-in", &cfg_type_uint32, 0 },
@@ -710,12 +937,12 @@ options_clauses[] = {
{ "treat-cr-as-space", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "use-id-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "use-ixfr", &cfg_type_boolean, 0 },
+ { "use-v4-udp-ports", &cfg_type_bracketed_portlist, 0 },
+ { "use-v6-udp-ports", &cfg_type_bracketed_portlist, 0 },
{ "version", &cfg_type_qstringornone, 0 },
- { "flush-zones-on-shutdown", &cfg_type_boolean, 0 },
{ NULL, NULL, 0 }
};
-
static cfg_type_t cfg_type_namelist = {
"namelist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_qstring };
@@ -726,6 +953,34 @@ static cfg_type_t cfg_type_optional_exclude = {
"optional_exclude", parse_optional_keyvalue, print_keyvalue,
doc_optional_keyvalue, &cfg_rep_list, &exclude_kw };
+static keyword_type_t exceptionnames_kw = { "except-from", &cfg_type_namelist };
+
+static cfg_type_t cfg_type_optional_exceptionnames = {
+ "optional_allow", parse_optional_keyvalue, print_keyvalue,
+ doc_optional_keyvalue, &cfg_rep_list, &exceptionnames_kw };
+
+static cfg_tuplefielddef_t denyaddresses_fields[] = {
+ { "acl", &cfg_type_bracketed_aml, 0 },
+ { "except-from", &cfg_type_optional_exceptionnames, 0 },
+ { NULL, NULL, 0 }
+};
+
+static cfg_type_t cfg_type_denyaddresses = {
+ "denyaddresses", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, denyaddresses_fields
+};
+
+static cfg_tuplefielddef_t denyaliases_fields[] = {
+ { "name", &cfg_type_namelist, 0 },
+ { "except-from", &cfg_type_optional_exceptionnames, 0 },
+ { NULL, NULL, 0 }
+};
+
+static cfg_type_t cfg_type_denyaliases = {
+ "denyaliases", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, denyaliases_fields
+};
+
static cfg_type_t cfg_type_algorithmlist = {
"algorithmlist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring };
@@ -758,20 +1013,134 @@ static cfg_type_t cfg_type_masterformat = {
&cfg_rep_string, &masterformat_enums
};
+
+
+/*
+ * response-policy {
+ * zone <string> [ policy (given|no-op|nxdomain|nodata|cname <domain> ) ];
+ * };
+ *
+ * this is a chimera of doc_optional_keyvalue() and cfg_doc_enum()
+ */
+static void
+doc_rpz_policies(cfg_printer_t *pctx, const cfg_type_t *type) {
+ const keyword_type_t *kw;
+ const char * const *p;
+
+ kw = type->of;
+ cfg_print_chars(pctx, "[ ", 2);
+ cfg_print_cstr(pctx, kw->name);
+ cfg_print_chars(pctx, " ", 1);
+
+ cfg_print_chars(pctx, "( ", 2);
+ for (p = kw->type->of; *p != NULL; p++) {
+ cfg_print_cstr(pctx, *p);
+ if (p[1] != NULL)
+ cfg_print_chars(pctx, " | ", 3);
+ }
+}
+
+/*
+ * print_qstring() from parser.c
+ */
+static void
+print_rpz_cname(cfg_printer_t *pctx, const cfg_obj_t *obj)
+{
+ cfg_print_chars(pctx, "\"", 1);
+ cfg_print_ustring(pctx, obj);
+ cfg_print_chars(pctx, "\"", 1);
+}
+
+static void
+doc_rpz_cname(cfg_printer_t *pctx, const cfg_type_t *type) {
+ cfg_doc_terminal(pctx, type);
+ cfg_print_chars(pctx, " ) ]", 4);
+}
+
+static isc_result_t
+parse_rpz(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+ isc_result_t result;
+ cfg_obj_t *obj = NULL;
+ const cfg_tuplefielddef_t *fields = type->of;
+
+ CHECK(cfg_create_tuple(pctx, type, &obj));
+ CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
+ CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1]));
+ /*
+ * parse cname domain only after "policy cname"
+ */
+ if (cfg_obj_isvoid(obj->value.tuple[1]) ||
+ strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[1]))) {
+ CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2]));
+ } else {
+ CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2]));
+ }
+
+ *ret = obj;
+ return (ISC_R_SUCCESS);
+
+cleanup:
+ CLEANUP_OBJ(obj);
+ return (result);
+}
+
+static const char *rpz_policies[] = {
+ "given", "no-op", "nxdomain", "nodata", "cname", NULL
+};
+static cfg_type_t cfg_type_rpz_policylist = {
+ "policies", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
+ &cfg_rep_string, &rpz_policies
+};
+static keyword_type_t rpz_policies_kw = {
+ "policy", &cfg_type_rpz_policylist
+};
+static cfg_type_t cfg_type_rpz_policy = {
+ "optional_policy", parse_optional_keyvalue, print_keyvalue,
+ doc_rpz_policies, &cfg_rep_string, &rpz_policies_kw
+};
+static cfg_type_t cfg_type_cname = {
+ "domain", cfg_parse_astring, print_rpz_cname, doc_rpz_cname,
+ &cfg_rep_string, NULL
+};
+static cfg_tuplefielddef_t rpzone_fields[] = {
+ { "name", &cfg_type_astring, 0 },
+ { "policy", &cfg_type_rpz_policy, 0 },
+ { "cname", &cfg_type_cname, 0 },
+ { NULL, NULL, 0 }
+};
+static cfg_type_t cfg_type_rpzone = {
+ "rpzone", parse_rpz, cfg_print_tuple, cfg_doc_tuple,
+ &cfg_rep_tuple, rpzone_fields
+};
+static cfg_clausedef_t rpz_clauses[] = {
+ { "zone", &cfg_type_rpzone, CFG_CLAUSEFLAG_MULTI },
+ { NULL, NULL, 0 }
+};
+static cfg_clausedef_t *rpz_clausesets[] = {
+ rpz_clauses,
+ NULL
+};
+static cfg_type_t cfg_type_rpz = {
+ "rpz", cfg_parse_map, cfg_print_map, cfg_doc_map,
+ &cfg_rep_map, rpz_clausesets
+};
+
+
+
/*%
* dnssec-lookaside
*/
static keyword_type_t trustanchor_kw = { "trust-anchor", &cfg_type_astring };
-static cfg_type_t cfg_type_trustanchor = {
- "trust-anchor", parse_keyvalue, print_keyvalue, doc_keyvalue,
- &cfg_rep_string, &trustanchor_kw
+static cfg_type_t cfg_type_optional_trustanchor = {
+ "optional_trustanchor", parse_optional_keyvalue, print_keyvalue,
+ doc_keyvalue, &cfg_rep_string, &trustanchor_kw
};
static cfg_tuplefielddef_t lookaside_fields[] = {
{ "domain", &cfg_type_astring, 0 },
- { "trust-anchor", &cfg_type_trustanchor, 0 },
+ { "trust-anchor", &cfg_type_optional_trustanchor, 0 },
{ NULL, NULL, 0 }
};
@@ -780,6 +1149,31 @@ static cfg_type_t cfg_type_lookaside = {
&cfg_rep_tuple, lookaside_fields
};
+/*
+ * DNS64.
+ */
+static cfg_clausedef_t
+dns64_clauses[] = {
+ { "clients", &cfg_type_bracketed_aml, 0 },
+ { "mapped", &cfg_type_bracketed_aml, 0 },
+ { "exclude", &cfg_type_bracketed_aml, 0 },
+ { "suffix", &cfg_type_netaddr6, 0 },
+ { "recursive-only", &cfg_type_boolean, 0 },
+ { "break-dnssec", &cfg_type_boolean, 0 },
+ { NULL, NULL, 0 },
+};
+
+static cfg_clausedef_t *
+dns64_clausesets[] = {
+ dns64_clauses,
+ NULL
+};
+
+static cfg_type_t cfg_type_dns64 = {
+ "dns64", cfg_parse_netprefix_map, cfg_print_map, cfg_doc_map,
+ &cfg_rep_map, dns64_clausesets
+};
+
/*%
* Clauses that can be found within the 'view' statement,
* with defaults in the 'options' statement.
@@ -791,26 +1185,33 @@ view_clauses[] = {
{ "acache-enable", &cfg_type_boolean, 0 },
{ "additional-from-auth", &cfg_type_boolean, 0 },
{ "additional-from-cache", &cfg_type_boolean, 0 },
+ { "allow-new-zones", &cfg_type_boolean, 0 },
{ "allow-query-cache", &cfg_type_bracketed_aml, 0 },
{ "allow-query-cache-on", &cfg_type_bracketed_aml, 0 },
{ "allow-recursion", &cfg_type_bracketed_aml, 0 },
{ "allow-recursion-on", &cfg_type_bracketed_aml, 0 },
{ "allow-v6-synthesis", &cfg_type_bracketed_aml,
CFG_CLAUSEFLAG_OBSOLETE },
+ { "attach-cache", &cfg_type_astring, 0 },
{ "auth-nxdomain", &cfg_type_boolean, CFG_CLAUSEFLAG_NEWDEFAULT },
{ "cache-file", &cfg_type_qstring, 0 },
{ "check-names", &cfg_type_checknames, CFG_CLAUSEFLAG_MULTI },
{ "cleaning-interval", &cfg_type_uint32, 0 },
{ "clients-per-query", &cfg_type_uint32, 0 },
+ { "deny-answer-addresses", &cfg_type_denyaddresses, 0 },
+ { "deny-answer-aliases", &cfg_type_denyaliases, 0 },
{ "disable-algorithms", &cfg_type_disablealgorithm,
CFG_CLAUSEFLAG_MULTI },
{ "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI },
+ { "dns64", &cfg_type_dns64, CFG_CLAUSEFLAG_MULTI },
+ { "dns64-server", &cfg_type_astring, 0 },
+ { "dns64-contact", &cfg_type_astring, 0 },
{ "dnssec-accept-expired", &cfg_type_boolean, 0 },
{ "dnssec-enable", &cfg_type_boolean, 0 },
{ "dnssec-lookaside", &cfg_type_lookaside, CFG_CLAUSEFLAG_MULTI },
{ "dnssec-must-be-secure", &cfg_type_mustbesecure,
CFG_CLAUSEFLAG_MULTI },
- { "dnssec-validation", &cfg_type_boolean, 0 },
+ { "dnssec-validation", &cfg_type_boolorauto, 0 },
{ "dual-stack-servers", &cfg_type_nameportiplist, 0 },
{ "edns-udp-size", &cfg_type_uint32, 0 },
{ "empty-contact", &cfg_type_astring, 0 },
@@ -841,6 +1242,7 @@ view_clauses[] = {
{ "recursion", &cfg_type_boolean, 0 },
{ "request-ixfr", &cfg_type_boolean, 0 },
{ "request-nsid", &cfg_type_boolean, 0 },
+ { "resolver-query-timeout", &cfg_type_uint32, 0 },
{ "rfc2308-type1", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI },
{ "root-delegation-only", &cfg_type_optional_exclude, 0 },
{ "rrset-order", &cfg_type_rrsetorder, 0 },
@@ -850,6 +1252,16 @@ view_clauses[] = {
{ "transfer-format", &cfg_type_transferformat, 0 },
{ "use-queryport-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "zero-no-soa-ttl-cache", &cfg_type_boolean, 0 },
+#ifdef ALLOW_FILTER_AAAA_ON_V4
+ { "filter-aaaa", &cfg_type_bracketed_aml, 0 },
+ { "filter-aaaa-on-v4", &cfg_type_v4_aaaa, 0 },
+#else
+ { "filter-aaaa", &cfg_type_bracketed_aml,
+ CFG_CLAUSEFLAG_NOTCONFIGURED },
+ { "filter-aaaa-on-v4", &cfg_type_v4_aaaa,
+ CFG_CLAUSEFLAG_NOTCONFIGURED },
+#endif
+ { "response-policy", &cfg_type_rpz, 0 },
{ NULL, NULL, 0 }
};
@@ -920,6 +1332,7 @@ zone_clauses[] = {
{ "also-notify", &cfg_type_portiplist, 0 },
{ "alt-transfer-source", &cfg_type_sockaddr4wild, 0 },
{ "alt-transfer-source-v6", &cfg_type_sockaddr6wild, 0 },
+ { "check-dup-records", &cfg_type_checkmode, 0 },
{ "check-integrity", &cfg_type_boolean, 0 },
{ "check-mx", &cfg_type_checkmode, 0 },
{ "check-mx-cname", &cfg_type_checkmode, 0 },
@@ -927,6 +1340,8 @@ zone_clauses[] = {
{ "check-srv-cname", &cfg_type_checkmode, 0 },
{ "check-wildcard", &cfg_type_boolean, 0 },
{ "dialup", &cfg_type_dialuptype, 0 },
+ { "dnssec-dnskey-kskonly", &cfg_type_boolean, 0 },
+ { "dnssec-secure-to-insecure", &cfg_type_boolean, 0 },
{ "forward", &cfg_type_forwardtype, 0 },
{ "forwarders", &cfg_type_portiplist, 0 },
{ "key-directory", &cfg_type_qstring, 0 },
@@ -986,6 +1401,9 @@ zone_only_clauses[] = {
*/
{ "check-names", &cfg_type_checkmode, 0 },
{ "ixfr-from-differences", &cfg_type_boolean, 0 },
+ { "auto-dnssec", &cfg_type_autodnssec, 0 },
+ { "server-addresses", &cfg_type_bracketed_sockaddrlist, 0 },
+ { "server-names", &cfg_type_namelist, 0 },
{ NULL, NULL, 0 }
};
@@ -998,12 +1416,40 @@ namedconf_clausesets[] = {
namedconf_or_view_clauses,
NULL
};
-
LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_namedconf = {
"namedconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
&cfg_rep_map, namedconf_clausesets
};
+/*% The bind.keys syntax (trusted-keys/managed-keys only). */
+static cfg_clausedef_t *
+bindkeys_clausesets[] = {
+ bindkeys_clauses,
+ NULL
+};
+LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_bindkeys = {
+ "bindkeys", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
+ &cfg_rep_map, bindkeys_clausesets
+};
+
+/*% The new-zone-file syntax (for zones added by 'rndc addzone') */
+static cfg_clausedef_t
+newzones_clauses[] = {
+ { "zone", &cfg_type_zone, CFG_CLAUSEFLAG_MULTI },
+ { NULL, NULL, 0 }
+};
+
+static cfg_clausedef_t *
+newzones_clausesets[] = {
+ newzones_clauses,
+ NULL
+};
+
+LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_newzones = {
+ "newzones", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
+ &cfg_rep_map, newzones_clausesets
+};
+
/*% The "options" statement syntax. */
static cfg_clausedef_t *
@@ -1166,6 +1612,38 @@ static cfg_type_t cfg_type_logging = {
"logging", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, logging_clausesets };
+/*%
+ * For parsing an 'addzone' statement
+ */
+
+static cfg_tuplefielddef_t addzone_fields[] = {
+ { "name", &cfg_type_astring, 0 },
+ { "class", &cfg_type_optional_class, 0 },
+ { "view", &cfg_type_optional_class, 0 },
+ { "options", &cfg_type_zoneopts, 0 },
+ { NULL, NULL, 0 }
+};
+static cfg_type_t cfg_type_addzone = {
+ "addzone", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, addzone_fields };
+
+static cfg_clausedef_t
+addzoneconf_clauses[] = {
+ { "addzone", &cfg_type_addzone, 0 },
+ { NULL, NULL, 0 }
+};
+
+static cfg_clausedef_t *
+addzoneconf_clausesets[] = {
+ addzoneconf_clauses,
+ NULL
+};
+
+LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_addzoneconf = {
+ "addzoneconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
+ &cfg_rep_map, addzoneconf_clausesets
+};
+
+
static isc_result_t
parse_unitstring(char *str, isc_resourcevalue_t *valuep) {
char *endp;
@@ -1385,6 +1863,17 @@ static cfg_type_t cfg_type_ixfrdifftype = {
&cfg_rep_string, ixfrdiff_enums,
};
+static const char *v4_aaaa_enums[] = { "break-dnssec", NULL };
+static isc_result_t
+parse_v4_aaaa(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret) {
+ return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
+}
+static cfg_type_t cfg_type_v4_aaaa = {
+ "v4_aaaa", parse_v4_aaaa, cfg_print_ustring,
+ doc_enum_or_other, &cfg_rep_string, v4_aaaa_enums,
+};
+
static keyword_type_t key_kw = { "key", &cfg_type_astring };
LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_keyref = {
@@ -2082,6 +2571,15 @@ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndckey = {
&cfg_rep_map, rndckey_clausesets
};
+/*
+ * session.key has exactly the same syntax as rndc.key, but it's defined
+ * separately for clarity (and so we can extend it someday, if needed).
+ */
+LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_sessionkey = {
+ "sessionkey", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody,
+ &cfg_rep_map, rndckey_clausesets
+};
+
static cfg_tuplefielddef_t nameport_fields[] = {
{ "name", &cfg_type_astring, 0 },
{ "port", &cfg_type_optional_port, 0 },
diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c
index 2f64a092ed73..87ad391a860b 100644
--- a/lib/isccfg/parser.c
+++ b/lib/isccfg/parser.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: parser.c,v 1.129 2008-09-25 04:02:39 tbox Exp $ */
+/* $Id: parser.c,v 1.139 2011-01-04 23:47:14 tbox Exp $ */
/*! \file */
@@ -29,12 +29,12 @@
#include <isc/mem.h>
#include <isc/net.h>
#include <isc/netaddr.h>
+#include <isc/netscope.h>
#include <isc/print.h>
#include <isc/string.h>
#include <isc/sockaddr.h>
-#include <isc/netscope.h>
-#include <isc/util.h>
#include <isc/symtab.h>
+#include <isc/util.h>
#include <isccfg/cfg.h>
#include <isccfg/grammar.h>
@@ -387,6 +387,12 @@ cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) {
if (pctx == NULL)
return (ISC_R_NOMEMORY);
+ result = isc_refcount_init(&pctx->references, 1);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, pctx, sizeof(*pctx));
+ return (result);
+ }
+
pctx->mctx = mctx;
pctx->lctx = lctx;
pctx->lexer = NULL;
@@ -400,6 +406,7 @@ cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) {
pctx->callback = NULL;
pctx->callbackarg = NULL;
pctx->token.type = isc_tokentype_unknown;
+ pctx->flags = 0;
memset(specials, 0, sizeof(specials));
specials['{'] = 1;
@@ -526,17 +533,30 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer,
}
void
+cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest) {
+ REQUIRE(src != NULL);
+ REQUIRE(dest != NULL && *dest == NULL);
+ isc_refcount_increment(&src->references, NULL);
+ *dest = src;
+}
+
+void
cfg_parser_destroy(cfg_parser_t **pctxp) {
cfg_parser_t *pctx = *pctxp;
- isc_lex_destroy(&pctx->lexer);
- /*
- * Cleaning up open_files does not
- * close the files; that was already done
- * by closing the lexer.
- */
- CLEANUP_OBJ(pctx->open_files);
- CLEANUP_OBJ(pctx->closed_files);
- isc_mem_put(pctx->mctx, pctx, sizeof(*pctx));
+ unsigned int refs;
+
+ isc_refcount_decrement(&pctx->references, &refs);
+ if (refs == 0) {
+ isc_lex_destroy(&pctx->lexer);
+ /*
+ * Cleaning up open_files does not
+ * close the files; that was already done
+ * by closing the lexer.
+ */
+ CLEANUP_OBJ(pctx->open_files);
+ CLEANUP_OBJ(pctx->closed_files);
+ isc_mem_put(pctx->mctx, pctx, sizeof(*pctx));
+ }
*pctxp = NULL;
}
@@ -848,8 +868,8 @@ cfg_obj_asboolean(const cfg_obj_t *obj) {
return (obj->value.boolean);
}
-static isc_result_t
-parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret)
+isc_result_t
+cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret)
{
isc_result_t result;
isc_boolean_t value;
@@ -888,8 +908,8 @@ parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret)
return (result);
}
-static void
-print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj) {
+void
+cfg_print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj) {
if (obj->value.boolean)
cfg_print_chars(pctx, "yes", 3);
else
@@ -897,7 +917,7 @@ print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj) {
}
cfg_type_t cfg_type_boolean = {
- "boolean", parse_boolean, print_boolean, cfg_doc_terminal,
+ "boolean", cfg_parse_boolean, cfg_print_boolean, cfg_doc_terminal,
&cfg_rep_boolean, NULL
};
@@ -1132,7 +1152,7 @@ cfg_list_length(const cfg_obj_t *obj, isc_boolean_t recurse) {
return (count);
}
-const cfg_obj_t *
+cfg_obj_t *
cfg_listelt_value(const cfg_listelt_t *elt) {
REQUIRE(elt != NULL);
return (elt->obj);
@@ -1237,6 +1257,14 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret)
if ((clause->flags & CFG_CLAUSEFLAG_NYI) != 0)
cfg_parser_warning(pctx, 0, "option '%s' is "
"not implemented", clause->name);
+
+ if ((clause->flags & CFG_CLAUSEFLAG_NOTCONFIGURED) != 0) {
+ cfg_parser_warning(pctx, 0, "option '%s' is not "
+ "configured", clause->name);
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
/*
* Don't log options with CFG_CLAUSEFLAG_NEWDEFAULT
* set here - we need to log the *lack* of such an option,
@@ -1478,6 +1506,7 @@ static struct flagtext {
{ CFG_CLAUSEFLAG_OBSOLETE, "obsolete" },
{ CFG_CLAUSEFLAG_NEWDEFAULT, "default changed" },
{ CFG_CLAUSEFLAG_TESTONLY, "test only" },
+ { CFG_CLAUSEFLAG_NOTCONFIGURED, "not configured" },
{ 0, NULL }
};
@@ -2305,6 +2334,7 @@ cfg_obj_line(const cfg_obj_t *obj) {
isc_result_t
cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+ isc_result_t result;
cfg_obj_t *obj;
obj = isc_mem_get(pctx->mctx, sizeof(cfg_obj_t));
@@ -2313,10 +2343,16 @@ cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
obj->type = type;
obj->file = current_file(pctx);
obj->line = pctx->line;
+ result = isc_refcount_init(&obj->references, 1);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t));
+ return (result);
+ }
*ret = obj;
return (ISC_R_SUCCESS);
}
+
static void
map_symtabitem_destroy(char *key, unsigned int type,
isc_symvalue_t symval, void *userarg)
@@ -2370,11 +2406,25 @@ cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type) {
void
cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) {
cfg_obj_t *obj = *objp;
- obj->type->rep->free(pctx, obj);
- isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t));
+ unsigned int refs;
+
+ isc_refcount_decrement(&obj->references, &refs);
+ if (refs == 0) {
+ obj->type->rep->free(pctx, obj);
+ isc_refcount_destroy(&obj->references);
+ isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t));
+ }
*objp = NULL;
}
+void
+cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest) {
+ REQUIRE(src != NULL);
+ REQUIRE(dest != NULL && *dest == NULL);
+ isc_refcount_increment(&src->references, NULL);
+ *dest = src;
+}
+
static void
free_noop(cfg_parser_t *pctx, cfg_obj_t *obj) {
UNUSED(pctx);
diff --git a/lib/lwres/api b/lib/lwres/api
index fbbf923b5324..94575eb4ef20 100644
--- a/lib/lwres/api
+++ b/lib/lwres/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 50
-LIBREVISION = 3
+LIBINTERFACE = 80
+LIBREVISION = 0
LIBAGE = 0
diff --git a/lib/lwres/context.c b/lib/lwres/context.c
index 1310022f2329..e8f0eda14966 100644
--- a/lib/lwres/context.c
+++ b/lib/lwres/context.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: context.c,v 1.50.332.5 2009-09-01 23:47:05 tbox Exp $ */
+/* $Id: context.c,v 1.55 2009-09-02 23:48:03 tbox Exp $ */
/*! \file context.c
lwres_context_create() creates a #lwres_context_t structure for use in
diff --git a/lib/lwres/context_p.h b/lib/lwres/context_p.h
index 663b1da7a783..097695128d37 100644
--- a/lib/lwres/context_p.h
+++ b/lib/lwres/context_p.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: context_p.h,v 1.17.332.2 2008-12-30 23:46:49 tbox Exp $ */
+/* $Id: context_p.h,v 1.19 2008-12-17 23:47:58 tbox Exp $ */
#ifndef LWRES_CONTEXT_P_H
#define LWRES_CONTEXT_P_H 1
diff --git a/lib/lwres/getaddrinfo.c b/lib/lwres/getaddrinfo.c
index 665205a0ae66..81534fc8b884 100644
--- a/lib/lwres/getaddrinfo.c
+++ b/lib/lwres/getaddrinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* This code is derived from software contributed to ISC by
@@ -18,7 +18,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: getaddrinfo.c,v 1.52.254.2 2009-03-31 23:47:16 tbox Exp $ */
+/* $Id: getaddrinfo.c,v 1.54 2008-11-25 23:47:23 tbox Exp $ */
/*! \file */
diff --git a/lib/lwres/getipnode.c b/lib/lwres/getipnode.c
index b9eadee8b069..bc90c74e704d 100644
--- a/lib/lwres/getipnode.c
+++ b/lib/lwres/getipnode.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: getipnode.c,v 1.42.332.5 2009-09-01 23:47:05 tbox Exp $ */
+/* $Id: getipnode.c,v 1.47 2009-09-01 23:47:45 tbox Exp $ */
/*! \file */
diff --git a/lib/lwres/include/lwres/context.h b/lib/lwres/include/lwres/context.h
index 46be27a302f8..2421b5737327 100644
--- a/lib/lwres/include/lwres/context.h
+++ b/lib/lwres/include/lwres/context.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: context.h,v 1.21.332.2 2008-12-30 23:46:49 tbox Exp $ */
+/* $Id: context.h,v 1.23 2008-12-17 23:47:58 tbox Exp $ */
#ifndef LWRES_CONTEXT_H
#define LWRES_CONTEXT_H 1
diff --git a/lib/lwres/include/lwres/netdb.h.in b/lib/lwres/include/lwres/netdb.h.in
index 7531ca309b89..8eedd2770c1a 100644
--- a/lib/lwres/include/lwres/netdb.h.in
+++ b/lib/lwres/include/lwres/netdb.h.in
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: netdb.h.in,v 1.39.332.2 2009-01-18 23:47:41 tbox Exp $ */
+/* $Id: netdb.h.in,v 1.41 2009-01-18 23:48:14 tbox Exp $ */
/*! \file */
diff --git a/lib/lwres/lwconfig.c b/lib/lwres/lwconfig.c
index 356c106ed427..764ff2aaa997 100644
--- a/lib/lwres/lwconfig.c
+++ b/lib/lwres/lwconfig.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: lwconfig.c,v 1.46.332.2 2008-12-30 23:46:49 tbox Exp $ */
+/* $Id: lwconfig.c,v 1.48 2008-12-17 23:47:58 tbox Exp $ */
/*! \file */
diff --git a/lib/lwres/man/lwres.3 b/lib/lwres/man/lwres.3
index 77f96b648523..c2c0bb693a9d 100644
--- a/lib/lwres/man/lwres.3
+++ b/lib/lwres/man/lwres.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres.3,v 1.28.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres.3,v 1.29 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres.html b/lib/lwres/man/lwres.html
index 3844c0115827..6cfb75061902 100644
--- a/lib/lwres/man/lwres.html
+++ b/lib/lwres/man/lwres.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres.html,v 1.23.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres.html,v 1.24.484.1 2011-06-09 03:41:05 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres &#8212; introduction to the lightweight resolver library</p>
@@ -32,7 +32,7 @@
<div class="funcsynopsis"><pre class="funcsynopsisinfo">#include &lt;lwres/lwres.h&gt;</pre></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543348"></a><h2>DESCRIPTION</h2>
+<a name="id2543346"></a><h2>DESCRIPTION</h2>
<p>
The BIND 9 lightweight resolver library is a simple, name service
independent stub resolver library. It provides hostname-to-address
@@ -47,7 +47,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543361"></a><h2>OVERVIEW</h2>
+<a name="id2543358"></a><h2>OVERVIEW</h2>
<p>
The lwresd library implements multiple name service APIs.
The standard
@@ -101,7 +101,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543425"></a><h2>CLIENT-SIDE LOW-LEVEL API CALL FLOW</h2>
+<a name="id2543422"></a><h2>CLIENT-SIDE LOW-LEVEL API CALL FLOW</h2>
<p>
When a client program wishes to make an lwres request using the
native low-level API, it typically performs the following
@@ -149,7 +149,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543573"></a><h2>SERVER-SIDE LOW-LEVEL API CALL FLOW</h2>
+<a name="id2543571"></a><h2>SERVER-SIDE LOW-LEVEL API CALL FLOW</h2>
<p>
When implementing the server side of the lightweight resolver
protocol using the lwres library, a sequence of actions like the
@@ -191,7 +191,7 @@
<p></p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543656"></a><h2>SEE ALSO</h2>
+<a name="id2543654"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">lwres_gethostent</span>(3)</span>,
<span class="citerefentry"><span class="refentrytitle">lwres_getipnode</span>(3)</span>,
diff --git a/lib/lwres/man/lwres_buffer.3 b/lib/lwres/man/lwres_buffer.3
index 89b9b65f986d..0fc5225e1967 100644
--- a/lib/lwres/man/lwres_buffer.3
+++ b/lib/lwres/man/lwres_buffer.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_buffer.3,v 1.26.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_buffer.3,v 1.27 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_buffer.html b/lib/lwres/man/lwres_buffer.html
index 7f3934a29f5b..b7e034ff6f70 100644
--- a/lib/lwres/man/lwres_buffer.html
+++ b/lib/lwres/man/lwres_buffer.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_buffer.html,v 1.21.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_buffer.html,v 1.22.484.1 2011-06-09 03:41:05 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_buffer_init, lwres_buffer_invalidate, lwres_buffer_add, lwres_buffer_subtract, lwres_buffer_clear, lwres_buffer_first, lwres_buffer_forward, lwres_buffer_back, lwres_buffer_getuint8, lwres_buffer_putuint8, lwres_buffer_getuint16, lwres_buffer_putuint16, lwres_buffer_getuint32, lwres_buffer_putuint32, lwres_buffer_putmem, lwres_buffer_getmem &#8212; lightweight resolver buffer management</p>
@@ -262,7 +262,7 @@ void
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543892"></a><h2>DESCRIPTION</h2>
+<a name="id2543890"></a><h2>DESCRIPTION</h2>
<p>
These functions provide bounds checked access to a region of memory
where data is being read or written.
diff --git a/lib/lwres/man/lwres_config.3 b/lib/lwres/man/lwres_config.3
index 5b8a728244d8..0ea132075e08 100644
--- a/lib/lwres/man/lwres_config.3
+++ b/lib/lwres/man/lwres_config.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_config.3,v 1.26.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_config.3,v 1.27 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_config.html b/lib/lwres/man/lwres_config.html
index 2cee5efd7ef6..8c330a386589 100644
--- a/lib/lwres/man/lwres_config.html
+++ b/lib/lwres/man/lwres_config.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_config.html,v 1.22.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_config.html,v 1.23.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_conf_init, lwres_conf_clear, lwres_conf_parse, lwres_conf_print, lwres_conf_get &#8212; lightweight resolver configuration</p>
@@ -90,7 +90,7 @@ lwres_conf_t *
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543441"></a><h2>DESCRIPTION</h2>
+<a name="id2543438"></a><h2>DESCRIPTION</h2>
<p><code class="function">lwres_conf_init()</code>
creates an empty
<span class="type">lwres_conf_t</span>
@@ -123,7 +123,7 @@ lwres_conf_t *
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543508"></a><h2>RETURN VALUES</h2>
+<a name="id2543506"></a><h2>RETURN VALUES</h2>
<p><code class="function">lwres_conf_parse()</code>
returns <span class="errorcode">LWRES_R_SUCCESS</span>
if it successfully read and parsed
@@ -142,13 +142,13 @@ lwres_conf_t *
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543545"></a><h2>SEE ALSO</h2>
+<a name="id2543543"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">stdio</span>(3)</span>,
<span class="citerefentry"><span class="refentrytitle">resolver</span>(5)</span>.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543571"></a><h2>FILES</h2>
+<a name="id2543569"></a><h2>FILES</h2>
<p><code class="filename">/etc/resolv.conf</code>
</p>
</div>
diff --git a/lib/lwres/man/lwres_context.3 b/lib/lwres/man/lwres_context.3
index a96a0751927f..fdcaf553d754 100644
--- a/lib/lwres/man/lwres_context.3
+++ b/lib/lwres/man/lwres_context.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_context.3,v 1.28.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_context.3,v 1.29 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_context.html b/lib/lwres/man/lwres_context.html
index d525a4b216c7..50d5d9f8d01f 100644
--- a/lib/lwres/man/lwres_context.html
+++ b/lib/lwres/man/lwres_context.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_context.html,v 1.23.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_context.html,v 1.24.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_context_create, lwres_context_destroy, lwres_context_nextserial, lwres_context_initserial, lwres_context_freemem, lwres_context_allocmem, lwres_context_sendrecv &#8212; lightweight resolver context management</p>
@@ -172,7 +172,7 @@ void *
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543531"></a><h2>DESCRIPTION</h2>
+<a name="id2543529"></a><h2>DESCRIPTION</h2>
<p><code class="function">lwres_context_create()</code>
creates a <span class="type">lwres_context_t</span> structure for use in
lightweight resolver operations. It holds a socket and other
@@ -258,7 +258,7 @@ void *
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543719"></a><h2>RETURN VALUES</h2>
+<a name="id2543717"></a><h2>RETURN VALUES</h2>
<p><code class="function">lwres_context_create()</code>
returns <span class="errorcode">LWRES_R_NOMEMORY</span> if memory for
the <span class="type">struct lwres_context</span> could not be allocated,
@@ -283,7 +283,7 @@ void *
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543769"></a><h2>SEE ALSO</h2>
+<a name="id2543767"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">lwres_conf_init</span>(3)</span>,
<span class="citerefentry"><span class="refentrytitle">malloc</span>(3)</span>,
diff --git a/lib/lwres/man/lwres_gabn.3 b/lib/lwres/man/lwres_gabn.3
index 28ea7e1f9552..769c952d90ae 100644
--- a/lib/lwres/man/lwres_gabn.3
+++ b/lib/lwres/man/lwres_gabn.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_gabn.3,v 1.27.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_gabn.3,v 1.28 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_gabn.html b/lib/lwres/man/lwres_gabn.html
index b69f432ad1df..32b5f21bd466 100644
--- a/lib/lwres/man/lwres_gabn.html
+++ b/lib/lwres/man/lwres_gabn.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_gabn.html,v 1.24.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_gabn.html,v 1.25.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_gabnrequest_render, lwres_gabnresponse_render, lwres_gabnrequest_parse, lwres_gabnresponse_parse, lwres_gabnresponse_free, lwres_gabnrequest_free &#8212; lightweight resolver getaddrbyname message handling</p>
@@ -178,7 +178,7 @@ void
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543522"></a><h2>DESCRIPTION</h2>
+<a name="id2543520"></a><h2>DESCRIPTION</h2>
<p>
These are low-level routines for creating and parsing
lightweight resolver name-to-address lookup request and
@@ -278,7 +278,7 @@ typedef struct {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543667"></a><h2>RETURN VALUES</h2>
+<a name="id2543665"></a><h2>RETURN VALUES</h2>
<p>
The getaddrbyname opcode functions
<code class="function">lwres_gabnrequest_render()</code>,
@@ -316,7 +316,7 @@ typedef struct {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543733"></a><h2>SEE ALSO</h2>
+<a name="id2543731"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">lwres_packet</span>(3)</span>
</p>
</div>
diff --git a/lib/lwres/man/lwres_gai_strerror.3 b/lib/lwres/man/lwres_gai_strerror.3
index 3d807270b206..2527896d8fd0 100644
--- a/lib/lwres/man/lwres_gai_strerror.3
+++ b/lib/lwres/man/lwres_gai_strerror.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_gai_strerror.3,v 1.27.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_gai_strerror.3,v 1.28 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_gai_strerror.html b/lib/lwres/man/lwres_gai_strerror.html
index 616eebea3e01..9ff330b13753 100644
--- a/lib/lwres/man/lwres_gai_strerror.html
+++ b/lib/lwres/man/lwres_gai_strerror.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_gai_strerror.html,v 1.24.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_gai_strerror.html,v 1.25.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_gai_strerror &#8212; print suitable error string</p>
@@ -42,7 +42,7 @@ char *
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543361"></a><h2>DESCRIPTION</h2>
+<a name="id2543358"></a><h2>DESCRIPTION</h2>
<p><code class="function">lwres_gai_strerror()</code>
returns an error message corresponding to an error code returned by
<code class="function">getaddrinfo()</code>.
@@ -110,7 +110,7 @@ char *
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543576"></a><h2>SEE ALSO</h2>
+<a name="id2543574"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">strerror</span>(3)</span>,
<span class="citerefentry"><span class="refentrytitle">lwres_getaddrinfo</span>(3)</span>,
diff --git a/lib/lwres/man/lwres_getaddrinfo.3 b/lib/lwres/man/lwres_getaddrinfo.3
index 2953f3bedad8..cfc4aec36f80 100644
--- a/lib/lwres/man/lwres_getaddrinfo.3
+++ b/lib/lwres/man/lwres_getaddrinfo.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_getaddrinfo.3,v 1.31.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_getaddrinfo.3,v 1.32 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_getaddrinfo.html b/lib/lwres/man/lwres_getaddrinfo.html
index 013e8782034b..d367f51d2ed5 100644
--- a/lib/lwres/man/lwres_getaddrinfo.html
+++ b/lib/lwres/man/lwres_getaddrinfo.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_getaddrinfo.html,v 1.27.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_getaddrinfo.html,v 1.28.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_getaddrinfo, lwres_freeaddrinfo &#8212; socket address structure to host and service name</p>
@@ -89,7 +89,7 @@ struct addrinfo {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543412"></a><h2>DESCRIPTION</h2>
+<a name="id2543410"></a><h2>DESCRIPTION</h2>
<p><code class="function">lwres_getaddrinfo()</code>
is used to get a list of IP addresses and port numbers for host
<em class="parameter"><code>hostname</code></em> and service
@@ -283,7 +283,7 @@ struct addrinfo {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543789"></a><h2>RETURN VALUES</h2>
+<a name="id2543787"></a><h2>RETURN VALUES</h2>
<p><code class="function">lwres_getaddrinfo()</code>
returns zero on success or one of the error codes listed in
<span class="citerefentry"><span class="refentrytitle">gai_strerror</span>(3)</span>
@@ -294,7 +294,7 @@ struct addrinfo {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543827"></a><h2>SEE ALSO</h2>
+<a name="id2542118"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">lwres</span>(3)</span>,
<span class="citerefentry"><span class="refentrytitle">lwres_getaddrinfo</span>(3)</span>,
diff --git a/lib/lwres/man/lwres_gethostent.3 b/lib/lwres/man/lwres_gethostent.3
index 35ea1c2f6c5b..7acc5060b82e 100644
--- a/lib/lwres/man/lwres_gethostent.3
+++ b/lib/lwres/man/lwres_gethostent.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_gethostent.3,v 1.29.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_gethostent.3,v 1.30 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_gethostent.html b/lib/lwres/man/lwres_gethostent.html
index fd27dcf15cdc..fdaa062fc903 100644
--- a/lib/lwres/man/lwres_gethostent.html
+++ b/lib/lwres/man/lwres_gethostent.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_gethostent.html,v 1.24.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_gethostent.html,v 1.25.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_gethostbyname, lwres_gethostbyname2, lwres_gethostbyaddr, lwres_gethostent, lwres_sethostent, lwres_endhostent, lwres_gethostbyname_r, lwres_gethostbyaddr_r, lwres_gethostent_r, lwres_sethostent_r, lwres_endhostent_r &#8212; lightweight resolver get network host entry</p>
@@ -228,7 +228,7 @@ void
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543608"></a><h2>DESCRIPTION</h2>
+<a name="id2543606"></a><h2>DESCRIPTION</h2>
<p>
These functions provide hostname-to-address and
address-to-hostname lookups by means of the lightweight resolver.
@@ -366,7 +366,7 @@ struct hostent {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543959"></a><h2>RETURN VALUES</h2>
+<a name="id2543957"></a><h2>RETURN VALUES</h2>
<p>
The functions
<code class="function">lwres_gethostbyname()</code>,
@@ -430,7 +430,7 @@ struct hostent {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544193"></a><h2>SEE ALSO</h2>
+<a name="id2544190"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">gethostent</span>(3)</span>,
<span class="citerefentry"><span class="refentrytitle">lwres_getipnode</span>(3)</span>,
@@ -439,7 +439,7 @@ struct hostent {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544227"></a><h2>BUGS</h2>
+<a name="id2544225"></a><h2>BUGS</h2>
<p><code class="function">lwres_gethostbyname()</code>,
<code class="function">lwres_gethostbyname2()</code>,
<code class="function">lwres_gethostbyaddr()</code>
diff --git a/lib/lwres/man/lwres_getipnode.3 b/lib/lwres/man/lwres_getipnode.3
index b46e78f4da67..40ba59c59259 100644
--- a/lib/lwres/man/lwres_getipnode.3
+++ b/lib/lwres/man/lwres_getipnode.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_getipnode.3,v 1.28.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_getipnode.3,v 1.29 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_getipnode.html b/lib/lwres/man/lwres_getipnode.html
index 20c6d30016e2..9f54cb6f5506 100644
--- a/lib/lwres/man/lwres_getipnode.html
+++ b/lib/lwres/man/lwres_getipnode.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_getipnode.html,v 1.25.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_getipnode.html,v 1.26.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_getipnodebyname, lwres_getipnodebyaddr, lwres_freehostent &#8212; lightweight resolver nodename / address translation API</p>
@@ -98,7 +98,7 @@ void
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543431"></a><h2>DESCRIPTION</h2>
+<a name="id2543429"></a><h2>DESCRIPTION</h2>
<p>
These functions perform thread safe, protocol independent
nodename-to-address and address-to-nodename
@@ -217,7 +217,7 @@ struct hostent {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543689"></a><h2>RETURN VALUES</h2>
+<a name="id2543687"></a><h2>RETURN VALUES</h2>
<p>
If an error occurs,
<code class="function">lwres_getipnodebyname()</code>
@@ -261,7 +261,7 @@ struct hostent {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543786"></a><h2>SEE ALSO</h2>
+<a name="id2543784"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">RFC2553</span></span>,
<span class="citerefentry"><span class="refentrytitle">lwres</span>(3)</span>,
diff --git a/lib/lwres/man/lwres_getnameinfo.3 b/lib/lwres/man/lwres_getnameinfo.3
index 3a75efb50c44..5674fb2ba735 100644
--- a/lib/lwres/man/lwres_getnameinfo.3
+++ b/lib/lwres/man/lwres_getnameinfo.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_getnameinfo.3,v 1.29.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_getnameinfo.3,v 1.30 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_getnameinfo.html b/lib/lwres/man/lwres_getnameinfo.html
index fb7837ff232b..104854331595 100644
--- a/lib/lwres/man/lwres_getnameinfo.html
+++ b/lib/lwres/man/lwres_getnameinfo.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_getnameinfo.html,v 1.23.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_getnameinfo.html,v 1.24.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_getnameinfo &#8212; lightweight resolver socket address structure to hostname and
@@ -82,7 +82,7 @@ int
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543393"></a><h2>DESCRIPTION</h2>
+<a name="id2543390"></a><h2>DESCRIPTION</h2>
<p>
This function is equivalent to the
<span class="citerefentry"><span class="refentrytitle">getnameinfo</span>(3)</span> function defined in RFC2133.
@@ -149,13 +149,13 @@ int
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543534"></a><h2>RETURN VALUES</h2>
+<a name="id2543532"></a><h2>RETURN VALUES</h2>
<p><code class="function">lwres_getnameinfo()</code>
returns 0 on success or a non-zero error code if an error occurs.
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543546"></a><h2>SEE ALSO</h2>
+<a name="id2543544"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">RFC2133</span></span>,
<span class="citerefentry"><span class="refentrytitle">getservbyport</span>(3)</span>,
<span class="citerefentry"><span class="refentrytitle">lwres</span>(3)</span>,
@@ -165,7 +165,7 @@ int
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543604"></a><h2>BUGS</h2>
+<a name="id2543602"></a><h2>BUGS</h2>
<p>
RFC2133 fails to define what the nonzero return values of
<span class="citerefentry"><span class="refentrytitle">getnameinfo</span>(3)</span>
diff --git a/lib/lwres/man/lwres_getrrsetbyname.3 b/lib/lwres/man/lwres_getrrsetbyname.3
index c804e1142a65..2aa1a9c5c8dd 100644
--- a/lib/lwres/man/lwres_getrrsetbyname.3
+++ b/lib/lwres/man/lwres_getrrsetbyname.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_getrrsetbyname.3,v 1.25.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_getrrsetbyname.3,v 1.26 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_getrrsetbyname.html b/lib/lwres/man/lwres_getrrsetbyname.html
index 9d9dc04fb30a..3a7fb9ffc317 100644
--- a/lib/lwres/man/lwres_getrrsetbyname.html
+++ b/lib/lwres/man/lwres_getrrsetbyname.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_getrrsetbyname.html,v 1.23.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_getrrsetbyname.html,v 1.24.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_getrrsetbyname, lwres_freerrset &#8212; retrieve DNS records</p>
@@ -102,7 +102,7 @@ struct rrsetinfo {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543414"></a><h2>DESCRIPTION</h2>
+<a name="id2543412"></a><h2>DESCRIPTION</h2>
<p><code class="function">lwres_getrrsetbyname()</code>
gets a set of resource records associated with a
<em class="parameter"><code>hostname</code></em>, <em class="parameter"><code>class</code></em>,
@@ -150,7 +150,7 @@ struct rrsetinfo {
<p></p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543526"></a><h2>RETURN VALUES</h2>
+<a name="id2543524"></a><h2>RETURN VALUES</h2>
<p><code class="function">lwres_getrrsetbyname()</code>
returns zero on success, and one of the following error codes if
an error occurred:
@@ -184,7 +184,7 @@ struct rrsetinfo {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543626"></a><h2>SEE ALSO</h2>
+<a name="id2543624"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">lwres</span>(3)</span>.
</p>
</div>
diff --git a/lib/lwres/man/lwres_gnba.3 b/lib/lwres/man/lwres_gnba.3
index b34fc05cb55f..ad9d6274385c 100644
--- a/lib/lwres/man/lwres_gnba.3
+++ b/lib/lwres/man/lwres_gnba.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_gnba.3,v 1.27.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_gnba.3,v 1.28 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_gnba.html b/lib/lwres/man/lwres_gnba.html
index 158f4d01a068..8c7691ec7160 100644
--- a/lib/lwres/man/lwres_gnba.html
+++ b/lib/lwres/man/lwres_gnba.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_gnba.html,v 1.24.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_gnba.html,v 1.25.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_gnbarequest_render, lwres_gnbaresponse_render, lwres_gnbarequest_parse, lwres_gnbaresponse_parse, lwres_gnbaresponse_free, lwres_gnbarequest_free &#8212; lightweight resolver getnamebyaddress message handling</p>
@@ -183,7 +183,7 @@ void
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543525"></a><h2>DESCRIPTION</h2>
+<a name="id2543523"></a><h2>DESCRIPTION</h2>
<p>
These are low-level routines for creating and parsing
lightweight resolver address-to-name lookup request and
@@ -270,7 +270,7 @@ typedef struct {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543665"></a><h2>RETURN VALUES</h2>
+<a name="id2543662"></a><h2>RETURN VALUES</h2>
<p>
The getnamebyaddr opcode functions
<code class="function">lwres_gnbarequest_render()</code>,
@@ -308,7 +308,7 @@ typedef struct {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543731"></a><h2>SEE ALSO</h2>
+<a name="id2543729"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">lwres_packet</span>(3)</span>.
</p>
</div>
diff --git a/lib/lwres/man/lwres_hstrerror.3 b/lib/lwres/man/lwres_hstrerror.3
index f65ba5403148..b9d5316e0e4a 100644
--- a/lib/lwres/man/lwres_hstrerror.3
+++ b/lib/lwres/man/lwres_hstrerror.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_hstrerror.3,v 1.27.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_hstrerror.3,v 1.28 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_hstrerror.html b/lib/lwres/man/lwres_hstrerror.html
index d5d25ecd0867..df1c425747f3 100644
--- a/lib/lwres/man/lwres_hstrerror.html
+++ b/lib/lwres/man/lwres_hstrerror.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_hstrerror.html,v 1.23.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_hstrerror.html,v 1.24.484.1 2011-06-09 03:41:07 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_herror, lwres_hstrerror &#8212; lightweight resolver error message generation</p>
@@ -50,7 +50,7 @@ const char *
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543379"></a><h2>DESCRIPTION</h2>
+<a name="id2543377"></a><h2>DESCRIPTION</h2>
<p><code class="function">lwres_herror()</code>
prints the string <em class="parameter"><code>s</code></em> on
<span class="type">stderr</span> followed by the string generated by
@@ -84,7 +84,7 @@ const char *
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543497"></a><h2>RETURN VALUES</h2>
+<a name="id2543495"></a><h2>RETURN VALUES</h2>
<p>
The string <span class="errorname">Unknown resolver error</span> is returned by
<code class="function">lwres_hstrerror()</code>
@@ -94,7 +94,7 @@ const char *
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543517"></a><h2>SEE ALSO</h2>
+<a name="id2543515"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">herror</span>(3)</span>,
<span class="citerefentry"><span class="refentrytitle">lwres_hstrerror</span>(3)</span>.
diff --git a/lib/lwres/man/lwres_inetntop.3 b/lib/lwres/man/lwres_inetntop.3
index 6bd063ae7662..be85906f2dde 100644
--- a/lib/lwres/man/lwres_inetntop.3
+++ b/lib/lwres/man/lwres_inetntop.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_inetntop.3,v 1.26.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_inetntop.3,v 1.27 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_inetntop.html b/lib/lwres/man/lwres_inetntop.html
index 8467e4bdb0c4..f0ea41acc621 100644
--- a/lib/lwres/man/lwres_inetntop.html
+++ b/lib/lwres/man/lwres_inetntop.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_inetntop.html,v 1.23.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_inetntop.html,v 1.24.484.1 2011-06-09 03:41:06 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_net_ntop &#8212; lightweight resolver IP address presentation</p>
@@ -62,7 +62,7 @@ const char *
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543379"></a><h2>DESCRIPTION</h2>
+<a name="id2543377"></a><h2>DESCRIPTION</h2>
<p><code class="function">lwres_net_ntop()</code>
converts an IP address of protocol family
<em class="parameter"><code>af</code></em> &#8212; IPv4 or IPv6 &#8212; at
@@ -80,7 +80,7 @@ const char *
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543411"></a><h2>RETURN VALUES</h2>
+<a name="id2543409"></a><h2>RETURN VALUES</h2>
<p>
If successful, the function returns <em class="parameter"><code>dst</code></em>:
a pointer to a string containing the presentation format of the
@@ -93,7 +93,7 @@ const char *
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543444"></a><h2>SEE ALSO</h2>
+<a name="id2543442"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">RFC1884</span></span>,
<span class="citerefentry"><span class="refentrytitle">inet_ntop</span>(3)</span>,
<span class="citerefentry"><span class="refentrytitle">errno</span>(3)</span>.
diff --git a/lib/lwres/man/lwres_noop.3 b/lib/lwres/man/lwres_noop.3
index fd05e7e5c377..3be40b27a68e 100644
--- a/lib/lwres/man/lwres_noop.3
+++ b/lib/lwres/man/lwres_noop.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_noop.3,v 1.28.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_noop.3,v 1.29 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_noop.html b/lib/lwres/man/lwres_noop.html
index 4a94836afe5c..8f9d402d8f88 100644
--- a/lib/lwres/man/lwres_noop.html
+++ b/lib/lwres/man/lwres_noop.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_noop.html,v 1.25.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_noop.html,v 1.26.484.1 2011-06-09 03:41:07 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_nooprequest_render, lwres_noopresponse_render, lwres_nooprequest_parse, lwres_noopresponse_parse, lwres_noopresponse_free, lwres_nooprequest_free &#8212; lightweight resolver no-op message handling</p>
@@ -179,7 +179,7 @@ void
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543522"></a><h2>DESCRIPTION</h2>
+<a name="id2543520"></a><h2>DESCRIPTION</h2>
<p>
These are low-level routines for creating and parsing
lightweight resolver no-op request and response messages.
@@ -270,7 +270,7 @@ typedef struct {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543672"></a><h2>RETURN VALUES</h2>
+<a name="id2543670"></a><h2>RETURN VALUES</h2>
<p>
The no-op opcode functions
<code class="function">lwres_nooprequest_render()</code>,
@@ -309,7 +309,7 @@ typedef struct {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543738"></a><h2>SEE ALSO</h2>
+<a name="id2543736"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">lwres_packet</span>(3)</span>
</p>
</div>
diff --git a/lib/lwres/man/lwres_packet.3 b/lib/lwres/man/lwres_packet.3
index 5c096b558d6a..ad4a82cedcc8 100644
--- a/lib/lwres/man/lwres_packet.3
+++ b/lib/lwres/man/lwres_packet.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_packet.3,v 1.29.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_packet.3,v 1.30 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_packet.html b/lib/lwres/man/lwres_packet.html
index 096b4bbb8611..84eafc13169e 100644
--- a/lib/lwres/man/lwres_packet.html
+++ b/lib/lwres/man/lwres_packet.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_packet.html,v 1.26.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_packet.html,v 1.27.484.1 2011-06-09 03:41:07 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_lwpacket_renderheader, lwres_lwpacket_parseheader &#8212; lightweight resolver packet handling functions</p>
@@ -66,7 +66,7 @@ lwres_result_t
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543389"></a><h2>DESCRIPTION</h2>
+<a name="id2543387"></a><h2>DESCRIPTION</h2>
<p>
These functions rely on a
<span class="type">struct lwres_lwpacket</span>
@@ -219,7 +219,7 @@ struct lwres_lwpacket {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543706"></a><h2>RETURN VALUES</h2>
+<a name="id2543704"></a><h2>RETURN VALUES</h2>
<p>
Successful calls to
<code class="function">lwres_lwpacket_renderheader()</code> and
diff --git a/lib/lwres/man/lwres_resutil.3 b/lib/lwres/man/lwres_resutil.3
index 6e1779746b2c..04cad4e7f8d6 100644
--- a/lib/lwres/man/lwres_resutil.3
+++ b/lib/lwres/man/lwres_resutil.3
@@ -13,7 +13,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $Id: lwres_resutil.3,v 1.28.418.1 2009-07-11 01:55:21 tbox Exp $
+.\" $Id: lwres_resutil.3,v 1.29 2009-07-11 01:12:46 tbox Exp $
.\"
.hy 0
.ad l
diff --git a/lib/lwres/man/lwres_resutil.html b/lib/lwres/man/lwres_resutil.html
index 1d2aa7602fe9..b4de764af6eb 100644
--- a/lib/lwres/man/lwres_resutil.html
+++ b/lib/lwres/man/lwres_resutil.html
@@ -14,7 +14,7 @@
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: lwres_resutil.html,v 1.25.418.1 2009-07-11 01:55:21 tbox Exp $ -->
+<!-- $Id: lwres_resutil.html,v 1.26.484.1 2011-06-09 03:41:07 tbox Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -22,7 +22,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476267"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p>lwres_string_parse, lwres_addr_parse, lwres_getaddrsbyname, lwres_getnamebyaddr &#8212; lightweight resolver utility functions</p>
@@ -134,7 +134,7 @@ lwres_result_t
</div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543466"></a><h2>DESCRIPTION</h2>
+<a name="id2543464"></a><h2>DESCRIPTION</h2>
<p><code class="function">lwres_string_parse()</code>
retrieves a DNS-encoded string starting the current pointer of
lightweight resolver buffer <em class="parameter"><code>b</code></em>: i.e.
@@ -210,7 +210,7 @@ typedef struct {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543605"></a><h2>RETURN VALUES</h2>
+<a name="id2543603"></a><h2>RETURN VALUES</h2>
<p>
Successful calls to
<code class="function">lwres_string_parse()</code>
@@ -248,7 +248,7 @@ typedef struct {
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543676"></a><h2>SEE ALSO</h2>
+<a name="id2543674"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">lwres_buffer</span>(3)</span>,
<span class="citerefentry"><span class="refentrytitle">lwres_gabn</span>(3)</span>.
diff --git a/lib/lwres/print_p.h b/lib/lwres/print_p.h
index e2f6ad60004a..ed71535c93f8 100644
--- a/lib/lwres/print_p.h
+++ b/lib/lwres/print_p.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: print_p.h,v 1.4.332.2 2010-08-16 23:45:48 tbox Exp $ */
+/* $Id: print_p.h,v 1.6 2010-08-16 23:46:52 tbox Exp $ */
#ifndef LWRES_PRINT_P_H
#define LWRES_PRINT_P_H 1
diff --git a/make/rules.in b/make/rules.in
index d8484808b498..12c9d5f50ca5 100644
--- a/make/rules.in
+++ b/make/rules.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: rules.in,v 1.64.130.2 2009-01-10 23:46:57 tbox Exp $
+# $Id: rules.in,v 1.68 2009-09-01 18:40:25 jinmei Exp $
###
### Common Makefile rules for BIND 9.
@@ -35,6 +35,8 @@ sysconfdir = @sysconfdir@
localstatedir = @localstatedir@
mandir = @mandir@
datarootdir = @datarootdir@
+export_libdir = @export_libdir@
+export_includedir = @export_includedir@
DESTDIR =
@@ -122,7 +124,7 @@ ALL_CPPFLAGS = \
ALL_CFLAGS = ${EXT_CFLAGS} ${ALL_CPPFLAGS} ${CFLAGS} \
${ALWAYS_WARNINGS} ${STD_CWARNINGS} ${CWARNINGS}
-.c.@O@:
+@BIND9_CO_RULE@
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -c $<
SHELL = @SHELL@
@@ -134,12 +136,83 @@ PURIFY = @PURIFY@
MKDEP = ${SHELL} ${top_builddir}/make/mkdep
+###
+### This is a template compound command to build an executable binary with
+### an internal symbol table.
+### This process is tricky. We first link all objects including a tentative
+### empty symbol table, then get a tentative list of symbols from the resulting
+### binary ($@tmp0). Next, we re-link all objects, but this time with the
+### symbol table just created ($tmp@1). The set of symbols should be the same,
+### but the corresponding addresses would be changed due to the difference on
+### the size of symbol tables. So we create the symbol table and re-create the
+### objects once again. Finally, we check the symbol table embedded in the
+### final binaryis consistent with the binary itself; otherwise the process is
+### terminated.
+###
+### To minimize the overhead of creating symbol tables, the autoconf switch
+### --enable-symtable takes an argument so that the symbol table can be created
+### on a per application basis: unless the argument is set to "all", the symbol
+### table is created only when a shell (environment) variable "MAKE_SYMTABLE" is
+### set to a non-null value in the rule to build the executable binary.
+###
+### Each Makefile.in that uses this macro is expected to define "LIBS" and
+### "NOSYMLIBS"; the former includes libisc with an empty symbol table, and
+### the latter includes libisc without the definition of a symbol table.
+### The rule to make the executable binary will look like this
+### binary@EXEEXT@: ${OBJS}
+### #export MAKE_SYMTABLE="yes"; \ <- enable if symtable is always needed
+### export BASEOBJS="${OBJS}"; \
+### ${FINALBUILDCMD}
+###
+### Normally, ${LIBS} includes all necessary libraries to build the binary;
+### there are some exceptions however, where the rule lists some of the
+### necessary libraries explicitly in addition to (or instead of) ${LIBS},
+### like this:
+### binary@EXEEXT@: ${OBJS}
+### cc -o $@ ${OBJS} ${OTHERLIB1} ${OTHERLIB2} ${lIBS}
+### in order to modify such a rule to use this compound command, a separate
+### variable "LIBS0" should be deinfed for the explicitly listed libraries,
+### while making sure ${LIBS} still includes libisc. So the above rule would
+### be modified as follows:
+### binary@EXEEXT@: ${OBJS}
+### export BASEOBJS="${OBJS}"; \
+### export LIBS0="${OTHERLIB1} ${OTHERLIB2}"; \
+### ${FINALBUILDCMD}
+### See bin/check/Makefile.in for a complete example of the use of LIBS0.
+###
+FINALBUILDCMD = if [ X"${MKSYMTBL_PROGRAM}" = X -o X"$${MAKE_SYMTABLE:-${ALWAYS_MAKE_SYMTABLE}}" = X ] ; then \
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} \
+ -o $@ $${BASEOBJS} $${LIBS0} ${LIBS}; \
+ else \
+ rm -f $@tmp0; \
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} \
+ -o $@tmp0 $${BASEOBJS} $${LIBS0} ${LIBS} || exit 1; \
+ rm -f $@-symtbl.c $@-symtbl.@O@; \
+ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \
+ -o $@-symtbl.c $@tmp0 || exit 1; \
+ $(MAKE) $@-symtbl.@O@ || exit 1; \
+ rm -f $@tmp1; \
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} \
+ -o $@tmp1 $${BASEOBJS} $@-symtbl.@O@ $${LIBS0} ${NOSYMLIBS} || exit 1; \
+ rm -f $@-symtbl.c $@-symtbl.@O@; \
+ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \
+ -o $@-symtbl.c $@tmp1 || exit 1; \
+ $(MAKE) $@-symtbl.@O@ || exit 1; \
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} \
+ -o $@tmp2 $${BASEOBJS} $@-symtbl.@O@ $${LIBS0} ${NOSYMLIBS}; \
+ ${MKSYMTBL_PROGRAM} ${top_srcdir}/util/mksymtbl.pl \
+ -o $@-symtbl2.c $@tmp2; \
+ diff $@-symtbl.c $@-symtbl2.c || exit 1;\
+ mv $@tmp2 $@; \
+ rm -f $@tmp0 $@tmp1 $@tmp2 $@-symtbl2.c; \
+ fi
+
cleandir: distclean
superclean: maintainer-clean
clean distclean maintainer-clean::
- rm -f *.@O@ *.o *.lo *.la core *.core .depend
- rm -rf .libs
+ rm -f *.@O@ *.o *.lo *.la core *.core *-symtbl.c *tmp0 *tmp1 *tmp2
+ rm -rf .depend .libs
distclean maintainer-clean::
rm -f Makefile
@@ -217,6 +290,16 @@ PDFLATEX = @PDFLATEX@
W3M = @W3M@
###
+### Script language program used to create internal symbol tables
+###
+MKSYMTBL_PROGRAM = @MKSYMTBL_PROGRAM@
+
+###
+### Switch to create internal symbol table selectively
+###
+ALWAYS_MAKE_SYMTABLE = @ALWAYS_MAKE_SYMTABLE@
+
+###
### DocBook -> HTML
### DocBook -> man page
###
diff --git a/version b/version
index e6bfe44037d0..1d9fbd2b07f1 100644
--- a/version
+++ b/version
@@ -1,10 +1,10 @@
-# $Id: version,v 1.43.12.11.2.2.2.3 2011-06-21 20:35:59 each Exp $
+# $Id: version,v 1.53.8.2.2.4 2011-06-21 20:44:01 each Exp $
#
# This file must follow /bin/sh rules. It is imported directly via
# configure.
#
MAJORVER=9
-MINORVER=6
-PATCHVER=
-RELEASETYPE=-ESV
-RELEASEVER=-R4-P3
+MINORVER=8
+PATCHVER=0
+RELEASETYPE=-P
+RELEASEVER=4